WinHTTP AutoProxy 函式
WinHTTP 使用 WinHttpGetProxyForUrl 函式以及兩個支援的公用程式函式來實作 WPAD 通訊協定,WinHttpDetectAutoProxyConfigUrl 和 WinHttpGetIEProxyConfigForCurrentUser。
AutoProxy 支持並未完全整合到 WinHTTP 中的 HTTP 堆疊。 傳送要求之前,應用程式必須呼叫 WinHttpGetProxyForUrl,以取得 Proxy 伺服器的名稱,然後使用 WINHTTP_OPTION_PROXY 呼叫 WinHttpSetOption,以在 winHttpOpenRequest 所建立的 WinHTTP 要求句柄上設定 Proxy 組態。
WinHttpGetProxyForUrl 函式可以執行上一個概觀中所述的 WPAD 通訊協定的所有三個步驟:(1) 探索 PAC URL,(2) 下載 PAC 腳本檔案,(3) 執行腳本程序代碼,並在 WINHTTP_PROXY_INFO 結構中傳回 Proxy 組態。 或者,如果應用程式事先知道 PAC URL,它可以指定此 URL 以 WinHttpGetProxyForUrl。
下列範例程式代碼使用 autoproxy。 它會先建立 WinHTTP 會話連線和要求句柄,以設定 HTTP GET 要求。 WinHttpOpen 呼叫會指定初始 Proxy 組態的 WINHTTP_ACCESS_TYPE_NO_PROXY,表示要求預設會直接傳送至目標伺服器。 然後使用 autoproxy,直接在要求句柄上設定 Proxy 組態。
HINTERNET hHttpSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
WINHTTP_AUTOPROXY_OPTIONS AutoProxyOptions;
WINHTTP_PROXY_INFO ProxyInfo;
DWORD cbProxyInfoSize = sizeof(ProxyInfo);
ZeroMemory( &AutoProxyOptions, sizeof(AutoProxyOptions) );
ZeroMemory( &ProxyInfo, sizeof(ProxyInfo) );
//
// Create the WinHTTP session.
//
hHttpSession = WinHttpOpen( L"WinHTTP AutoProxy Sample/1.0",
WINHTTP_ACCESS_TYPE_NO_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0 );
// Exit if WinHttpOpen failed.
if( !hHttpSession )
goto Exit;
//
// Create the WinHTTP connect handle.
//
hConnect = WinHttpConnect( hHttpSession,
L"www.microsoft.com",
INTERNET_DEFAULT_HTTP_PORT,
0 );
// Exit if WinHttpConnect failed.
if( !hConnect )
goto Exit;
//
// Create the HTTP request handle.
//
hRequest = WinHttpOpenRequest( hConnect,
L"GET",
L"ms.htm",
L"HTTP/1.1",
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0 );
// Exit if WinHttpOpenRequest failed.
if( !hRequest )
goto Exit;
//
// Set up the autoproxy call.
//
// Use auto-detection because the Proxy
// Auto-Config URL is not known.
AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
// Use DHCP and DNS-based auto-detection.
AutoProxyOptions.dwAutoDetectFlags =
WINHTTP_AUTO_DETECT_TYPE_DHCP |
WINHTTP_AUTO_DETECT_TYPE_DNS_A;
// If obtaining the PAC script requires NTLM/Negotiate
// authentication, then automatically supply the client
// domain credentials.
AutoProxyOptions.fAutoLogonIfChallenged = TRUE;
//
// Call WinHttpGetProxyForUrl with our target URL. If
// auto-proxy succeeds, then set the proxy info on the
// request handle. If auto-proxy fails, ignore the error
// and attempt to send the HTTP request directly to the
// target server (using the default WINHTTP_ACCESS_TYPE_NO_PROXY
// configuration, which the requesthandle will inherit
// from the session).
//
if( WinHttpGetProxyForUrl( hHttpSession,
L"https://www.microsoft.com/ms.htm",
&AutoProxyOptions,
&ProxyInfo))
{
// A proxy configuration was found, set it on the
// request handle.
if( !WinHttpSetOption( hRequest,
WINHTTP_OPTION_PROXY,
&ProxyInfo,
cbProxyInfoSize ) )
{
// Exit if setting the proxy info failed.
goto Exit;
}
}
//
// Send the request.
//
if( !WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0,
WINHTTP_NO_REQUEST_DATA,
0,
0,
NULL ) )
{
// Exit if WinHttpSendRequest failed.
goto Exit;
}
//
// Wait for the response.
//
if( !WinHttpReceiveResponse( hRequest, NULL ) )
goto Exit;
//
// A response has been received, then process it.
// (omitted)
//
Exit:
//
// Clean up the WINHTTP_PROXY_INFO structure.
//
if( ProxyInfo.lpszProxy != NULL )
GlobalFree(ProxyInfo.lpszProxy);
if( ProxyInfo.lpszProxyBypass != NULL )
GlobalFree( ProxyInfo.lpszProxyBypass );
//
// Close the WinHTTP handles.
//
if( hRequest != NULL )
WinHttpCloseHandle( hRequest );
if( hConnect != NULL )
WinHttpCloseHandle( hConnect );
if( hHttpSession != NULL )
WinHttpCloseHandle( hHttpSession );
在提供的範例程式代碼中,呼叫 WinHttpGetProxyForUrl 會指示函式在 WINHTTP_AUTOPROXY_OPTIONS 結構中指定 WINHTTP_AUTOPROXY_AUTO_DETECT 旗標,自動探索 Proxy 自動配置檔。 使用 WINHTTP_AUTOPROXY_AUTO_DETECT 旗標需要程式碼指定一或兩個自動偵測旗標(WINHTTP_AUTO_DETECT_TYPE_DHCP、WINHTTP_AUTO_DETECT_TYPE_DNS_A)。 範例程式代碼會使用 WinHttpGetProxyForUrl 的自動偵測功能,因為事先不知道 PAC URL。 如果此案例中的 PAC URL 無法位於網路上,WinHttpGetProxyForUrl 失敗(GetLastError 傳回 ERROR_WINHTTP_AUTODETECTION_FAILED)。
如果 PAC URL 事先已知
如果應用程式知道 PAC URL,它可以在 WINHTTP_AUTOPROXY_OPTIONS 結構中指定它,並將 WinHttpGetProxyForUrl 設定為略過自動偵測階段。
例如,如果在 URL 的局域網路上提供 PAC 檔案,則https://InternalSite/proxy-config.pac"呼叫 WinHttpGetProxyForUrl 如下所示。
//
// Set up the autoproxy call.
//
// The proxy auto-config URL is known. Auto-detection
// is not required.
AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
// Set the proxy auto-config URL.
AutoProxyOptions. lpszAutoConfigUrl = L"https://InternalSite/proxy-config.pac";
// If obtaining the PAC script requires NTLM/Negotiate
// authentication, then automatically supply the client
// domain credentials.
AutoProxyOptions.fAutoLogonIfChallenged = TRUE;
//
// Call WinHttpGetProxyForUrl with our target URL. If auto-proxy
// succeeds, then set the proxy info on the request handle.
// If auto-proxy fails, ignore the error and attempt to send the
// HTTP request directly to the target server (using the default
// WINHTTP_ACCESS_TYPE_NO_PROXY configuration, which the request
// handle will inherit from the session).
//
if( WinHttpGetProxyForUrl( hHttpSession,
L"https://www.microsoft.com/ms.htm",
&AutoProxyOptions,
&ProxyInfo ) )
{
//...
如果 WINHTTP_AUTOPROXY_OPTIONS 結構同時指定 WINHTTP_AUTOPROXY_AUTO_DETECT 和 WINHTTP_AUTOPROXY_CONFIG_URL 旗標(並指定自動取用旗標和自動設定 URL),WinHttpGetProxyForUrl 先嘗試自動偵測,然後,如果自動偵測找不到 PAC URL,則「回復」到應用程式提供的自動設定 URL。
WinHttpDetectAutoProxyConfigUrl 函式
WinHttpDetectAutoProxyConfigUrl 函式會實作 WPAD 通訊協定的子集:它會嘗試自動偵測 Proxy 自動配置檔的 URL,而不需下載或執行 PAC 檔案。 此函式適用於 Web 用戶端應用程式必須處理 PAC 檔案本身下載和執行的特殊情況。
WinHttpGetIEProxyConfigForCurrentUser 函式
WinHttpGetIEProxyConfigForCurrentUser 函式會傳回目前使用中網路連線的目前使用者 Internet Explorer Proxy 設定,而不呼叫 “WinInet.dll”。 只有在以互動式用戶帳戶身分識別執行的進程內呼叫此函式才有用,因為沒有 Internet Explorer Proxy 組態可能會有其他用途。 例如,從 IIS 服務進程中執行的 ISAPI DLL 呼叫此函式並無用處。 如需詳細資訊和 WinHTTP 型應用程式將使用 WinHttpGetIEProxyConfigForCurrentUser的案例,請參閱 探索沒有自動配置檔。