From: Hans Leidekker Subject: wininet: Set Content-Length header to zero if the verb is CONNECT. Message-Id: <1443791196-17204-1-git-send-email-hans@codeweavers.com> Date: Fri, 2 Oct 2015 15:06:36 +0200 Signed-off-by: Hans Leidekker --- dlls/wininet/http.c | 25 ++++++++++++++++++++----- dlls/wininet/tests/http.c | 26 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index edea9f8..143dc75 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -4877,6 +4877,16 @@ static char *build_ascii_request( const WCHAR *str, void *data, DWORD data_len, return ret; } +static void set_content_length_header( http_request_t *request, DWORD len, DWORD flags ) +{ + static const WCHAR fmtW[] = + {'C','o','n','t','e','n','t','-','L','e','n','g','t','h',':',' ','%','u','\r','\n',0}; + WCHAR buf[sizeof(fmtW)/sizeof(fmtW[0]) + 10]; + + sprintfW( buf, fmtW, len ); + HTTP_HttpAddRequestHeadersW( request, buf, ~0u, flags ); +} + /*********************************************************************** * HTTP_HttpSendRequestW (internal) * @@ -4891,12 +4901,9 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwContentLength, BOOL bEndRequest) { - static const WCHAR szContentLength[] = - { 'C','o','n','t','e','n','t','-','L','e','n','g','t','h',':',' ','%','l','i','\r','\n',0 }; BOOL redirected = FALSE, secure_proxy_connect = FALSE, loop_next; LPWSTR requestString = NULL; INT responseLen, cnt; - WCHAR contentLengthStr[sizeof szContentLength/2 /* includes \r\n */ + 20 /* int */ ]; DWORD res; TRACE("--> %p\n", request); @@ -4912,8 +4919,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, if (dwContentLength || strcmpW(request->verb, szGET)) { - sprintfW(contentLengthStr, szContentLength, dwContentLength); - HTTP_HttpAddRequestHeadersW(request, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_ADD_IF_NEW); + set_content_length_header(request, dwContentLength, HTTP_ADDREQ_FLAG_ADD_IF_NEW); request->bytesToWrite = dwContentLength; } if (request->session->appInfo->agent) @@ -5002,6 +5008,10 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, { static const WCHAR connectW[] = {'C','O','N','N','E','C','T',0}; const WCHAR *target = request->server->host_port; + + if (HTTP_GetCustomHeaderIndex(request, szContent_Length, 0, TRUE) >= 0) + set_content_length_header(request, 0, HTTP_ADDREQ_FLAG_REPLACE); + requestString = build_request_header(request, connectW, target, g_szHttp1_1, TRUE); } else if (request->proxy && !(request->hdr.dwFlags & INTERNET_FLAG_SECURE)) @@ -5011,7 +5021,12 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, heap_free(url); } else + { + if (request->proxy && HTTP_GetCustomHeaderIndex(request, szContent_Length, 0, TRUE) >= 0) + set_content_length_header(request, dwContentLength, HTTP_ADDREQ_FLAG_REPLACE); + requestString = build_request_header(request, request->verb, request->path, request->version, TRUE); + } TRACE("Request header -> %s\n", debugstr_w(requestString) ); diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 973413a..410865d 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -2106,6 +2106,13 @@ static DWORD CALLBACK server_thread(LPVOID param) else send(c, notokmsg, sizeof notokmsg-1, 0); } + if (strstr(buffer, "CONNECT ")) + { + if (!strstr(buffer, "Content-Length: 0")) + send(c, notokmsg, sizeof notokmsg-1, 0); + else + send(c, proxymsg, sizeof proxymsg-1, 0); + } if (strstr(buffer, "/test2")) { if (strstr(buffer, "Proxy-Authorization: Basic bWlrZToxMTAx")) @@ -2806,6 +2813,25 @@ static void test_proxy_direct(int port) ok(r, "HttpQueryInfo failed\n"); ok(!strcmp(buffer, "200"), "proxy code wrong\n"); + InternetCloseHandle(hr); + InternetCloseHandle(hc); + InternetCloseHandle(hi); + + sprintf(buffer, "localhost:%d\n", port); + hi = InternetOpenA("winetest", INTERNET_OPEN_TYPE_PROXY, buffer, NULL, 0); + ok(hi != NULL, "InternetOpen failed\n"); + + hc = InternetConnectA(hi, "test.winehq.org", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + ok(hc != NULL, "InternetConnect failed\n"); + + hr = HttpOpenRequestA(hc, "POST", "/test2", NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0); + ok(hr != NULL, "HttpOpenRequest failed\n"); + + r = HttpSendRequestA(hr, NULL, 0, (char *)"data", sizeof("data")); + ok(r, "HttpSendRequest failed %u\n", GetLastError()); + + test_status_code(hr, 407); + done: InternetCloseHandle(hr); InternetCloseHandle(hc); -- 2.1.4