Module: wine Branch: master Commit: 7b42dc4931201a078029fb35d51cb1d0c75e2d1f URL: http://source.winehq.org/git/wine.git/?a=commit;h=7b42dc4931201a078029fb35d5...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Feb 27 15:20:26 2017 +0100
wininet: Improved netconn_drain_content.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wininet/http.c | 15 ++++++++------ dlls/wininet/tests/http.c | 52 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 12 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 635b7d6..21b93dd 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -2682,17 +2682,20 @@ static BOOL netconn_drain_content(data_stream_t *stream, http_request_t *req) { netconn_stream_t *netconn_stream = (netconn_stream_t*)stream; BYTE buf[1024]; - int len; + int len, res; + size_t size;
- if(netconn_end_of_data(stream, req)) - return TRUE; + if(netconn_stream->content_length == ~0u) + return FALSE;
- do { - if(NETCON_recv(req->netconn, buf, sizeof(buf), FALSE, &len) != ERROR_SUCCESS) + while(netconn_stream->content_read < netconn_stream->content_length) { + size = min(sizeof(buf), netconn_stream->content_length-netconn_stream->content_read); + res = NETCON_recv(req->netconn, buf, size, FALSE, &len); + if(res || !len) return FALSE;
netconn_stream->content_read += len; - }while(netconn_stream->content_read < netconn_stream->content_length); + }
return TRUE; } diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index fb64e3c..6df30fa 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -4652,7 +4652,14 @@ static void _readex_expect_sync_data(unsigned line, HINTERNET req, DWORD flags, _readex_expect_sync_data_len(line, req, flags, buf, buf_size, exdata, strlen(exdata)); }
-static void send_response_and_wait(const char *response, BOOL close_connection, INTERNET_BUFFERSW *buf) +static void close_connection(void) +{ + char c; + SetEvent(conn_wait_event); + recv(server_socket, &c, 1, 0); +} + +static void send_response_and_wait(const char *response, BOOL do_close_connection, INTERNET_BUFFERSW *buf) { DWORD orig_size = buf->dwBufferLength;
@@ -4661,11 +4668,8 @@ static void send_response_and_wait(const char *response, BOOL close_connection, if(response) server_send_string(response);
- if(close_connection) { - char c; - SetEvent(conn_wait_event); - recv(server_socket, &c, 1, 0); - } + if(do_close_connection) + close_connection();
WaitForSingleObject(hCompleteEvent, INFINITE);
@@ -4821,6 +4825,41 @@ static void test_http_read(int port) CloseHandle(server_req_rec_event); }
+static void test_connection_break(int port) +{ + INTERNET_BUFFERSW ib; + test_request_t req; + char buf[24000]; + + if(!is_ie7plus) + return; + + hCompleteEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + conn_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL); + server_req_rec_event = CreateEventW(NULL, FALSE, FALSE, NULL); + + memset(&ib, 0, sizeof(ib)); + ib.dwStructSize = sizeof(ib); + ib.lpvBuffer = buf; + + trace("Testing InternetReadFileExW on broken connection...\n"); + + open_read_test_request(port, &req, + "HTTP/1.1 200 OK\r\n" + "Server: winetest\r\n" + "Content-Length: 10000\r\n" + "\r\n" + "xx"); + + /* close connection and make sure that it's closed on handle release. */ + close_connection(); + SET_EXPECT(INTERNET_STATUS_CLOSING_CONNECTION); + SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED); + close_async_handle(req.session, hCompleteEvent, 2); + CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION); + CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED); +} + static void test_long_url(int port) { char long_path[INTERNET_MAX_PATH_LENGTH*2] = "/echo_request?"; @@ -4919,6 +4958,7 @@ static void test_http_connection(void) test_basic_auth_credentials_reuse(si.port); test_async_read(si.port); test_http_read(si.port); + test_connection_break(si.port); test_long_url(si.port); test_remove_dot_segments(si.port);