Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/winhttp/request.c | 6 +- dlls/winhttp/session.c | 138 ++++++++++++++++++++++++++++------------- dlls/winhttp/tests/winhttp.c | 68 +++++++++++++++++++- dlls/winhttp/winhttp_private.h | 6 +- 4 files changed, 169 insertions(+), 49 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 3e6d2af396..80694da02e 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -1741,7 +1741,7 @@ static BOOL open_connection( request_t *request ) return FALSE; } netconn_set_timeout( netconn, TRUE, request->send_timeout ); - netconn_set_timeout( netconn, FALSE, request->recv_timeout ); + netconn_set_timeout( netconn, FALSE, request->receive_response_timeout ); if (is_secure) { if (connect->session->proxy_server && @@ -1776,7 +1776,7 @@ static BOOL open_connection( request_t *request ) TRACE("using connection %p\n", netconn);
netconn_set_timeout( netconn, TRUE, request->send_timeout ); - netconn_set_timeout( netconn, FALSE, request->recv_timeout ); + netconn_set_timeout( netconn, FALSE, request->receive_response_timeout ); request->netconn = netconn; }
@@ -2628,6 +2628,7 @@ static BOOL receive_response( request_t *request, BOOL async ) BOOL ret; DWORD size, query, status;
+ netconn_set_timeout( request->netconn, FALSE, request->receive_response_timeout ); for (;;) { if (!(ret = read_reply( request ))) @@ -2665,6 +2666,7 @@ static BOOL receive_response( request_t *request, BOOL async ) break; }
+ netconn_set_timeout( request->netconn, FALSE, request->receive_timeout ); if (request->content_length) refill_buffer( request, FALSE );
if (async) diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index b697d4febf..959cafa209 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -46,10 +46,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
-#define DEFAULT_RESOLVE_TIMEOUT 0 -#define DEFAULT_CONNECT_TIMEOUT 20000 -#define DEFAULT_SEND_TIMEOUT 30000 -#define DEFAULT_RECEIVE_TIMEOUT 30000 +#define DEFAULT_RESOLVE_TIMEOUT 0 +#define DEFAULT_CONNECT_TIMEOUT 20000 +#define DEFAULT_SEND_TIMEOUT 30000 +#define DEFAULT_RECEIVE_TIMEOUT 30000 +#define DEFAULT_RECEIVE_RESPONSE_TIMEOUT ~0u
void set_last_error( DWORD error ) { @@ -132,18 +133,27 @@ static BOOL session_query_option( object_header_t *hdr, DWORD option, LPVOID buf *(DWORD *)buffer = session->resolve_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_CONNECT_TIMEOUT: *(DWORD *)buffer = session->connect_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_SEND_TIMEOUT: *(DWORD *)buffer = session->send_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_RECEIVE_TIMEOUT: - *(DWORD *)buffer = session->recv_timeout; + *(DWORD *)buffer = session->receive_timeout; + *buflen = sizeof(DWORD); + return TRUE; + + case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT: + *(DWORD *)buffer = session->receive_response_timeout; *buflen = sizeof(DWORD); return TRUE; + default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_INVALID_PARAMETER ); @@ -193,31 +203,44 @@ static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffe case WINHTTP_OPTION_DISABLE_FEATURE: set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); return FALSE; + case WINHTTP_OPTION_RESOLVE_TIMEOUT: session->resolve_timeout = *(DWORD *)buffer; return TRUE; + case WINHTTP_OPTION_CONNECT_TIMEOUT: session->connect_timeout = *(DWORD *)buffer; return TRUE; + case WINHTTP_OPTION_SEND_TIMEOUT: session->send_timeout = *(DWORD *)buffer; return TRUE; + case WINHTTP_OPTION_RECEIVE_TIMEOUT: - session->recv_timeout = *(DWORD *)buffer; + session->receive_timeout = *(DWORD *)buffer; return TRUE; + + case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT: + session->receive_response_timeout = *(DWORD *)buffer; + return TRUE; + case WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH: FIXME("WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH: 0x%x\n", *(DWORD *)buffer); return TRUE; + case WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT: TRACE("WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT: %p\n", *(HANDLE *)buffer); session->unload_event = *(HANDLE *)buffer; return TRUE; + case WINHTTP_OPTION_MAX_CONNS_PER_SERVER: FIXME("WINHTTP_OPTION_MAX_CONNS_PER_SERVER: %d\n", *(DWORD *)buffer); return TRUE; + case WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER: FIXME("WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER: %d\n", *(DWORD *)buffer); return TRUE; + default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_WINHTTP_INVALID_OPTION ); @@ -253,7 +276,8 @@ HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWST session->resolve_timeout = DEFAULT_RESOLVE_TIMEOUT; session->connect_timeout = DEFAULT_CONNECT_TIMEOUT; session->send_timeout = DEFAULT_SEND_TIMEOUT; - session->recv_timeout = DEFAULT_RECEIVE_TIMEOUT; + session->receive_timeout = DEFAULT_RECEIVE_TIMEOUT; + session->receive_response_timeout = DEFAULT_RECEIVE_RESPONSE_TIMEOUT; list_init( &session->cookie_cache );
if (agent && !(session->agent = strdupW( agent ))) goto end; @@ -334,18 +358,27 @@ static BOOL connect_query_option( object_header_t *hdr, DWORD option, LPVOID buf *(DWORD *)buffer = connect->session->resolve_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_CONNECT_TIMEOUT: *(DWORD *)buffer = connect->session->connect_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_SEND_TIMEOUT: *(DWORD *)buffer = connect->session->send_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_RECEIVE_TIMEOUT: - *(DWORD *)buffer = connect->session->recv_timeout; + *(DWORD *)buffer = connect->session->receive_timeout; *buflen = sizeof(DWORD); return TRUE; + + case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT: + *(DWORD *)buffer = connect->session->receive_response_timeout; + *buflen = sizeof(DWORD); + return TRUE; + default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_INVALID_PARAMETER ); @@ -795,16 +828,24 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf *(DWORD *)buffer = request->resolve_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_CONNECT_TIMEOUT: *(DWORD *)buffer = request->connect_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_SEND_TIMEOUT: *(DWORD *)buffer = request->send_timeout; *buflen = sizeof(DWORD); return TRUE; + case WINHTTP_OPTION_RECEIVE_TIMEOUT: - *(DWORD *)buffer = request->recv_timeout; + *(DWORD *)buffer = request->receive_timeout; + *buflen = sizeof(DWORD); + return TRUE; + + case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT: + *(DWORD *)buffer = request->receive_response_timeout; *buflen = sizeof(DWORD); return TRUE;
@@ -927,14 +968,21 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe case WINHTTP_OPTION_RESOLVE_TIMEOUT: request->resolve_timeout = *(DWORD *)buffer; return TRUE; + case WINHTTP_OPTION_CONNECT_TIMEOUT: request->connect_timeout = *(DWORD *)buffer; return TRUE; + case WINHTTP_OPTION_SEND_TIMEOUT: request->send_timeout = *(DWORD *)buffer; return TRUE; + case WINHTTP_OPTION_RECEIVE_TIMEOUT: - request->recv_timeout = *(DWORD *)buffer; + request->receive_timeout = *(DWORD *)buffer; + return TRUE; + + case WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT: + request->receive_response_timeout = *(DWORD *)buffer; return TRUE;
case WINHTTP_OPTION_USERNAME: @@ -977,6 +1025,7 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe } FIXME("WINHTTP_OPTION_CLIENT_CERT_CONTEXT\n"); return TRUE; + case WINHTTP_OPTION_ENABLE_FEATURE: if(buflen == sizeof( DWORD ) && *(DWORD *)buffer == WINHTTP_ENABLE_SSL_REVOCATION) { @@ -989,9 +1038,11 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } + case WINHTTP_OPTION_CONNECT_RETRIES: FIXME("WINHTTP_OPTION_CONNECT_RETRIES\n"); return TRUE; + default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_WINHTTP_INVALID_OPTION ); @@ -1094,7 +1145,8 @@ HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, LPCWSTR verb, LPCWSTR o request->resolve_timeout = connect->session->resolve_timeout; request->connect_timeout = connect->session->connect_timeout; request->send_timeout = connect->session->send_timeout; - request->recv_timeout = connect->session->recv_timeout; + request->receive_timeout = connect->session->receive_timeout; + request->receive_response_timeout = connect->session->receive_response_timeout;
if (!verb || !verb[0]) verb = getW; if (!(request->verb = strdupW( verb ))) goto end; @@ -2024,8 +2076,6 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int { BOOL ret = TRUE; object_header_t *hdr; - request_t *request; - session_t *session;
TRACE("%p, %d, %d, %d, %d\n", handle, resolve, connect, send, receive);
@@ -2043,43 +2093,45 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
switch(hdr->type) { - case WINHTTP_HANDLE_TYPE_REQUEST: - request = (request_t *)hdr; - request->connect_timeout = connect; - - if (resolve < 0) resolve = 0; - request->resolve_timeout = resolve; - - if (send < 0) send = 0; - request->send_timeout = send; + case WINHTTP_HANDLE_TYPE_REQUEST: + { + request_t *request = (request_t *)hdr; + request->connect_timeout = connect;
- if (receive < 0) receive = 0; - request->recv_timeout = receive; + if (resolve < 0) resolve = 0; + request->resolve_timeout = resolve;
- if (request->netconn) - { - if (netconn_set_timeout( request->netconn, TRUE, send )) ret = FALSE; - if (netconn_set_timeout( request->netconn, FALSE, receive )) ret = FALSE; - } - break; + if (send < 0) send = 0; + request->send_timeout = send;
- case WINHTTP_HANDLE_TYPE_SESSION: - session = (session_t *)hdr; - session->connect_timeout = connect; + if (receive < 0) receive = 0; + request->receive_timeout = receive;
- if (resolve < 0) resolve = 0; - session->resolve_timeout = resolve; + if (request->netconn) + { + if (netconn_set_timeout( request->netconn, TRUE, send )) ret = FALSE; + if (netconn_set_timeout( request->netconn, FALSE, receive )) ret = FALSE; + } + break; + } + case WINHTTP_HANDLE_TYPE_SESSION: + { + session_t *session = (session_t *)hdr; + session->connect_timeout = connect;
- if (send < 0) send = 0; - session->send_timeout = send; + if (resolve < 0) resolve = 0; + session->resolve_timeout = resolve;
- if (receive < 0) receive = 0; - session->recv_timeout = receive; - break; + if (send < 0) send = 0; + session->send_timeout = send;
- default: - set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); - ret = FALSE; + if (receive < 0) receive = 0; + session->receive_timeout = receive; + break; + } + default: + set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); + ret = FALSE; } release_object( hdr ); if (ret) set_last_error( ERROR_SUCCESS ); diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index a3c8507fea..1c72c07574 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -1383,7 +1383,7 @@ static void test_set_default_proxy_config(void) set_default_proxy_reg_value( saved_proxy_settings, len, type ); }
-static void test_Timeouts (void) +static void test_timeouts(void) { BOOL ret; DWORD value, size; @@ -1972,6 +1972,70 @@ static void test_Timeouts (void) ok(ret, "%u\n", GetLastError()); ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
+ /* response timeout */ + SetLastError(0xdeadbeef); + value = 0xdeadbeef; + size = sizeof(value); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size); + ok(ret, "%u\n", GetLastError()); + ok(value == ~0u, "got %u\n", value); + + SetLastError(0xdeadbeef); + value = 30000; + ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value)); + ok(ret, "%u\n", GetLastError()); + + SetLastError(0xdeadbeef); + value = 0xdeadbeef; + size = sizeof(value); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size); + ok(ret, "%u\n", GetLastError()); + todo_wine ok(value == 0xbeefdead, "got %u\n", value); + + SetLastError(0xdeadbeef); + value = 0xdeadbeef; + size = sizeof(value); + ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size); + ok(ret, "%u\n", GetLastError()); + ok(value == ~0u, "got %u\n", value); + + SetLastError(0xdeadbeef); + value = 30000; + ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value)); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + value = 0xdeadbeef; + size = sizeof(value); + ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size); + ok(ret, "%u\n", GetLastError()); + ok(value == ~0u, "got %u\n", value); + + SetLastError(0xdeadbeef); + value = 48878; + ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value)); + ok(ret, "%u\n", GetLastError()); + + SetLastError(0xdeadbeef); + value = 0xdeadbeef; + size = sizeof(value); + ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size); + ok(ret, "%u\n", GetLastError()); + todo_wine ok(value == 48879, "got %u\n", value); + + SetLastError(0xdeadbeef); + value = 48880; + ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, sizeof(value)); + ok(ret, "%u\n", GetLastError()); + + SetLastError(0xdeadbeef); + value = 0xdeadbeef; + size = sizeof(value); + ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT, &value, &size); + ok(ret, "%u\n", GetLastError()); + ok(value == 48880, "got %u\n", value); + WinHttpCloseHandle(req); WinHttpCloseHandle(con); WinHttpCloseHandle(ses); @@ -4563,7 +4627,7 @@ START_TEST (winhttp) test_QueryOption(); test_set_default_proxy_config(); test_empty_headers_param(); - test_Timeouts(); + test_timeouts(); test_resolve_timeout(); test_credentials(); test_IWinHttpRequest_Invoke(); diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 838561fe66..6b4e3b0405 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -98,7 +98,8 @@ typedef struct int resolve_timeout; int connect_timeout; int send_timeout; - int recv_timeout; + int receive_timeout; + int receive_response_timeout; LPWSTR proxy_server; LPWSTR proxy_bypass; LPWSTR proxy_username; @@ -198,7 +199,8 @@ typedef struct int resolve_timeout; int connect_timeout; int send_timeout; - int recv_timeout; + int receive_timeout; + int receive_response_timeout; LPWSTR status_text; DWORD content_length; /* total number of bytes to be read */ DWORD content_read; /* bytes read so far */
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=41785
Your paranoid android.
=== w2003std (32 bit Windows report) ===
winhttp: winhttp.c:4047: Test failed: got 80072f0d
=== w864 (32 bit Windows report) ===
winhttp: winhttp.c:4047: Test failed: got 80090321
=== w864 (64 bit Windows report) ===
winhttp: winhttp.c:1087: Test failed: failed to send request 2148074273 winhttp.c:1091: Test failed: failed to retrieve certificate context 12019 winhttp.c:1096: Test failed: failed to retrieve key bitness 4317 winhttp.c:1100: Test failed: failed to retrieve certificate info 12019 winhttp.c:1115: Test failed: failed to receive response 12019 winhttp.c:1119: Test failed: failed to query available data 12019 winhttp.c:1120: Test failed: available_size = 0 winhttp.c:1125: Test failed: failed unexpectedly 12019 winhttp.c:1126: Test failed: request failed unexpectedly 3735928559 winhttp.c:1137: Test failed: WinHttpReadData failed: 12019. winhttp.c:1148: Test failed: failed to retrieve certificate context 12019
On Mon, 2018-09-10 at 06:34 -0500, Marvin wrote:
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=41785
Your paranoid android.
=== w2003std (32 bit Windows report) ===
winhttp: winhttp.c:4047: Test failed: got 80072f0d
=== w864 (32 bit Windows report) ===
winhttp: winhttp.c:4047: Test failed: got 80090321
=== w864 (64 bit Windows report) ===
winhttp: winhttp.c:1087: Test failed: failed to send request 2148074273 winhttp.c:1091: Test failed: failed to retrieve certificate context 12019 winhttp.c:1096: Test failed: failed to retrieve key bitness 4317 winhttp.c:1100: Test failed: failed to retrieve certificate info 12019 winhttp.c:1115: Test failed: failed to receive response 12019 winhttp.c:1119: Test failed: failed to query available data 12019 winhttp.c:1120: Test failed: available_size = 0 winhttp.c:1125: Test failed: failed unexpectedly 12019 winhttp.c:1126: Test failed: request failed unexpectedly 3735928559 winhttp.c:1137: Test failed: WinHttpReadData failed: 12019. winhttp.c:1148: Test failed: failed to retrieve certificate context 12019
These failures are intermittent and unrelated. Here's a successful run: