From: Paul Gofman pgofman@codeweavers.com
--- dlls/winhttp/request.c | 64 +++++++++++++++++----------------- dlls/winhttp/session.c | 1 + dlls/winhttp/winhttp_private.h | 3 ++ 3 files changed, 36 insertions(+), 32 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index e04d5a04e9d..f878fd18dc0 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -1772,6 +1772,7 @@ static DWORD read_more_data( struct request *request, int maxlen, BOOL notify ) maxlen - request->read_size, 0, &len );
if (notify) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, &len, sizeof(len) ); + request->read_reply_len += len;
request->read_size += len; return ret; @@ -2174,6 +2175,10 @@ static DWORD send_request( struct request *request, const WCHAR *headers, DWORD int bytes_sent; DWORD ret, len;
+ request->read_reply_len = 0; + free( request->redirect_location ); + request->redirect_location = NULL; + if (request->flags & REQUEST_FLAG_WEBSOCKET_UPGRADE && request->websocket_set_send_buffer_size < MIN_WEBSOCKET_SEND_BUFFER_SIZE) { @@ -2492,7 +2497,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, TRUE ))) return ret; + if ((ret = read_more_data( request, -1, FALSE ))) return ret; if (!request->read_size) { *len = 0; @@ -2629,6 +2634,12 @@ static DWORD get_redirect_url( struct request *request, WCHAR **ret_url, DWORD * DWORD size, ret; WCHAR *url;
+ if (*ret_url) + { + free( *ret_url ); + *ret_url = NULL; + } + ret = query_headers( request, WINHTTP_QUERY_LOCATION, NULL, NULL, &size, NULL ); if (ret != ERROR_INSUFFICIENT_BUFFER) return ret; if (!(url = malloc( size ))) return ERROR_OUTOFMEMORY; @@ -2644,13 +2655,15 @@ static DWORD get_redirect_url( struct request *request, WCHAR **ret_url, DWORD *
static DWORD handle_redirect( struct request *request, DWORD status ) { - DWORD ret, len, len_loc = 0; + DWORD ret, len, len_loc; URL_COMPONENTS uc; struct connect *connect = request->connect; INTERNET_PORT port; - WCHAR *hostname = NULL, *location = NULL; + WCHAR *hostname = NULL, *location;
- if ((ret = get_redirect_url( request, &location, &len_loc ))) return ret; + if ((ret = get_redirect_url( request, &request->redirect_location, &request->redirect_location_len ))) return ret; + location = request->redirect_location; + len_loc = request->redirect_location_len;
memset( &uc, 0, sizeof(uc) ); uc.dwStructSize = sizeof(uc); @@ -2660,10 +2673,9 @@ static DWORD handle_redirect( struct request *request, DWORD status ) { WCHAR *path, *p;
- ret = ERROR_OUTOFMEMORY; if (location[0] == '/') { - if (!(path = malloc( (len_loc + 1) * sizeof(WCHAR) ))) goto end; + if (!(path = malloc( (len_loc + 1) * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; memcpy( path, location, len_loc * sizeof(WCHAR) ); path[len_loc] = 0; } @@ -2671,7 +2683,7 @@ static DWORD handle_redirect( struct request *request, DWORD status ) { if ((p = wcsrchr( request->path, '/' ))) *p = 0; len = lstrlenW( request->path ) + 1 + len_loc; - if (!(path = malloc( (len + 1) * sizeof(WCHAR) ))) goto end; + if (!(path = malloc( (len + 1) * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; lstrcpyW( path, request->path ); lstrcatW( path, L"/" ); memcpy( path + lstrlenW(path), location, len_loc * sizeof(WCHAR) ); @@ -2679,19 +2691,14 @@ static DWORD handle_redirect( struct request *request, DWORD status ) } free( request->path ); request->path = path; - ret = ERROR_SUCCESS; - - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REDIRECT, location, len_loc + 1 ); } else { if (uc.nScheme == INTERNET_SCHEME_HTTP && request->hdr.flags & WINHTTP_FLAG_SECURE) { if (request->hdr.redirect_policy == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP) - { - ret = ERROR_WINHTTP_REDIRECT_FAILED; - goto end; - } + return ERROR_WINHTTP_REDIRECT_FAILED; + TRACE("redirect from secure page to non-secure page\n"); request->hdr.flags &= ~WINHTTP_FLAG_SECURE; } @@ -2700,15 +2707,8 @@ static DWORD handle_redirect( struct request *request, DWORD status ) TRACE("redirect from non-secure page to secure page\n"); request->hdr.flags |= WINHTTP_FLAG_SECURE; } - - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REDIRECT, location, len_loc + 1 ); - len = uc.dwHostNameLength; - if (!(hostname = malloc( (len + 1) * sizeof(WCHAR) ))) - { - ret = ERROR_OUTOFMEMORY; - goto end; - } + if (!(hostname = malloc( (len + 1) * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; memcpy( hostname, uc.lpszHostName, len * sizeof(WCHAR) ); hostname[len] = 0;
@@ -2718,11 +2718,7 @@ static DWORD handle_redirect( struct request *request, DWORD status ) free( connect->hostname ); connect->hostname = hostname; connect->hostport = port; - if (!set_server_for_hostname( connect, hostname, port )) - { - ret = ERROR_OUTOFMEMORY; - goto end; - } + if (!set_server_for_hostname( connect, hostname, port )) return ERROR_OUTOFMEMORY;
netconn_release( request->netconn ); request->netconn = NULL; @@ -2732,14 +2728,14 @@ static DWORD handle_redirect( struct request *request, DWORD status ) } else free( hostname );
- if ((ret = add_host_header( request, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE ))) goto end; + if ((ret = add_host_header( request, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE ))) return ret;
free( request->path ); request->path = NULL; if (uc.dwUrlPathLength) { len = uc.dwUrlPathLength + uc.dwExtraInfoLength; - if (!(request->path = malloc( (len + 1) * sizeof(WCHAR) ))) goto end; + if (!(request->path = malloc( (len + 1) * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY; memcpy( request->path, uc.lpszUrlPath, (len + 1) * sizeof(WCHAR) ); request->path[len] = 0; } @@ -2754,9 +2750,7 @@ static DWORD handle_redirect( struct request *request, DWORD status ) request->optional_len = 0; }
-end: - free( location ); - return ret; + return ERROR_SUCCESS; }
static BOOL is_passport_request( struct request *request ) @@ -2803,6 +2797,9 @@ static DWORD receive_response( struct request *request, BOOL async ) netconn_set_timeout( request->netconn, FALSE, request->receive_response_timeout ); for (;;) { + 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 = read_reply( request ))) break;
size = sizeof(DWORD); @@ -2826,6 +2823,9 @@ static DWORD receive_response( struct request *request, BOOL async )
if ((ret = handle_redirect( request, status ))) break;
+ 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; } diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index 8aa99f0ece7..b0b50ef06af 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -678,6 +678,7 @@ static void request_destroy( struct object_header *hdr ) } }
+ free( request->redirect_location ); free( request ); }
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 0326a8fc1e3..ed0f6e590ab 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -220,6 +220,9 @@ 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; + WCHAR *redirect_location; + DWORD redirect_location_len; };
enum socket_state