-- v5: winhttp: Add support for WINHTTP_AUTOPROXY_HOST_LOWERCASE flag in WinHttpGetProxyForUrl.
From: Piotr Caban piotr@codeweavers.com
--- dlls/winhttp/tests/winhttp.c | 71 ++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-)
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index 09abc4c5854..9d845b509ea 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -2281,6 +2281,12 @@ static const char redirectmsg[] = "Location: /temporary\r\n" "Connection: close\r\n\r\n";
+static const char proxy_pac[] = +"function FindProxyForURL(url, host) {\r\n" +" url = url.replace(/[:/]/g, '_');\r\n" +" return 'PROXY ' + url + '_' + host + ':8080';\r\n" +"}\r\n\r\n"; + static const char unauthorized[] = "Unauthorized"; static const char hello_world[] = "Hello World"; static const char auth_unseen[] = "Auth Unseen"; @@ -2541,6 +2547,11 @@ static DWORD CALLBACK server_thread(LPVOID param) ok(!!strstr(buffer, "Cookie: 111\r\n"), "Header missing from request %s.\n", debugstr_a(buffer)); send(c, okmsg, sizeof(okmsg) - 1, 0); } + if (strstr(buffer, "GET /proxy.pac")) + { + send(c, okmsg, sizeof(okmsg) - 1, 0); + send(c, proxy_pac, sizeof(proxy_pac) - 1, 0); + }
if (strstr(buffer, "PUT /test") || strstr(buffer, "POST /test")) { @@ -5268,9 +5279,10 @@ static void test_WinHttpGetIEProxyConfigForCurrentUser(void) GlobalFree( cfg.lpszProxyBypass ); }
-static void test_WinHttpGetProxyForUrl(void) +static void test_WinHttpGetProxyForUrl(int port) { - BOOL ret; + WCHAR pac_url[64]; + BOOL ret, old_winhttp = FALSE; DWORD error; HINTERNET session; WINHTTP_AUTOPROXY_OPTIONS options; @@ -5379,6 +5391,59 @@ static void test_WinHttpGetProxyForUrl(void) ret = WinHttpGetProxyForUrl( session, L"http:", &options, &info ); ok( !ret, "expected failure\n" );
+ swprintf(pac_url, ARRAY_SIZE(pac_url), L"http://localhost:%d/proxy.pac?ver=1", port); + options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL | WINHTTP_AUTOPROXY_NO_CACHE_SVC; + options.dwAutoDetectFlags = 0; + options.lpszAutoConfigUrl = pac_url; + + ret = WinHttpGetProxyForUrl( session, L"HTTP://WINEHQ.ORG/Test.html", &options, &info); + if (!ret) + { + old_winhttp = TRUE; + options.dwFlags &= ~WINHTTP_AUTOPROXY_NO_CACHE_SVC; + ret = WinHttpGetProxyForUrl( session, L"HTTP://WINEHQ.ORG/Test.html", &options, &info); + } + ok(ret, "expected success\n" ); + ok(info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY, + "info.dwAccessType = %lu\n", info.dwAccessType); + todo_wine + ok(!wcscmp(info.lpszProxy, L"http___WINEHQ.ORG_Test.html_WINEHQ.ORG:8080") || + broken(old_winhttp && !wcscmp(info.lpszProxy, L"HTTP___WINEHQ.ORG_Test.html_WINEHQ.ORG:8080")), + "info.Proxy = %s\n", wine_dbgstr_w(info.lpszProxy)); + ok(!info.lpszProxyBypass, "info.ProxyBypass = %s\n", + wine_dbgstr_w(info.lpszProxyBypass)); + GlobalFree( info.lpszProxy ); + + options.dwFlags |= WINHTTP_AUTOPROXY_HOST_LOWERCASE; + + ret = WinHttpGetProxyForUrl( session, L"HTTP://WINEHQ.ORG/Test.html", &options, &info); + ok(ret, "expected success\n" ); + ok(info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY, + "info.dwAccessType = %lu\n", info.dwAccessType); + todo_wine + ok(!wcscmp(info.lpszProxy, L"http___winehq.org_Test.html_winehq.org:8080") || + broken(old_winhttp && !wcscmp(info.lpszProxy, L"HTTP___winehq.org_Test.html_winehq.org:8080")), + "info.Proxy = %s\n", wine_dbgstr_w(info.lpszProxy)); + ok(!info.lpszProxyBypass, "info.ProxyBypass = %s\n", + wine_dbgstr_w(info.lpszProxyBypass)); + GlobalFree( info.lpszProxy ); + + if (!old_winhttp) + { + options.dwFlags |= WINHTTP_AUTOPROXY_HOST_KEEPCASE; + + ret = WinHttpGetProxyForUrl( session, L"HTTP://WINEHQ.ORG/Test.html", &options, &info); + ok(ret, "expected success\n" ); + ok(info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY, + "info.dwAccessType = %lu\n", info.dwAccessType); + todo_wine + ok(!wcscmp(info.lpszProxy, L"http___WINEHQ.ORG_Test.html_WINEHQ.ORG:8080"), + "info.Proxy = %s\n", wine_dbgstr_w(info.lpszProxy)); + ok(!info.lpszProxyBypass, "info.ProxyBypass = %s\n", + wine_dbgstr_w(info.lpszProxyBypass)); + GlobalFree( info.lpszProxy ); + } + WinHttpCloseHandle( session ); }
@@ -5854,7 +5919,6 @@ START_TEST (winhttp) test_IWinHttpRequest_Invoke(); test_WinHttpDetectAutoProxyConfigUrl(); test_WinHttpGetIEProxyConfigForCurrentUser(); - test_WinHttpGetProxyForUrl(); test_chunked_read(); test_max_http_automatic_redirects(); si.event = CreateEventW(NULL, 0, 0, NULL); @@ -5889,6 +5953,7 @@ START_TEST (winhttp) test_passport_auth(si.port); test_websocket(si.port); test_redirect(si.port); + test_WinHttpGetProxyForUrl(si.port);
/* send the basic request again to shutdown the server thread */ test_basic_request(si.port, NULL, L"/quit");
From: Piotr Caban piotr@codeweavers.com
--- dlls/winhttp/session.c | 69 +++++++++++++++++++++++----------- dlls/winhttp/tests/winhttp.c | 3 -- dlls/winhttp/winhttp_private.h | 15 -------- 3 files changed, 48 insertions(+), 39 deletions(-)
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index 978bf28bc37..b009639297d 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -2031,42 +2031,69 @@ BOOL WINAPI InternetDeInitializeAutoProxyDll(LPSTR, DWORD); BOOL WINAPI InternetGetProxyInfo(LPCSTR, DWORD, LPSTR, DWORD, LPSTR *, LPDWORD); BOOL WINAPI InternetInitializeAutoProxyDll(DWORD, LPSTR, LPSTR, void *, struct AUTO_PROXY_SCRIPT_BUFFER *);
-static BOOL run_script( char *script, DWORD size, const WCHAR *url, WINHTTP_PROXY_INFO *info ) +#define MAX_SCHEME_LENGTH 32 +static BOOL run_script( char *script, DWORD size, const WCHAR *url, WINHTTP_PROXY_INFO *info, DWORD flags ) { + WCHAR scheme[MAX_SCHEME_LENGTH + 1], buf[MAX_HOST_NAME_LENGTH + 1], *hostname; BOOL ret; - char *result, *urlA; - DWORD len_result; + char *result, *urlA, *hostnameA; + DWORD len, len_scheme, len_hostname; struct AUTO_PROXY_SCRIPT_BUFFER buffer; URL_COMPONENTSW uc;
+ memset( &uc, 0, sizeof(uc) ); + uc.dwStructSize = sizeof(uc); + uc.dwSchemeLength = -1; + uc.dwHostNameLength = -1; + + if (!WinHttpCrackUrl( url, 0, 0, &uc )) + return FALSE; + + memcpy( scheme, uc.lpszScheme, uc.dwSchemeLength * sizeof(WCHAR) ); + scheme[uc.dwSchemeLength] = 0; + wcslwr( scheme ); + len_scheme = WideCharToMultiByte( CP_ACP, 0, scheme, uc.dwSchemeLength, NULL, 0, NULL, NULL ); + + if (flags & WINHTTP_AUTOPROXY_HOST_LOWERCASE && !(flags & WINHTTP_AUTOPROXY_HOST_KEEPCASE)) + { + memcpy( buf, uc.lpszHostName, uc.dwHostNameLength * sizeof(WCHAR) ); + buf[uc.dwHostNameLength] = 0; + wcslwr( buf ); + hostname = buf; + } + else + { + hostname = uc.lpszHostName; + } + len_hostname = WideCharToMultiByte( CP_ACP, 0, hostname, uc.dwHostNameLength, NULL, 0, NULL, NULL ); + + len = WideCharToMultiByte( CP_ACP, 0, uc.lpszHostName + uc.dwHostNameLength, -1, NULL, 0, NULL, NULL ); + if (!(urlA = malloc( len + len_scheme + len_hostname + 3 ))) return FALSE; + WideCharToMultiByte( CP_ACP, 0, scheme, uc.dwSchemeLength, urlA, len_scheme, NULL, NULL ); + urlA[len_scheme++] = ':'; + urlA[len_scheme++] = '/'; + urlA[len_scheme++] = '/'; + WideCharToMultiByte( CP_ACP, 0, hostname, uc.dwHostNameLength, urlA + len_scheme, len_hostname, NULL, NULL ); + hostnameA = urlA + len_scheme; + WideCharToMultiByte( CP_ACP, 0, uc.lpszHostName + uc.dwHostNameLength, -1, + urlA + len_scheme + len_hostname, len, NULL, NULL ); + buffer.dwStructSize = sizeof(buffer); buffer.lpszScriptBuffer = script; buffer.dwScriptBufferSize = size;
- if (!(urlA = strdupWA( url ))) return FALSE; - if (!(ret = InternetInitializeAutoProxyDll( 0, NULL, NULL, NULL, &buffer ))) + if (!InternetInitializeAutoProxyDll( 0, NULL, NULL, NULL, &buffer )) { free( urlA ); return FALSE; }
- memset( &uc, 0, sizeof(uc) ); - uc.dwStructSize = sizeof(uc); - uc.dwHostNameLength = -1; - - if ((ret = WinHttpCrackUrl( url, 0, 0, &uc ))) + if ((ret = InternetGetProxyInfo( urlA, strlen(urlA), hostnameA, len_hostname, &result, &len ))) { - char *hostnameA = strdupWA_sized( uc.lpszHostName, uc.dwHostNameLength ); - - if ((ret = InternetGetProxyInfo( urlA, strlen(urlA), - hostnameA, strlen(hostnameA), &result, &len_result ))) - { - ret = parse_script_result( result, info ); - free( result ); - } - - free( hostnameA ); + ret = parse_script_result( result, info ); + free( result ); } + free( urlA ); InternetDeInitializeAutoProxyDll( NULL, 0 ); return ret; @@ -2118,7 +2145,7 @@ BOOL WINAPI WinHttpGetProxyForUrl( HINTERNET hsession, LPCWSTR url, WINHTTP_AUTO
if ((script = download_script( pac_url, &size ))) { - ret = run_script( script, size, url, info ); + ret = run_script( script, size, url, info, options->dwFlags ); free( script ); }
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index 9d845b509ea..1724612202a 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -5406,7 +5406,6 @@ static void test_WinHttpGetProxyForUrl(int port) ok(ret, "expected success\n" ); ok(info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY, "info.dwAccessType = %lu\n", info.dwAccessType); - todo_wine ok(!wcscmp(info.lpszProxy, L"http___WINEHQ.ORG_Test.html_WINEHQ.ORG:8080") || broken(old_winhttp && !wcscmp(info.lpszProxy, L"HTTP___WINEHQ.ORG_Test.html_WINEHQ.ORG:8080")), "info.Proxy = %s\n", wine_dbgstr_w(info.lpszProxy)); @@ -5420,7 +5419,6 @@ static void test_WinHttpGetProxyForUrl(int port) ok(ret, "expected success\n" ); ok(info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY, "info.dwAccessType = %lu\n", info.dwAccessType); - todo_wine ok(!wcscmp(info.lpszProxy, L"http___winehq.org_Test.html_winehq.org:8080") || broken(old_winhttp && !wcscmp(info.lpszProxy, L"HTTP___winehq.org_Test.html_winehq.org:8080")), "info.Proxy = %s\n", wine_dbgstr_w(info.lpszProxy)); @@ -5436,7 +5434,6 @@ static void test_WinHttpGetProxyForUrl(int port) ok(ret, "expected success\n" ); ok(info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY, "info.dwAccessType = %lu\n", info.dwAccessType); - todo_wine ok(!wcscmp(info.lpszProxy, L"http___WINEHQ.ORG_Test.html_WINEHQ.ORG:8080"), "info.Proxy = %s\n", wine_dbgstr_w(info.lpszProxy)); ok(!info.lpszProxyBypass, "info.ProxyBypass = %s\n", diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 80ce2614ca1..a71447dbe1c 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -455,21 +455,6 @@ static inline char *strdupWA( const WCHAR *src ) return dst; }
-static inline char *strdupWA_sized( const WCHAR *src, DWORD size ) -{ - char *dst = NULL; - if (src) - { - int len = WideCharToMultiByte( CP_ACP, 0, src, size, NULL, 0, NULL, NULL ) + 1; - if ((dst = malloc( len ))) - { - WideCharToMultiByte( CP_ACP, 0, src, size, dst, len, NULL, NULL ); - dst[len - 1] = 0; - } - } - return dst; -} - extern HINSTANCE winhttp_instance;
#define MIN_WEBSOCKET_SEND_BUFFER_SIZE 16
On Fri Feb 2 15:52:29 2024 +0000, Hans Leidekker wrote:
urlA should be freed here. While you're at it, could you wrap lines at 120 columns?
Done. I've also removed no longer used strdupWA_sized helper.
This merge request was approved by Hans Leidekker.