From: Hans Leidekker Subject: [3/3] wininet: Also report data available in the chunk buffer. Message-Id: <1468920457-17688-3-git-send-email-hans@codeweavers.com> Date: Tue, 19 Jul 2016 11:27:37 +0200 Signed-off-by: Hans Leidekker --- dlls/wininet/http.c | 4 +-- dlls/wininet/tests/http.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index c4cf66b..9a388ab 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -2802,8 +2802,8 @@ static DWORD start_next_chunk(chunked_stream_t *stream, http_request_t *req) static DWORD chunked_get_avail_data(data_stream_t *stream, http_request_t *req) { - /* Allow reading only from read buffer */ - return 0; + chunked_stream_t *chunked_stream = (chunked_stream_t*)stream; + return min(chunked_stream->buf_size, chunked_stream->chunk_size); } static BOOL chunked_end_of_data(data_stream_t *stream, http_request_t *req) diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 3b06fb9..f7d701f 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -2268,7 +2268,6 @@ static DWORD CALLBACK server_thread(LPVOID param) { send(c, page1, sizeof page1-1, 0); } - if (strstr(buffer, "GET /testJ")) { if (count == 0) @@ -2408,6 +2407,14 @@ static DWORD CALLBACK server_thread(LPVOID param) send(c, okmsg, sizeof(okmsg)-1, 0); send(c, buffer, strlen(buffer), 0); } + if (strstr(buffer, "/chunked")) + { + static const char header[] = + "HTTP/1.1 200 Success\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nxxxx\r\n"; + send(c, header, sizeof(header)-1, 0); + send(c, "8\r\nxxxxxxxx\r\n", sizeof("8\r\nxxxxxxxx\r\n")-1, 0); + WaitForSingleObject(conn_wait_event, INFINITE); + } shutdown(c, 2); closesocket(c); c = -1; @@ -4763,6 +4770,60 @@ static void test_long_url(int port) close_request(&req); } +static void WINAPI complete_cb(HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID info, DWORD size) +{ + if (status == INTERNET_STATUS_REQUEST_COMPLETE) SetEvent((HANDLE)context); +} + +static void test_async_chunked_read(int port) +{ + HINTERNET ses, con, req; + INTERNET_BUFFERSA buffers; + HANDLE wait = CreateEventW(NULL, 0, 0, NULL); + DWORD res, bytes_left = 12, total = 0; + char buf[4]; + BOOL ret; + + ses = InternetOpenA("winetest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC); + ok(ses != NULL, "got %u\n", GetLastError()); + + con = InternetConnectA(ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(con != NULL, "got %u\n", GetLastError()); + + req = HttpOpenRequestA(con, NULL, "/chunked", NULL, NULL, NULL, 0, (DWORD_PTR)wait); + ok(req != NULL, "got %u\n", GetLastError()); + InternetSetStatusCallbackA(req, complete_cb); + + conn_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL); + HttpSendRequestA(req, NULL, 0, NULL, 0); + res = WaitForSingleObject(wait, 3000); + ok(res == WAIT_OBJECT_0, "wait failed %u\n", GetLastError()); + + memset(&buffers, 0, sizeof(buffers)); + buffers.dwStructSize = sizeof(buffers); + buffers.lpvBuffer = buf; + while (bytes_left) + { + buffers.dwBufferLength = min(bytes_left, sizeof(buf)); + if (!InternetReadFileExA(req, &buffers, IRF_ASYNC, 0)) + { + res = WaitForSingleObject(wait, 3000); + ok(res == WAIT_OBJECT_0, "wait failed %u\n", GetLastError()); + } + if (!buffers.dwBufferLength) break; + bytes_left -= buffers.dwBufferLength; + total += buffers.dwBufferLength; + } + ok(total == 12, "got %u\n", total); + + SetEvent(conn_wait_event); + InternetCloseHandle(req); + InternetCloseHandle(con); + InternetCloseHandle(ses); + CloseHandle(conn_wait_event); + CloseHandle(wait); +} + static void test_http_connection(void) { struct server_info si; @@ -4814,6 +4875,7 @@ static void test_http_connection(void) test_async_read(si.port); test_http_read(si.port); test_long_url(si.port); + test_async_chunked_read(si.port); /* send the basic request again to shutdown the server thread */ test_basic_request(si.port, "GET", "/quit"); -- 2.8.1