The mentioned bug randomly occurred after some subsequent patches, so the sleep should happen before GetOverlappedResult is called.
Signed-off-by: Julian Klemann jklemann@codeweavers.com --- dlls/httpapi/tests/httpapi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/httpapi/tests/httpapi.c b/dlls/httpapi/tests/httpapi.c index be1d31c12ad..9d344f26d02 100644 --- a/dlls/httpapi/tests/httpapi.c +++ b/dlls/httpapi/tests/httpapi.c @@ -228,10 +228,6 @@ static void test_v1_server(void) ret = send(s, req_text, strlen(req_text), 0); ok(ret == strlen(req_text), "send() returned %d.\n", ret);
- ret = GetOverlappedResult(queue, &ovl, &ret_size, TRUE); - ok(ret, "Got error %lu.\n", GetLastError()); - ok(ret_size > sizeof(*req), "Got size %lu.\n", ret_size); - /* Various versions of Windows (observed on 64-bit Windows 8 and Windows 10 * version 1507, but probably affecting others) suffer from a bug where the * kernel will report success before completely filling the buffer or @@ -239,6 +235,10 @@ static void test_v1_server(void) * around this. */ Sleep(100);
+ ret = GetOverlappedResult(queue, &ovl, &ret_size, TRUE); + ok(ret, "Got error %lu.\n", GetLastError()); + ok(ret_size > sizeof(*req), "Got size %lu.\n", ret_size); + ok(!req->Flags, "Got flags %#lx.\n", req->Flags); ok(req->ConnectionId, "Expected nonzero connection ID.\n"); ok(req->RequestId, "Expected nonzero connection ID.\n");
If a queue is associated to a URL group and the URL cannot be added to the queue, the URL should not be set in the group. In other cases, it should be.
Signed-off-by: Julian Klemann jklemann@codeweavers.com --- dlls/httpapi/tests/httpapi.c | 118 +++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+)
diff --git a/dlls/httpapi/tests/httpapi.c b/dlls/httpapi/tests/httpapi.c index 9d344f26d02..d231fd1d8ed 100644 --- a/dlls/httpapi/tests/httpapi.c +++ b/dlls/httpapi/tests/httpapi.c @@ -1218,6 +1218,122 @@ static void test_HttpCreateUrlGroup(void) ok(!ret, "Unexpected return value %u.\n", ret); }
+static void test_v2_bound_port(void) +{ + static const HTTPAPI_VERSION version = {2, 0}; + struct sockaddr_in sockaddr; + HTTP_SERVER_SESSION_ID session; + HTTP_BINDING_INFO binding; + HTTP_URL_GROUP_ID group; + unsigned short port; + WCHAR url[50]; + HANDLE queue, dummy_queue; + int ret; + SOCKET s, s2; + + ret = pHttpCreateServerSession(version, &session, 0); + ok(!ret, "Failed to create session, error %u.\n", ret); + ret = pHttpCreateUrlGroup(session, &group, 0); + ok(!ret, "Failed to create URL group, error %u.\n", ret); + + ret = pHttpCreateRequestQueue(version, NULL, NULL, 0, &queue); + ok(!ret, "Failed to create request queue, error %u.\n", ret); + ret = pHttpCreateRequestQueue(version, NULL, NULL, 0, &dummy_queue); + ok(!ret, "Failed to create request queue, error %u.\n", ret); + binding.Flags.Present = 1; + binding.RequestQueueHandle = queue; + ret = pHttpSetUrlGroupProperty(group, HttpServerBindingProperty, &binding, sizeof(binding)); + ok(!ret, "Failed to bind request queue, error %u.\n", ret); + + s2 = socket(AF_INET, SOCK_STREAM, 0); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); + for (port = 50000; port < 51000; ++port) + { + sockaddr.sin_port = htons(port); + ret = bind(s2, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + if (!ret) + break; + } + ok(!ret, "Failed to bind to port\n"); + swprintf(url, ARRAY_SIZE(url), L"http://localhost:%u/", port); + ret = pHttpAddUrlToUrlGroup(group, url, 0xdeadbeef, 0); + ok(ret == ERROR_SHARING_VIOLATION, "Unexpected failure adding %s, error %u.\n", debugstr_w(url), ret); + shutdown(s2, SD_BOTH); + closesocket(s2); + + binding.RequestQueueHandle = dummy_queue; + ret = pHttpSetUrlGroupProperty(group, HttpServerBindingProperty, &binding, sizeof(binding)); + ok(!ret, "Failed to rebind request queue, error %u.\n", ret); + + s = socket(AF_INET, SOCK_STREAM, 0); + ret = connect(s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + todo_wine ok(ret, "Connecting to socket succeeded, %lu.\n", GetLastError()); + todo_wine ok(GetLastError() == WSAECONNREFUSED, "Unexpected error connecting to socket, %lu.\n", GetLastError()); + + closesocket(s); + ret = pHttpCloseRequestQueue(dummy_queue); + ok(!ret, "Failed to close queue handle, error %u.\n", ret); + ret = pHttpCloseRequestQueue(queue); + ok(!ret, "Failed to close queue handle, error %u.\n", ret); + ret = pHttpCloseUrlGroup(group); + ok(!ret, "Failed to close group, error %u.\n", ret); + ret = pHttpCloseServerSession(session); + ok(!ret, "Failed to close group, error %u.\n", ret); +} + +static void test_v2_queue_after_url(void) +{ + char DECLSPEC_ALIGN(8) req_buffer[2048]; + HTTP_REQUEST_V2 *reqv2 = (HTTP_REQUEST_V2 *)req_buffer; + static const HTTPAPI_VERSION version = {2, 0}; + HTTP_REQUEST_V1 *req = &reqv2->s; + HTTP_SERVER_SESSION_ID session; + HTTP_BINDING_INFO binding; + HTTP_URL_GROUP_ID group; + unsigned short port; + char req_text[100]; + HANDLE queue; + int ret; + SOCKET s; + + ret = pHttpCreateServerSession(version, &session, 0); + ok(!ret, "Failed to create session, error %u.\n", ret); + ret = pHttpCreateUrlGroup(session, &group, 0); + ok(!ret, "Failed to create URL group, error %u.\n", ret); + + port = add_url_v2(group); + + ret = pHttpCreateRequestQueue(version, NULL, NULL, 0, &queue); + ok(!ret, "Failed to create request queue, error %u.\n", ret); + binding.Flags.Present = 1; + binding.RequestQueueHandle = queue; + ret = pHttpSetUrlGroupProperty(group, HttpServerBindingProperty, &binding, sizeof(binding)); + ok(!ret, "Failed to bind request queue, error %u.\n", ret); + + s = create_client_socket(port); + + sprintf(req_text, simple_req, port); + ret = send(s, req_text, strlen(req_text), 0); + ok(ret == strlen(req_text), "send() returned %d.\n", ret); + + ret = HttpReceiveHttpRequest(queue, HTTP_NULL_ID, 0, (HTTP_REQUEST *)req, sizeof(req_buffer), NULL, NULL); + ok(!ret, "Got error %u.\n", ret); + + ok(req->BytesReceived == strlen(req_text), "Got %s bytes.\n", wine_dbgstr_longlong(req->BytesReceived)); + + ret = remove_url_v2(group, port); + ok(!ret, "Got error %u.\n", ret); + + closesocket(s); + ret = pHttpCloseRequestQueue(queue); + ok(!ret, "Failed to close queue handle, error %u.\n", ret); + ret = pHttpCloseUrlGroup(group); + ok(!ret, "Failed to close group, error %u.\n", ret); + ret = pHttpCloseServerSession(session); + ok(!ret, "Failed to close group, error %u.\n", ret); +} + static void test_v2_server(void) { char DECLSPEC_ALIGN(8) req_buffer[2048], response_buffer[2048]; @@ -1538,6 +1654,8 @@ START_TEST(httpapi) test_HttpCreateServerSession(); test_HttpCreateUrlGroup(); test_v2_server(); + test_v2_queue_after_url(); + test_v2_bound_port(); test_v2_completion_port();
ret = HttpTerminate(HTTP_INITIALIZE_SERVER, NULL);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
The URL should not be set if the URL cannot be added to a request queue.
Signed-off-by: Julian Klemann jklemann@codeweavers.com --- dlls/httpapi/httpapi_main.c | 11 ++++++++--- dlls/httpapi/tests/httpapi.c | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/dlls/httpapi/httpapi_main.c b/dlls/httpapi/httpapi_main.c index 4d2d307ffcb..a5f8007b0a9 100644 --- a/dlls/httpapi/httpapi_main.c +++ b/dlls/httpapi/httpapi_main.c @@ -686,6 +686,7 @@ ULONG WINAPI HttpAddUrlToUrlGroup(HTTP_URL_GROUP_ID id, const WCHAR *url, HTTP_URL_CONTEXT context, ULONG reserved) { struct url_group *group = get_url_group(id); + ULONG ret;
TRACE("id %s, url %s, context %s, reserved %#lx.\n", wine_dbgstr_longlong(id), debugstr_w(url), wine_dbgstr_longlong(context), reserved); @@ -696,13 +697,17 @@ ULONG WINAPI HttpAddUrlToUrlGroup(HTTP_URL_GROUP_ID id, const WCHAR *url, return ERROR_CALL_NOT_IMPLEMENTED; }
+ if (group->queue) + { + ret = add_url(group->queue, url, context); + if (ret) + return ret; + } + if (!(group->url = heap_strdupW(url))) return ERROR_OUTOFMEMORY; group->context = context;
- if (group->queue) - return add_url(group->queue, url, context); - return ERROR_SUCCESS; }
diff --git a/dlls/httpapi/tests/httpapi.c b/dlls/httpapi/tests/httpapi.c index d231fd1d8ed..3c3f7abcd90 100644 --- a/dlls/httpapi/tests/httpapi.c +++ b/dlls/httpapi/tests/httpapi.c @@ -1268,8 +1268,8 @@ static void test_v2_bound_port(void)
s = socket(AF_INET, SOCK_STREAM, 0); ret = connect(s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); - todo_wine ok(ret, "Connecting to socket succeeded, %lu.\n", GetLastError()); - todo_wine ok(GetLastError() == WSAECONNREFUSED, "Unexpected error connecting to socket, %lu.\n", GetLastError()); + ok(ret, "Connecting to socket succeeded, %lu.\n", GetLastError()); + ok(GetLastError() == WSAECONNREFUSED, "Unexpected error connecting to socket, %lu.\n", GetLastError());
closesocket(s); ret = pHttpCloseRequestQueue(dummy_queue);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
The request queue has a growable array rather than single URL and socket properties.
Signed-off-by: Julian Klemann jklemann@codeweavers.com --- dlls/http.sys/http.c | 134 ++++++++++++++++++++++++----------- dlls/http.sys/request.h | 2 +- dlls/httpapi/tests/httpapi.c | 40 ++++++++++- 3 files changed, 132 insertions(+), 44 deletions(-)
diff --git a/dlls/http.sys/http.c b/dlls/http.sys/http.c index 523c70ee12c..31687485179 100644 --- a/dlls/http.sys/http.c +++ b/dlls/http.sys/http.c @@ -70,6 +70,7 @@ struct connection BOOL available; struct request_queue *queue; HTTP_REQUEST_ID req_id; + HTTP_URL_CONTEXT context;
/* Things we already parsed out of the request header in parse_request(). * These are valid only if "available" is TRUE. */ @@ -82,15 +83,21 @@ struct connection
static struct list connections = LIST_INIT(connections);
-struct request_queue +struct url { struct list entry; - LIST_ENTRY irp_queue; - HTTP_URL_CONTEXT context; char *url; + HTTP_URL_CONTEXT context; SOCKET socket; };
+struct request_queue +{ + struct list entry; + LIST_ENTRY irp_queue; + struct list urls; +}; + static struct list request_queues = LIST_INIT(request_queues);
static void accept_connection(SOCKET socket) @@ -319,17 +326,30 @@ static int parse_number(const char *str, const char **endptr, const char *end) return n; }
-static BOOL host_matches(const struct connection *conn, const struct request_queue *queue) +static struct url *host_matches(const struct connection *conn, const struct request_queue *queue) { const char *conn_host = (conn->url[0] == '/') ? conn->host : conn->url + 7; + struct url *url;
- if (queue->url[7] == '+') + LIST_FOR_EACH_ENTRY(url, &queue->urls, struct url, entry) { - const char *queue_port = strchr(queue->url + 7, ':'); - return !strncmp(queue_port, strchr(conn_host, ':'), strlen(queue_port) - 1 /* strip final slash */); + if (url->url) + { + if (url->url && url->url[7] == '+') + { + /* strip final slash */ + const char *queue_port = strchr(url->url + 7, ':'); + if (!strncmp(queue_port, strchr(conn_host, ':'), strlen(queue_port) - 1)) + return url; + } + + /* strip final slash */ + if (!memicmp(url->url + 7, conn_host, strlen(url->url) - 8)) + return url; + } }
- return !memicmp(queue->url + 7, conn_host, strlen(queue->url) - 8 /* strip final slash */); + return NULL; }
/* Upon receiving a request, parse it to ensure that it is a valid HTTP request, @@ -339,6 +359,7 @@ static int parse_request(struct connection *conn) { const char *const req = conn->buffer, *const end = conn->buffer + conn->len; struct request_queue *queue; + struct url *conn_url; const char *p = req, *q; int len, ret;
@@ -432,10 +453,11 @@ static int parse_request(struct connection *conn) /* Find a queue which can receive this request. */ LIST_FOR_EACH_ENTRY(queue, &request_queues, struct request_queue, entry) { - if (host_matches(conn, queue)) + if ((conn_url = host_matches(conn, queue))) { TRACE("Assigning request to queue %p.\n", queue); conn->queue = queue; + conn->context = conn_url->context; break; } } @@ -544,6 +566,7 @@ static DWORD WINAPI request_thread_proc(void *arg) { struct connection *conn, *cursor; struct request_queue *queue; + struct url *url;
TRACE("Starting request thread.\n");
@@ -553,8 +576,11 @@ static DWORD WINAPI request_thread_proc(void *arg)
LIST_FOR_EACH_ENTRY(queue, &request_queues, struct request_queue, entry) { - if (queue->socket != -1) - accept_connection(queue->socket); + LIST_FOR_EACH_ENTRY(url, &queue->urls, struct url, entry) + { + if (url->socket != -1) + accept_connection(url->socket); + } }
LIST_FOR_EACH_ENTRY_SAFE(conn, cursor, &connections, struct connection, entry) @@ -575,6 +601,7 @@ static NTSTATUS http_add_url(struct request_queue *queue, IRP *irp) const struct http_add_url_params *params = irp->AssociatedIrp.SystemBuffer; struct sockaddr_in addr; struct connection *conn; + struct url *url_entry, *new_entry; unsigned int count = 0; char *url, *endptr; ULONG true = 1; @@ -594,7 +621,7 @@ static NTSTATUS http_add_url(struct request_queue *queue, IRP *irp) if (!(addr.sin_port = htons(strtol(strchr(params->url + 7, ':') + 1, &endptr, 10))) || *endptr != '/') return STATUS_INVALID_PARAMETER;
- if (!(url = heap_alloc(strlen(params->url)+1))) + if (!(url = malloc(strlen(params->url)+1))) return STATUS_NO_MEMORY; strcpy(url, params->url);
@@ -603,27 +630,28 @@ static NTSTATUS http_add_url(struct request_queue *queue, IRP *irp) if (count > 3) FIXME("Binding to relative URIs is not implemented; binding to all URIs instead.\n");
+ if (!(new_entry = malloc(sizeof(struct url)))) + return STATUS_NO_MEMORY; + EnterCriticalSection(&http_cs);
- if (queue->url && !strcmp(queue->url, url)) - { - LeaveCriticalSection(&http_cs); - heap_free(url); - return STATUS_OBJECT_NAME_COLLISION; - } - else if (queue->url) + LIST_FOR_EACH_ENTRY(url_entry, &queue->urls, struct url, entry) { - FIXME("Binding to multiple URLs is not implemented.\n"); - LeaveCriticalSection(&http_cs); - heap_free(url); - return STATUS_NOT_IMPLEMENTED; + if (url_entry->url && !strcmp(url_entry->url, url)) + { + LeaveCriticalSection(&http_cs); + free(url); + free(new_entry); + return STATUS_OBJECT_NAME_COLLISION; + } }
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { ERR("Failed to create socket, error %u.\n", WSAGetLastError()); LeaveCriticalSection(&http_cs); - heap_free(url); + free(url); + free(new_entry); return STATUS_UNSUCCESSFUL; }
@@ -633,7 +661,8 @@ static NTSTATUS http_add_url(struct request_queue *queue, IRP *irp) { LeaveCriticalSection(&http_cs); closesocket(s); - heap_free(url); + free(url); + free(new_entry); if (WSAGetLastError() == WSAEADDRINUSE) { WARN("Address %s is already in use.\n", debugstr_a(params->url)); @@ -653,15 +682,17 @@ static NTSTATUS http_add_url(struct request_queue *queue, IRP *irp) ERR("Failed to listen to port %u, error %u.\n", addr.sin_port, WSAGetLastError()); LeaveCriticalSection(&http_cs); closesocket(s); - heap_free(url); + free(url); + free(new_entry); return STATUS_OBJECT_NAME_COLLISION; }
ioctlsocket(s, FIONBIO, &true); WSAEventSelect(s, request_event, FD_ACCEPT); - queue->socket = s; - queue->url = url; - queue->context = params->context; + new_entry->url = url; + new_entry->context = params->context; + new_entry->socket = s; + list_add_head(&queue->urls, &new_entry->entry);
/* See if any pending requests now match this queue. */ LIST_FOR_EACH_ENTRY(conn, &connections, struct connection, entry) @@ -669,6 +700,7 @@ static NTSTATUS http_add_url(struct request_queue *queue, IRP *irp) if (conn->available && !conn->queue && host_matches(conn, queue)) { conn->queue = queue; + conn->context = params->context; try_complete_irp(conn); } } @@ -681,21 +713,33 @@ static NTSTATUS http_add_url(struct request_queue *queue, IRP *irp) static NTSTATUS http_remove_url(struct request_queue *queue, IRP *irp) { const char *url = irp->AssociatedIrp.SystemBuffer; + struct url *url_entry;
TRACE("host %s.\n", debugstr_a(url));
EnterCriticalSection(&http_cs);
- if (!queue->url || strcmp(url, queue->url)) + LIST_FOR_EACH_ENTRY(url_entry, &queue->urls, struct url, entry) { - LeaveCriticalSection(&http_cs); - return STATUS_OBJECT_NAME_NOT_FOUND; + if (url_entry->url && !strcmp(url, url_entry->url)) + { + free(url_entry->url); + url_entry->url = NULL; + + shutdown(url_entry->socket, SD_BOTH); + closesocket(url_entry->socket); + url_entry->socket = -1; + + list_remove(&url_entry->entry); + free(url_entry); + + LeaveCriticalSection(&http_cs); + return STATUS_SUCCESS; + } } - heap_free(queue->url); - queue->url = NULL;
LeaveCriticalSection(&http_cs); - return STATUS_SUCCESS; + return STATUS_OBJECT_NAME_NOT_FOUND; }
static struct connection *get_connection(HTTP_REQUEST_ID req_id) @@ -892,8 +936,9 @@ static NTSTATUS WINAPI dispatch_create(DEVICE_OBJECT *device, IRP *irp) IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); struct request_queue *queue;
- if (!(queue = heap_alloc_zero(sizeof(*queue)))) + if (!(queue = calloc(1, sizeof(*queue)))) return STATUS_NO_MEMORY; + list_init(&queue->urls); stack->FileObject->FsContext = queue; InitializeListHead(&queue->irp_queue);
@@ -910,17 +955,22 @@ static NTSTATUS WINAPI dispatch_create(DEVICE_OBJECT *device, IRP *irp)
static void close_queue(struct request_queue *queue) { + struct url *url, *url_next; + EnterCriticalSection(&http_cs); list_remove(&queue->entry); - if (queue->socket != -1) + + LIST_FOR_EACH_ENTRY_SAFE(url, url_next, &queue->urls, struct url, entry) { - shutdown(queue->socket, SD_BOTH); - closesocket(queue->socket); + free(url->url); + shutdown(url->socket, SD_BOTH); + closesocket(url->socket); + list_remove(&url->entry); + free(url); } - LeaveCriticalSection(&http_cs); + free(queue);
- heap_free(queue->url); - heap_free(queue); + LeaveCriticalSection(&http_cs); }
static NTSTATUS WINAPI dispatch_close(DEVICE_OBJECT *device, IRP *irp) diff --git a/dlls/http.sys/request.h b/dlls/http.sys/request.h index f044db3bb2c..f307ca3dead 100644 --- a/dlls/http.sys/request.h +++ b/dlls/http.sys/request.h @@ -181,9 +181,9 @@ static NTSTATUS complete_irp(struct connection *conn, IRP *irp)
offset = sizeof(*req);
+ req->UrlContext = conn->context; req->ConnectionId = (ULONG_PTR)conn; req->RequestId = conn->req_id; - req->UrlContext = conn->queue->context; req->Version = conn->version; req->Verb = conn->verb; req->UnknownVerbLength = conn->unk_verb_len; diff --git a/dlls/httpapi/tests/httpapi.c b/dlls/httpapi/tests/httpapi.c index 3c3f7abcd90..bbed4580b92 100644 --- a/dlls/httpapi/tests/httpapi.c +++ b/dlls/httpapi/tests/httpapi.c @@ -108,7 +108,7 @@ static unsigned short add_url_v1(HANDLE queue) swprintf(url, ARRAY_SIZE(url), L"http://localhost:%u/", port); if (!(ret = HttpAddUrl(queue, url, NULL))) return port; - ok(ret == ERROR_SHARING_VIOLATION, "Failed to add %s, error %u.\n", debugstr_w(url), ret); + ok(ret == ERROR_SHARING_VIOLATION || ret == ERROR_ALREADY_EXISTS, "Failed to add %s, error %u.\n", debugstr_w(url), ret); } ok(0, "Failed to add url %s, error %u.\n", debugstr_w(url), ret); return 0; @@ -1083,6 +1083,43 @@ static void test_v1_unknown_tokens(void) ok(ret, "Failed to close queue handle, error %lu.\n", GetLastError()); }
+static void test_v1_multiple_urls(void) +{ + char DECLSPEC_ALIGN(8) req_buffer[2048]; + HTTP_REQUEST_V1 *req = (HTTP_REQUEST_V1 *)req_buffer; + unsigned short ports[4]; + char req_text[200]; + DWORD ret_size; + HANDLE queue; + SOCKET s; + int ret; + + ret = HttpCreateHttpHandle(&queue, 0); + ok(!ret, "Got error %u.\n", ret); + + for (int i = 0; i < 4; ++i) + ports[i] = add_url_v1(queue); + + for (int i = 0; i < 4; ++i) + { + s = create_client_socket(ports[i]); + sprintf(req_text, simple_req, ports[i]); + ret = send(s, req_text, strlen(req_text), 0); + ok(ret == strlen(req_text), "send() returned %d.\n", ret); + + memset(req_buffer, 0xcc, sizeof(req_buffer)); + ret = HttpReceiveHttpRequest(queue, HTTP_NULL_ID, 0, (HTTP_REQUEST *)req, sizeof(req_buffer), &ret_size, NULL); + ok(!ret, "Got error %u.\n", ret); + ok(ret_size > sizeof(*req), "Got size %lu.\n", ret_size); + + send_response_v1(queue, req->RequestId, s); + closesocket(s); + } + + ret = CloseHandle(queue); + ok(ret, "Failed to close queue handle, error %lu.\n", GetLastError()); +} + static void test_v1_urls(void) { char DECLSPEC_ALIGN(8) req_buffer[2048]; @@ -1643,6 +1680,7 @@ START_TEST(httpapi) test_v1_bad_request(); test_v1_cooked_url(); test_v1_unknown_tokens(); + test_v1_multiple_urls(); test_v1_urls();
ret = HttpTerminate(HTTP_INITIALIZE_SERVER, NULL);
Mostly looks good, just a couple of errors...
On 6/14/22 16:38, Julian Klemann wrote:
- if (!(new_entry = malloc(sizeof(struct url))))
return STATUS_NO_MEMORY;
This leaks "url".
- for (int i = 0; i < 4; ++i)
ports[i] = add_url_v1(queue);
- for (int i = 0; i < 4; ++i)
- {
s = create_client_socket(ports[i]);
sprintf(req_text, simple_req, ports[i]);
ret = send(s, req_text, strlen(req_text), 0);
ok(ret == strlen(req_text), "send() returned %d.\n", ret);
memset(req_buffer, 0xcc, sizeof(req_buffer));
ret = HttpReceiveHttpRequest(queue, HTTP_NULL_ID, 0, (HTTP_REQUEST *)req, sizeof(req_buffer), &ret_size, NULL);
ok(!ret, "Got error %u.\n", ret);
ok(ret_size > sizeof(*req), "Got size %lu.\n", ret_size);
send_response_v1(queue, req->RequestId, s);
closesocket(s);
- }
I believe some compilers still don't like declarations in for-loop initializers. Also, something of a nitpick, but those should probably be unsigned.