From: Paul Gofman pgofman@codeweavers.com
--- dlls/winhttp/request.c | 42 +++++++++++++++++++++++++++------- dlls/winhttp/tests/winhttp.c | 8 +++---- dlls/winhttp/winhttp_private.h | 4 ++++ 3 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index cddd9235b9e..24894b48188 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -800,6 +800,13 @@ BOOL WINAPI WinHttpQueryHeaders( HINTERNET hrequest, DWORD level, const WCHAR *n SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); return FALSE; } + if (!request->receive_response_complete && !(level & WINHTTP_QUERY_FLAG_REQUEST_HEADERS) + && ((level & ~QUERY_MODIFIER_MASK) != WINHTTP_QUERY_REQUEST_METHOD)) + { + release_object( &request->hdr ); + SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_STATE ); + return FALSE; + }
ret = query_headers( request, level, name, buffer, buflen, index );
@@ -2166,6 +2173,8 @@ static DWORD add_websocket_key_header( struct request *request ) return ERROR_SUCCESS; }
+static DWORD receive_server_response( struct request *request ); + static DWORD send_request( struct request *request, const WCHAR *headers, DWORD headers_len, void *optional, DWORD optional_len, DWORD total_len, DWORD_PTR context, BOOL async ) { @@ -2175,6 +2184,8 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD int bytes_sent; DWORD ret, len;
+ request->server_reply_complete = FALSE; + request->receive_response_complete = FALSE; request->read_reply_len = 0; free( request->redirect_location ); request->redirect_location = NULL; @@ -2245,6 +2256,7 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD } TRACE("full request: %s\n", debugstr_a(wire_req));
+ request->sending_request = TRUE; send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST, NULL, 0 );
ret = netconn_send( request->netconn, wire_req, len, &bytes_sent, NULL ); @@ -2259,8 +2271,11 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD len += optional_len; } send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_SENT, &len, sizeof(len) ); - + request->server_reply_status = receive_server_response( request ); + request->server_reply_complete = TRUE; end: + request->sending_request = FALSE; + if (async) { if (!ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE, NULL, 0 ); @@ -2870,6 +2885,12 @@ static DWORD receive_response( struct request *request, enum receive_response_qu
TRACE( "request %p, queue_state %d, async_mode %d.\n", request, queue_state, async_mode );
+ if (request->receive_response_complete) + { + ret = ERROR_WINHTTP_INCORRECT_HANDLE_STATE; + goto done; + } + if (queue_state == RECEIVE_RESPONSE_RECURSIVE_REQUEST) { TRACE( "Sending request.\n" ); @@ -2877,30 +2898,35 @@ static DWORD receive_response( struct request *request, enum receive_response_qu if (ret) goto done; }
- if (async_mode && !queue_state) - return queue_receive_response( request, RECEIVE_RESPONSE_SEND_INCOMPLETE ); - - if (!request->netconn) + if (!request->server_reply_complete && !(async_mode && request->sending_request)) { ret = ERROR_WINHTTP_INCORRECT_HANDLE_STATE; goto done; }
- ret = receive_server_response( request ); + if (queue_state != RECEIVE_RESPONSE_SEND_INCOMPLETE) + send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); + + if (!request->server_reply_complete && async_mode && request->sending_request) + return queue_receive_response( request, RECEIVE_RESPONSE_SEND_INCOMPLETE );
- send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, &request->read_reply_len, sizeof(request->read_reply_len) );
+ ret = request->server_reply_status; if (ret || !request->recursive_request) goto done;
if (request->redirect_location) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REDIRECT, request->redirect_location, request->redirect_location_len + 1 );
- return receive_response( request, RECEIVE_RESPONSE_RECURSIVE_REQUEST ); + if (async_mode) + return queue_receive_response( request, RECEIVE_RESPONSE_RECURSIVE_REQUEST ); + else + return receive_response( request, RECEIVE_RESPONSE_RECURSIVE_REQUEST );
done: + if (!ret) request->receive_response_complete = TRUE; if (async_mode) { if (!ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE, NULL, 0 ); diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index b7deaea324a..76f12837e86 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -3277,14 +3277,14 @@ static void test_websocket(int port) ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_UPGRADE, NULL, &header, &size, NULL); error = GetLastError(); ok(!ret, "success\n"); - todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error); + ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
size = sizeof(header); SetLastError(0xdeadbeef); ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CONNECTION, NULL, &header, &size, NULL); error = GetLastError(); ok(!ret, "success\n"); - todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error); + ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
index = 0; size = sizeof(buf); @@ -3312,14 +3312,14 @@ static void test_websocket(int port) ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_UPGRADE, NULL, &header, &size, NULL); error = GetLastError(); ok(!ret, "success\n"); - todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error); + ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
size = sizeof(header); SetLastError(0xdeadbeef); ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CONNECTION, NULL, &header, &size, NULL); error = GetLastError(); ok(!ret, "success\n"); - todo_wine ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error); + ok(error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %lu\n", error);
index = 0; buf[0] = 0; diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index f0680c16469..e1519c73c4f 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -220,10 +220,14 @@ struct request } creds[TARGET_MAX][SCHEME_MAX]; unsigned int websocket_receive_buffer_size; unsigned int websocket_send_buffer_size, websocket_set_send_buffer_size; + BOOL sending_request; + BOOL server_reply_complete; + DWORD server_reply_status; int read_reply_len; WCHAR *redirect_location; DWORD redirect_location_len; BOOL recursive_request; + BOOL receive_response_complete; };
enum socket_state