From: Paul Gofman pgofman@codeweavers.com
--- dlls/winhttp/request.c | 57 ++++++++++++++++++++++------------ dlls/winhttp/winhttp_private.h | 8 +++++ 2 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 91febf40e97..cddd9235b9e 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -2851,39 +2851,57 @@ static DWORD receive_server_response( struct request *request )
static void task_receive_response( void *ctx, BOOL abort );
-static DWORD queue_receive_response( struct request *request ) +static DWORD queue_receive_response( struct request *request, enum receive_response_queue_state queue_state ) { struct receive_response *r; DWORD ret;
if (!(r = malloc( sizeof(*r) ))) return ERROR_OUTOFMEMORY; + r->queue_state = queue_state; if ((ret = queue_task( &request->queue, task_receive_response, &r->task_hdr, &request->hdr ))) free( r ); return ret; }
-static DWORD receive_response( struct request *request, BOOL async ) +static DWORD receive_response( struct request *request, enum receive_response_queue_state queue_state ) { + BOOL async_mode = request->connect->hdr.flags & WINHTTP_FLAG_ASYNC; DWORD ret;
- if (!request->netconn) return ERROR_WINHTTP_INCORRECT_HANDLE_STATE; + TRACE( "request %p, queue_state %d, async_mode %d.\n", request, queue_state, async_mode );
- for (;;) + if (queue_state == RECEIVE_RESPONSE_RECURSIVE_REQUEST) { - 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) ); - if ((ret = receive_server_response( request ))) break; - if (!request->recursive_request) break; - if (request->redirect_location) - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REDIRECT, - request->redirect_location, request->redirect_location_len + 1 ); - /* recurse synchronously */ - if (!(ret = send_request( request, NULL, 0, request->optional, request->optional_len, 0, 0, FALSE ))) continue; - break; + TRACE( "Sending request.\n" ); + ret = send_request( request, NULL, 0, request->optional, request->optional_len, 0, 0, FALSE ); + if (ret) goto done; }
- if (async) + if (async_mode && !queue_state) + return queue_receive_response( request, RECEIVE_RESPONSE_SEND_INCOMPLETE ); + + if (!request->netconn) + { + ret = ERROR_WINHTTP_INCORRECT_HANDLE_STATE; + goto done; + } + + ret = receive_server_response( request ); + + 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) ); + + 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 ); + +done: + if (async_mode) { if (!ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE, NULL, 0 ); else @@ -2894,7 +2912,7 @@ static DWORD receive_response( struct request *request, BOOL async ) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, &result, sizeof(result) ); } } - return ret; + return async_mode ? ERROR_SUCCESS : ret; }
static void task_receive_response( void *ctx, BOOL abort ) @@ -2905,7 +2923,7 @@ static void task_receive_response( void *ctx, BOOL abort ) if (abort) return;
TRACE("running %p\n", ctx); - receive_response( request, TRUE ); + receive_response( request, r->queue_state ); }
/*********************************************************************** @@ -2930,8 +2948,7 @@ BOOL WINAPI WinHttpReceiveResponse( HINTERNET hrequest, LPVOID reserved ) return FALSE; }
- if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC) ret = queue_receive_response( request ); - else ret = receive_response( request, FALSE ); + ret = receive_response( request, RECEIVE_RESPONSE_NOT_QUEUED );
release_object( &request->hdr ); SetLastError( ret ); diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index cffad0e0c74..f0680c16469 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -311,9 +311,17 @@ struct send_request DWORD_PTR context; };
+enum receive_response_queue_state +{ + RECEIVE_RESPONSE_NOT_QUEUED, + RECEIVE_RESPONSE_SEND_INCOMPLETE, + RECEIVE_RESPONSE_RECURSIVE_REQUEST, +}; + struct receive_response { struct task_header task_hdr; + enum receive_response_queue_state queue_state; };
struct query_data