Zebediah Figura : http.sys: Receive data from connected sockets.

Alexandre Julliard julliard at winehq.org
Fri Aug 23 15:14:54 CDT 2019


Module: wine
Branch: master
Commit: fb6956c7d147e18e2e106f3ffd6727d9cb65d306
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=fb6956c7d147e18e2e106f3ffd6727d9cb65d306

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Thu Aug 22 22:35:28 2019 -0500

http.sys: Receive data from connected sockets.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/http.sys/http.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c
index bfec4cf..5e29db0 100644
--- a/dlls/http.sys/http.c
+++ b/dlls/http.sys/http.c
@@ -49,6 +49,9 @@ struct connection
     struct list entry; /* in "connections" below */
 
     int socket;
+
+    char *buffer;
+    unsigned int len, size;
 };
 
 static struct list connections = LIST_INIT(connections);
@@ -79,6 +82,15 @@ static void accept_connection(int socket)
         closesocket(peer);
         return;
     }
+    if (!(conn->buffer = heap_alloc(8192)))
+    {
+        ERR("Failed to allocate buffer memory.\n");
+        heap_free(conn);
+        shutdown(peer, SD_BOTH);
+        closesocket(peer);
+        return;
+    }
+    conn->size = 8192;
     WSAEventSelect(peer, request_event, FD_READ | FD_CLOSE);
     ioctlsocket(peer, FIONBIO, &true);
     conn->socket = peer;
@@ -93,8 +105,74 @@ static void close_connection(struct connection *conn)
     heap_free(conn);
 }
 
+/* Upon receiving a request, parse it to ensure that it is a valid HTTP request,
+ * and mark down some information that we will use later. Returns 1 if we parsed
+ * a complete request, 0 if incomplete, -1 if invalid. */
+static int parse_request(struct connection *conn)
+{
+    FIXME("Not implemented.\n");
+    return -1;
+}
+
+static void receive_data(struct connection *conn)
+{
+    int len, ret;
+
+    /* We might be waiting for an IRP, but always call recv() anyway, since we
+     * might have been woken up by the socket closing. */
+    if ((len = recv(conn->socket, conn->buffer + conn->len, conn->size - conn->len, 0)) <= 0)
+    {
+        if (WSAGetLastError() == WSAEWOULDBLOCK)
+            return; /* nothing to receive */
+        else if (!len)
+            TRACE("Connection was shut down by peer.\n");
+        else
+            ERR("Got error %u; shutting down connection.\n", WSAGetLastError());
+        close_connection(conn);
+        return;
+    }
+    conn->len += len;
+
+    TRACE("Received %u bytes of data.\n", len);
+
+    if (!(ret = parse_request(conn)))
+    {
+        ULONG available;
+        ioctlsocket(conn->socket, FIONREAD, &available);
+        if (available)
+        {
+            TRACE("%u more bytes of data available, trying with larger buffer.\n", available);
+            if (!(conn->buffer = heap_realloc(conn->buffer, conn->len + available)))
+            {
+                ERR("Failed to allocate %u bytes of memory.\n", conn->len + available);
+                close_connection(conn);
+                return;
+            }
+            conn->size = conn->len + available;
+
+            if ((len = recv(conn->socket, conn->buffer + conn->len, conn->size - conn->len, 0)) < 0)
+            {
+                ERR("Got error %u; shutting down connection.\n", WSAGetLastError());
+                close_connection(conn);
+                return;
+            }
+            TRACE("Received %u bytes of data.\n", len);
+            conn->len += len;
+            ret = parse_request(conn);
+        }
+    }
+    if (!ret)
+        TRACE("Request is incomplete, waiting for more data.\n");
+    else if (ret < 0)
+    {
+        WARN("Failed to parse request; shutting down connection.\n");
+        close_connection(conn);
+    }
+}
+
 static DWORD WINAPI request_thread_proc(void *arg)
 {
+    struct connection *conn, *cursor;
     struct request_queue *queue;
 
     TRACE("Starting request thread.\n");
@@ -109,6 +187,11 @@ static DWORD WINAPI request_thread_proc(void *arg)
                 accept_connection(queue->socket);
         }
 
+        LIST_FOR_EACH_ENTRY_SAFE(conn, cursor, &connections, struct connection, entry)
+        {
+            receive_data(conn);
+        }
+
         LeaveCriticalSection(&http_cs);
     }
 




More information about the wine-cvs mailing list