[PATCH 0/6] MR10586: winhttp/tests: Fix test failures on old Windows versions.
From: Hans Leidekker <hans@codeweavers.com> --- dlls/winhttp/tests/winhttp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index a6c77eba3e9..adc8e30cbde 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -287,7 +287,7 @@ static void test_WinHttpQueryOption(void) info.ConnectionInfo.dwProtocol = 0xdeadbeef; info.ConnectionInfo.dwCipherStrength = 0xdeadbeef; ret = WinHttpQueryOption(request, WINHTTP_OPTION_SECURITY_INFO, &info, &size); - ok(ret, "got %lu\n", GetLastError()); + ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* win10 <= 1909 */, "got %lu\n", GetLastError()); if (ret) { ok(info.ConnectionInfo.dwProtocol == 0, "got %lu\n", info.ConnectionInfo.dwProtocol); @@ -1225,7 +1225,7 @@ static void test_secure_connection(void) size = sizeof(secinfo); ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_INFO, &secinfo, &size); - ok(ret, "got %lu\n", GetLastError()); + ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_PARAMETER) /* win10 <= 1909 */, "got %lu\n", GetLastError()); if (ret) { ok(secinfo.ConnectionInfo.dwProtocol == SP_PROT_TLS1_2_CLIENT, "got %lu\n", secinfo.ConnectionInfo.dwProtocol); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10586
From: Hans Leidekker <hans@codeweavers.com> --- dlls/winhttp/tests/notification.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/winhttp/tests/notification.c b/dlls/winhttp/tests/notification.c index b4d942ff30f..83c57ee4469 100644 --- a/dlls/winhttp/tests/notification.c +++ b/dlls/winhttp/tests/notification.c @@ -1900,7 +1900,7 @@ static void CALLBACK test_recursion_callback( HINTERNET handle, DWORD_PTR contex break; } - ok( context->recursion_count < TEST_RECURSION_LIMIT, + ok( context->recursion_count <= TEST_RECURSION_LIMIT, "got %lu, thread %#lx\n", context->recursion_count, GetCurrentThreadId() ); context->max_recursion_query = max( context->max_recursion_query, context->recursion_count ); InterlockedIncrement( &context->recursion_count ); @@ -1926,7 +1926,7 @@ static void CALLBACK test_recursion_callback( HINTERNET handle, DWORD_PTR contex SetEvent( context->wait ); break; } - ok( context->recursion_count < TEST_RECURSION_LIMIT, + ok( context->recursion_count <= TEST_RECURSION_LIMIT, "got %lu, thread %#lx\n", context->recursion_count, GetCurrentThreadId() ); context->max_recursion_read = max( context->max_recursion_read, context->recursion_count ); context->read_from_callback = TRUE; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10586
From: Hans Leidekker <hans@codeweavers.com> --- dlls/winhttp/request.c | 58 +++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 54896eed72a..f99b0e73f5c 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -3720,13 +3720,13 @@ BOOL WINAPI WinHttpWriteData( HINTERNET hrequest, const void *buffer, DWORD to_w return !ret; } -enum request_state +enum winhttp_request_state { - REQUEST_STATE_INITIALIZED, - REQUEST_STATE_CANCELLED, - REQUEST_STATE_OPEN, - REQUEST_STATE_SENT, - REQUEST_STATE_RESPONSE_RECEIVED + WINHTTP_REQUEST_STATE_INITIALIZED, + WINHTTP_REQUEST_STATE_CANCELLED, + WINHTTP_REQUEST_STATE_OPEN, + WINHTTP_REQUEST_STATE_SENT, + WINHTTP_REQUEST_STATE_RESPONSE_RECEIVED }; struct winhttp_request @@ -3734,7 +3734,7 @@ struct winhttp_request IWinHttpRequest IWinHttpRequest_iface; LONG refs; CRITICAL_SECTION cs; - enum request_state state; + enum winhttp_request_state state; HINTERNET hsession; HINTERNET hconnect; HINTERNET hrequest; @@ -3776,7 +3776,7 @@ static ULONG WINAPI winhttp_request_AddRef( /* critical section must be held */ static void cancel_request( struct winhttp_request *request ) { - if (request->state <= REQUEST_STATE_CANCELLED) return; + if (request->state <= WINHTTP_REQUEST_STATE_CANCELLED) return; if (request->proc_running) { @@ -3787,13 +3787,13 @@ static void cancel_request( struct winhttp_request *request ) EnterCriticalSection( &request->cs ); } - request->state = REQUEST_STATE_CANCELLED; + request->state = WINHTTP_REQUEST_STATE_CANCELLED; } /* critical section must be held */ static void free_request( struct winhttp_request *request ) { - if (request->state < REQUEST_STATE_INITIALIZED) return; + if (request->state < WINHTTP_REQUEST_STATE_INITIALIZED) return; WinHttpCloseHandle( request->hrequest ); WinHttpCloseHandle( request->hconnect ); WinHttpCloseHandle( request->hsession ); @@ -4096,7 +4096,7 @@ static HRESULT WINAPI winhttp_request_SetCredentials( TRACE( "%p, %s, %p, %#lx\n", request, debugstr_w(username), password, flags ); EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_OPEN) + if (request->state < WINHTTP_REQUEST_STATE_OPEN) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN; goto done; @@ -4132,7 +4132,7 @@ static void initialize_request( struct winhttp_request *request ) request->receive_timeout = 30000; request->url_codepage = CP_UTF8; VariantInit( &request->data ); - request->state = REQUEST_STATE_INITIALIZED; + request->state = WINHTTP_REQUEST_STATE_INITIALIZED; } static void reset_request( struct winhttp_request *request ) @@ -4162,7 +4162,7 @@ static void reset_request( struct winhttp_request *request ) free( request->proxy.lpszProxyBypass ); request->proxy.lpszProxyBypass = NULL; VariantClear( &request->data ); - request->state = REQUEST_STATE_INITIALIZED; + request->state = WINHTTP_REQUEST_STATE_INITIALIZED; } static HRESULT WINAPI winhttp_request_Open( @@ -4241,7 +4241,7 @@ static HRESULT WINAPI winhttp_request_Open( } WinHttpSetOption( request->hrequest, WINHTTP_OPTION_CONTEXT_VALUE, &request, sizeof(request) ); - request->state = REQUEST_STATE_OPEN; + request->state = WINHTTP_REQUEST_STATE_OPEN; request->verb = verb; free( hostname ); free( path ); @@ -4272,12 +4272,12 @@ static HRESULT WINAPI winhttp_request_SetRequestHeader( if (!header) return E_INVALIDARG; EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_OPEN) + if (request->state < WINHTTP_REQUEST_STATE_OPEN) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN; goto done; } - if (request->state >= REQUEST_STATE_SENT) + if (request->state >= WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND; goto done; @@ -4313,7 +4313,7 @@ static HRESULT WINAPI winhttp_request_GetResponseHeader( TRACE("%p, %p\n", request, header); EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_SENT) + if (request->state < WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND; goto done; @@ -4357,7 +4357,7 @@ static HRESULT WINAPI winhttp_request_GetAllResponseHeaders( if (!headers) return E_INVALIDARG; EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_SENT) + if (request->state < WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND; goto done; @@ -4450,7 +4450,7 @@ static HRESULT request_receive( struct winhttp_request *request ) if ((err = wait_for_completion( request ))) return HRESULT_FROM_WIN32( err ); if (!wcscmp( request->verb, L"HEAD" )) { - request->state = REQUEST_STATE_RESPONSE_RECEIVED; + request->state = WINHTTP_REQUEST_STATE_RESPONSE_RECEIVED; return S_OK; } if (!(request->buffer = malloc( buflen ))) return E_OUTOFMEMORY; @@ -4489,7 +4489,7 @@ static HRESULT request_receive( struct winhttp_request *request ) request->offset += request->bytes_read; } while (request->bytes_read); - request->state = REQUEST_STATE_RESPONSE_RECEIVED; + request->state = WINHTTP_REQUEST_STATE_RESPONSE_RECEIVED; return S_OK; error: @@ -4585,7 +4585,7 @@ static HRESULT request_send( struct winhttp_request *request ) if ((err = wait_for_completion( request ))) goto error; if (sa) SafeArrayUnaccessData( sa ); else free( ptr ); - request->state = REQUEST_STATE_SENT; + request->state = WINHTTP_REQUEST_STATE_SENT; return S_OK; error: @@ -4644,12 +4644,12 @@ static HRESULT WINAPI winhttp_request_Send( TRACE("%p, %s\n", request, debugstr_variant(&body)); EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_OPEN) + if (request->state < WINHTTP_REQUEST_STATE_OPEN) { LeaveCriticalSection( &request->cs ); return HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ); } - if (request->state >= REQUEST_STATE_SENT) + if (request->state >= WINHTTP_REQUEST_STATE_SENT) { LeaveCriticalSection( &request->cs ); return S_OK; @@ -4686,7 +4686,7 @@ static HRESULT WINAPI winhttp_request_get_Status( if (!status) return E_INVALIDARG; EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_SENT) + if (request->state < WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND; goto done; @@ -4716,7 +4716,7 @@ static HRESULT WINAPI winhttp_request_get_StatusText( if (!status) return E_INVALIDARG; EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_SENT) + if (request->state < WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND; goto done; @@ -4787,7 +4787,7 @@ static HRESULT WINAPI winhttp_request_get_ResponseText( if (!body) return E_INVALIDARG; EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_SENT) + if (request->state < WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND; goto done; @@ -4822,7 +4822,7 @@ static HRESULT WINAPI winhttp_request_get_ResponseBody( if (!body) return E_INVALIDARG; EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_SENT) + if (request->state < WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND; goto done; @@ -5023,7 +5023,7 @@ static HRESULT WINAPI winhttp_request_get_ResponseStream( if (!body) return E_INVALIDARG; EnterCriticalSection( &request->cs ); - if (request->state < REQUEST_STATE_SENT) + if (request->state < WINHTTP_REQUEST_STATE_SENT) { err = ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND; goto done; @@ -5159,7 +5159,7 @@ static HRESULT WINAPI winhttp_request_WaitForResponse( TRACE("%p, %s, %p\n", request, debugstr_variant(&timeout), succeeded); EnterCriticalSection( &request->cs ); - if (request->state >= REQUEST_STATE_RESPONSE_RECEIVED) + if (request->state >= WINHTTP_REQUEST_STATE_RESPONSE_RECEIVED) { LeaveCriticalSection( &request->cs ); return S_OK; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10586
From: Hans Leidekker <hans@codeweavers.com> --- dlls/winhttp/request.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index f99b0e73f5c..d7dc2bb39d5 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -2849,9 +2849,9 @@ static void remove_data( struct request *request, int count ) } /* read some more data into the read buffer */ -static DWORD read_more_data( struct request *request, int max_len, BOOL notify ) +static DWORD read_more_data( struct request *request ) { - int len; + int len, max_len; DWORD ret; if (request->read.pos) @@ -2859,13 +2859,9 @@ static DWORD read_more_data( struct request *request, int max_len, BOOL notify ) if (request->read.size) memmove( request->read.buf, request->read.buf + request->read.pos, request->read.size ); request->read.pos = 0; } - if (max_len == -1) max_len = sizeof(request->read.buf); - - if (notify) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); - - ret = netconn_recv( request->netconn, request->read.buf + request->read.size, max_len - request->read.size, 0, &len ); + max_len = sizeof(request->read.buf) - request->read.size; - if (notify) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, &len, sizeof(len) ); + ret = netconn_recv( request->netconn, request->read.buf + request->read.size, max_len, 0, &len ); request->read_reply_len += len; request->read.size += len; @@ -2893,7 +2889,7 @@ static DWORD read_line( struct request *request, char *buffer, DWORD *len ) remove_data( request, bytes_read ); if (eol) break; - if ((ret = read_more_data( request, -1, FALSE ))) return ret; + if ((ret = read_more_data( request ))) return ret; if (!request->read.size) { *len = 0; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10586
From: Hans Leidekker <hans@codeweavers.com> As a result we can simplify the request state machine. --- dlls/winhttp/request.c | 155 ++++++++++++--------------------- dlls/winhttp/session.c | 1 - dlls/winhttp/winhttp_private.h | 23 +++-- 3 files changed, 66 insertions(+), 113 deletions(-) diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index d7dc2bb39d5..31b74ce3e9e 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -53,7 +53,7 @@ static DWORD query_data_stream( struct request *request, DWORD *size ) if (!request->read.size) ret = request->data_stream->vtbl->fill_buffer( request->data_stream, request, &request->read ); - *size = request->read.size; + if (size) *size = request->read.size; return ret; } @@ -470,12 +470,6 @@ static void gzip_zfree( voidpf opaque, voidpf address ) free( address ); } -static int request_receive_response_timeout( struct request *req ) -{ - if (req->receive_response_timeout == -1) return ACTUAL_DEFAULT_RECEIVE_RESPONSE_TIMEOUT; - return req->receive_response_timeout; -} - static const WCHAR *attribute_table[] = { L"Mime-Version", /* WINHTTP_QUERY_MIME_VERSION = 0 */ @@ -1256,7 +1250,7 @@ BOOL WINAPI WinHttpQueryHeaders( HINTERNET hrequest, DWORD level, const WCHAR *n SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); return FALSE; } - if (request->state < REQUEST_RESPONSE_STATE_RESPONSE_RECEIVED && !(level & WINHTTP_QUERY_FLAG_REQUEST_HEADERS) + if (request->state < REQUEST_STATE_RESPONSE_RECEIVED && !(level & WINHTTP_QUERY_FLAG_REQUEST_HEADERS) && ((level & ~QUERY_MODIFIER_MASK) != WINHTTP_QUERY_REQUEST_METHOD)) { release_object( &request->hdr ); @@ -1990,6 +1984,12 @@ static DWORD ensure_cred_handle( struct request *request ) return ERROR_SUCCESS; } +static int get_receive_response_timeout( struct request *request ) +{ + if (request->receive_response_timeout == -1) return ACTUAL_DEFAULT_RECEIVE_RESPONSE_TIMEOUT; + return request->receive_response_timeout; +} + static DWORD open_connection( struct request *request ) { BOOL is_secure = request->hdr.flags & WINHTTP_FLAG_SECURE; @@ -2105,7 +2105,7 @@ static DWORD open_connection( struct request *request ) return ret; } netconn_set_timeout( netconn, TRUE, request->send_timeout ); - netconn_set_timeout( netconn, FALSE, request_receive_response_timeout( request )); + netconn_set_timeout( netconn, FALSE, get_receive_response_timeout( request )); request->netconn = netconn; @@ -2143,7 +2143,7 @@ static DWORD open_connection( struct request *request ) TRACE("using connection %p\n", netconn); netconn_set_timeout( netconn, TRUE, request->send_timeout ); - netconn_set_timeout( netconn, FALSE, request_receive_response_timeout( request )); + netconn_set_timeout( netconn, FALSE, get_receive_response_timeout( request )); request->netconn = netconn; } @@ -2431,7 +2431,6 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD struct connect *connect = request->connect; struct session *session = connect->session; DWORD ret, len, buflen; - UINT64 content_length; WCHAR buf[21]; char *wire_req; int bytes_sent; @@ -2439,9 +2438,8 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD TRACE( "request state %d.\n", request->state ); - request->read_reply_status = ERROR_WINHTTP_INCORRECT_HANDLE_STATE; - request->read_reply_len = 0; - request->state = REQUEST_RESPONSE_STATE_NONE; + request->reply_len = 0; + request->state = REQUEST_STATE_NONE; if (request->flags & REQUEST_FLAG_WEBSOCKET_UPGRADE && request->websocket_set_send_buffer_size < MIN_WEBSOCKET_SEND_BUFFER_SIZE) @@ -2524,7 +2522,7 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD } TRACE("full request: %s\n", debugstr_a(wire_req)); - request->state = REQUEST_RESPONSE_STATE_SENDING_REQUEST; + request->state = REQUEST_STATE_SENDING_REQUEST; send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST, NULL, 0 ); ret = netconn_send( request->netconn, wire_req, len, &bytes_sent, NULL ); @@ -2538,31 +2536,9 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD request->optional_len = optional_len; len += optional_len; } - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_SENT, &len, sizeof(len) ); - - buflen = sizeof(buf); - if (query_headers( request, WINHTTP_QUERY_FLAG_REQUEST_HEADERS | WINHTTP_QUERY_CONTENT_LENGTH, - NULL, buf, &buflen, NULL )) - content_length = total_len; - else - content_length = wcstoull( buf, NULL, 10 ); - if (!chunked && content_length <= optional_len) - { - netconn_set_timeout( request->netconn, FALSE, request_receive_response_timeout( request )); - request->read_reply_status = read_reply( request ); - if (request->state == REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED) - request->state = REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED_REPLY_RECEIVED; - else - request->state = REQUEST_RESPONSE_STATE_REPLY_RECEIVED; - } - else - { - if (request->state == REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED) - request->state = REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED_REQUEST_SENT; - else - request->state = REQUEST_RESPONSE_STATE_REQUEST_SENT; - } + request->state = REQUEST_STATE_REQUEST_SENT; + send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_SENT, &len, sizeof(len) ); end: if (async) @@ -2824,6 +2800,7 @@ static DWORD set_content_length( struct request *request, DWORD status ) } request->data_stream = &chunked_stream->data_stream; request->content_length = ~0ull; + query_data_stream( request, NULL ); /* start first chunk */ } if (request->hdr.decompression) @@ -2863,7 +2840,7 @@ static DWORD read_more_data( struct request *request ) ret = netconn_recv( request->netconn, request->read.buf + request->read.size, max_len, 0, &len ); - request->read_reply_len += len; + request->reply_len += len; request->read.size += len; return ret; } @@ -3227,50 +3204,29 @@ static DWORD queue_receive_response( struct request *request ) static DWORD receive_response( struct request *request ) { - BOOL async_mode = request->connect->hdr.flags & WINHTTP_FLAG_ASYNC; + BOOL async = request->connect->hdr.flags & WINHTTP_FLAG_ASYNC; DWORD ret, size, query, status; - TRACE( "request state %d.\n", request->state ); + TRACE( "request state %d\n", request->state ); switch (request->state) { - case REQUEST_RESPONSE_RECURSIVE_REQUEST: - TRACE( "Sending request.\n" ); + case REQUEST_STATE_RECURSIVE_REQUEST: + TRACE( "sending request again\n" ); if ((ret = send_request( request, NULL, 0, request->optional, request->optional_len, 0, 0, FALSE ))) goto done; - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); break; - case REQUEST_RESPONSE_STATE_SENDING_REQUEST: - if (!async_mode) + case REQUEST_STATE_SENDING_REQUEST: + if (!async) { ret = ERROR_WINHTTP_INCORRECT_HANDLE_STATE; goto done; } - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); - request->state = REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED; + request->state = REQUEST_STATE_READ_RESPONSE_QUEUED; return queue_receive_response( request ); - - case REQUEST_RESPONSE_STATE_REQUEST_SENT: - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); - if (async_mode) - { - request->state = REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED_REQUEST_SENT; - return queue_receive_response( request ); - } - /* fallthrough */ - case REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED_REQUEST_SENT: - netconn_set_timeout( request->netconn, FALSE, request_receive_response_timeout( request )); - request->read_reply_status = read_reply( request ); - request->state = REQUEST_RESPONSE_STATE_REPLY_RECEIVED; - break; - - case REQUEST_RESPONSE_STATE_REPLY_RECEIVED: - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); - break; - - case REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED_REPLY_RECEIVED: - request->state = REQUEST_RESPONSE_STATE_REPLY_RECEIVED; + case REQUEST_STATE_REQUEST_SENT: + case REQUEST_STATE_READ_RESPONSE_QUEUED: break; default: @@ -3278,9 +3234,15 @@ static DWORD receive_response( struct request *request ) goto done; } - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, - &request->read_reply_len, sizeof(request->read_reply_len) ); - if ((ret = request->read_reply_status)) goto done; + request->state = REQUEST_STATE_RECEIVING_RESPONSE; + send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); + + netconn_set_timeout( request->netconn, FALSE, get_receive_response_timeout( request )); + ret = read_reply( request ); + + request->state = REQUEST_STATE_RESPONSE_RECEIVED; + send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, &request->reply_len, sizeof(request->reply_len) ); + if (ret) goto done; size = sizeof(DWORD); query = WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER; @@ -3317,16 +3279,16 @@ static DWORD receive_response( struct request *request ) } else goto done; - request->state = REQUEST_RESPONSE_RECURSIVE_REQUEST; - return async_mode ? queue_receive_response( request ) : receive_response( request ); + request->state = REQUEST_STATE_RECURSIVE_REQUEST; + return async ? queue_receive_response( request ) : receive_response( request ); done: if (!ret) { - request->state = REQUEST_RESPONSE_STATE_RESPONSE_RECEIVED; + request->state = REQUEST_STATE_RESPONSE_RECEIVED; if (request->netconn) netconn_set_timeout( request->netconn, FALSE, request->receive_timeout ); } - if (async_mode) + if (async) { if (!ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE, NULL, 0 ); else @@ -3385,7 +3347,7 @@ static BOOL skip_async_queue( struct request *request, BOOL *wont_block, DWORD t { to_read = min( to_read, request->content_length - request->content_read ); *wont_block = end_of_data_stream( request ) || request->read.size >= to_read; - return request->hdr.recursion_count < 3 && *wont_block; + return request->hdr.recursion_count <= 3 && *wont_block; } static DWORD query_data_available( struct request *request, DWORD *available, BOOL async ) @@ -3448,7 +3410,7 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); return FALSE; } - if (request->state < REQUEST_RESPONSE_STATE_RESPONSE_RECEIVED) + if (request->state < REQUEST_STATE_RESPONSE_RECEIVED) { release_object( &request->hdr ); SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_STATE ); @@ -3487,10 +3449,8 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) s->buflen = sizeof(s->result); } - if ((ret = queue_task( &request->queue, task_send_callback, &s->task_hdr, &request->hdr ))) - free( s ); - else - ret = ERROR_IO_PENDING; + if ((ret = queue_task( &request->queue, task_send_callback, &s->task_hdr, &request->hdr ))) free( s ); + else ret = ERROR_IO_PENDING; } else { @@ -3505,10 +3465,8 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) q->available = available; - if ((ret = queue_task( &request->queue, task_query_data_available, &q->task_hdr, &request->hdr ))) - free( q ); - else - ret = ERROR_IO_PENDING; + if ((ret = queue_task( &request->queue, task_query_data_available, &q->task_hdr, &request->hdr ))) free( q ); + else ret = ERROR_IO_PENDING; } release_object( &request->hdr ); @@ -3607,10 +3565,8 @@ BOOL WINAPI WinHttpReadData( HINTERNET hrequest, void *buffer, DWORD to_read, DW s->buflen = sizeof(s->result); } - if ((ret = queue_task( &request->queue, task_send_callback, &s->task_hdr, &request->hdr ))) - free( s ); - else - ret = ERROR_IO_PENDING; + if ((ret = queue_task( &request->queue, task_send_callback, &s->task_hdr, &request->hdr ))) free( s ); + else ret = ERROR_IO_PENDING; } else { @@ -3626,10 +3582,8 @@ BOOL WINAPI WinHttpReadData( HINTERNET hrequest, void *buffer, DWORD to_read, DW r->to_read = to_read; r->read = read; - if ((ret = queue_task( &request->queue, task_read_data, &r->task_hdr, &request->hdr ))) - free( r ); - else - ret = ERROR_IO_PENDING; + if ((ret = queue_task( &request->queue, task_read_data, &r->task_hdr, &request->hdr ))) free( r ); + else ret = ERROR_IO_PENDING; } release_object( &request->hdr ); @@ -3677,6 +3631,7 @@ BOOL WINAPI WinHttpWriteData( HINTERNET hrequest, const void *buffer, DWORD to_w { DWORD ret; struct request *request; + BOOL async; TRACE( "%p, %p, %lu, %p\n", hrequest, buffer, to_write, written ); @@ -3692,7 +3647,11 @@ BOOL WINAPI WinHttpWriteData( HINTERNET hrequest, const void *buffer, DWORD to_w return FALSE; } - if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) + if (!(async = request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) || request->hdr.recursion_count <= 3) + { + ret = write_data( request, buffer, to_write, written, async ); + } + else { struct write_data *w; @@ -3706,10 +3665,8 @@ BOOL WINAPI WinHttpWriteData( HINTERNET hrequest, const void *buffer, DWORD to_w w->to_write = to_write; w->written = written; - if ((ret = queue_task( &request->queue, task_write_data, &w->task_hdr, &request->hdr ))) - free( w ); + if ((ret = queue_task( &request->queue, task_write_data, &w->task_hdr, &request->hdr ))) free( w ); } - else ret = write_data( request, buffer, to_write, written, FALSE ); release_object( &request->hdr ); SetLastError( ret ); diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index 2face5115b2..ca9e628660a 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -1486,7 +1486,6 @@ HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, const WCHAR *verb, cons request->websocket_receive_buffer_size = connect->session->websocket_receive_buffer_size; request->websocket_send_buffer_size = connect->session->websocket_send_buffer_size; request->websocket_set_send_buffer_size = request->websocket_send_buffer_size; - request->read_reply_status = ERROR_WINHTTP_INCORRECT_HANDLE_STATE; request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl; request->data_stream = &request->netconn_stream.data_stream; diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 44a91a37d6f..99f57749856 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -171,17 +171,15 @@ enum request_flags REQUEST_FLAG_WEBSOCKET_UPGRADE = 0x01, }; -enum request_response_state +enum request_state { - REQUEST_RESPONSE_STATE_NONE, - REQUEST_RESPONSE_STATE_SENDING_REQUEST, - REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED, - REQUEST_RESPONSE_STATE_REQUEST_SENT, - REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED_REQUEST_SENT, - REQUEST_RESPONSE_STATE_REPLY_RECEIVED, - REQUEST_RESPONSE_STATE_READ_RESPONSE_QUEUED_REPLY_RECEIVED, - REQUEST_RESPONSE_RECURSIVE_REQUEST, - REQUEST_RESPONSE_STATE_RESPONSE_RECEIVED, + REQUEST_STATE_NONE, + REQUEST_STATE_RECURSIVE_REQUEST, + REQUEST_STATE_SENDING_REQUEST, + REQUEST_STATE_REQUEST_SENT, + REQUEST_STATE_READ_RESPONSE_QUEUED, + REQUEST_STATE_RECEIVING_RESPONSE, + REQUEST_STATE_RESPONSE_RECEIVED, }; #define READ_BUFFER_SIZE 8192 @@ -259,9 +257,8 @@ struct request } creds[TARGET_MAX][SCHEME_MAX]; unsigned int websocket_receive_buffer_size; unsigned int websocket_send_buffer_size, websocket_set_send_buffer_size; - int read_reply_len; - DWORD read_reply_status; - enum request_response_state state; + int reply_len; + enum request_state state; }; enum socket_state -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10586
From: Hans Leidekker <hans@codeweavers.com> --- dlls/winhttp/tests/winhttp.c | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index adc8e30cbde..5625eb86fa5 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -6374,6 +6374,80 @@ static void test_decompression(void) WinHttpCloseHandle( ses ); } +static void CALLBACK status_callback( HINTERNET req, DWORD_PTR ctx, DWORD status, void *buf, DWORD buflen ) +{ + HANDLE wait = (HANDLE)ctx; + DWORD size, code; + char data[32]; + BOOL ret; + + switch (status) + { + case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE: + ret = WinHttpWriteData( req, "data", 4, NULL ); + ok( ret, "got %lu\n", GetLastError() ); + break; + + case WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE: + ret = WinHttpReceiveResponse( req, 0 ); + ok( ret, "got %lu\n", GetLastError() ); + break; + + case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE: + code = 0xdeadbeef; + size = sizeof(code); + ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &code, &size, NULL ); + ok( ret, "got %lu\n", GetLastError() ); + ok( code == HTTP_STATUS_OK, "got %lu\n", code ); + + ret = WinHttpQueryDataAvailable( req, NULL ); + ok( ret, "got %lu\n", GetLastError() ); + break; + + case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE: + ret = WinHttpReadData( req, data, sizeof(data), NULL ); + ok( ret, "got %lu\n", GetLastError() ); + break; + + case WINHTTP_CALLBACK_STATUS_READ_COMPLETE: + SetEvent( wait ); + break; + + default: + ok( 0, "unexpected status %08lx\n", status ); + break; + } +} + +static void test_recursive_async(void) +{ + HINTERNET ses, req, con; + HANDLE wait = CreateEventW( NULL, 0, 0, NULL ); + DWORD err; + BOOL ret; + + ses = WinHttpOpen( L"winetest", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, WINHTTP_FLAG_ASYNC ); + ok( ses != NULL, "got %lu\n", GetLastError() ); + + con = WinHttpConnect( ses, L"test.winehq.org", 0, 0 ); + ok( con != NULL, "got %lu\n", GetLastError() ); + + req = WinHttpOpenRequest( con, L"POST", L"tests/post.php", NULL, NULL, NULL, 0 ); + ok( req != NULL, "got %lu\n", GetLastError() ); + + WinHttpSetStatusCallback( req, status_callback, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, 0 ); + + ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 4, (DWORD_PTR)wait ); + ok( ret, "got %lu\n", GetLastError() ); + err = WaitForSingleObject( wait, 10000 ); + ok( err == WAIT_OBJECT_0, "got %08lx\n", err ); + + WinHttpCloseHandle( req ); + WinHttpCloseHandle( con ); + WinHttpCloseHandle( ses ); + CloseHandle( wait ); +} + START_TEST (winhttp) { struct server_info si; @@ -6409,6 +6483,7 @@ START_TEST (winhttp) test_chunked_read(); test_max_http_automatic_redirects(); test_decompression(); + test_recursive_async(); si.event = CreateEventW(NULL, 0, 0, NULL); si.port = 7532; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10586
participants (2)
-
Hans Leidekker -
Hans Leidekker (@hans)