WinHTTP AutoProxy 関数

WinHTTP は、WinHttpGetProxyForUrl 関数と、WinHttpDetectAutoProxyConfigUrlWinHttpGetIEProxyConfigForCurrentUser という 2 つのサポート ユーティリティ関数を使用して WPAD プロトコルを実装します。

AutoProxy のサポートは、WinHTTP の HTTP スタックに完全に統合されていません。 要求を送信する前に、アプリケーションで WinHttpGetProxyForUrl を呼び出してプロキシ サーバーの名前を取得し、WINHTTP_OPTION_PROXYを使用して WinHttpSetOption を呼び出して、WinHttpOpenRequest によって作成された WinHTTP 要求ハンドルにプロキシ構成を設定する必要があります。

WinHttpGetProxyForUrl 関数は、前の概要で説明した WPAD プロトコルの 3 つの手順すべてを実行できます。(1) PAC URL の検出、(2) PAC スクリプト ファイルのダウンロード、(3) スクリプト コードの実行、WINHTTP_PROXY_INFO構造でのプロキシ構成の返し。 必要に応じて、アプリケーションが PAC URL を事前に認識している場合は、 これを WinHttpGetProxyForUrl に指定できます。

次のコード例では、autoproxy を使用します。 最初に WinHTTP セッション接続ハンドルと要求ハンドルを作成して、HTTP GET 要求を設定します。 WinHttpOpen 呼び出しは、要求既定でターゲット サーバーに直接送信されることを示すために、初期プロキシ構成のWINHTTP_ACCESS_TYPE_NO_PROXYを指定します。 autoproxy を使用して、要求ハンドルにプロキシ構成を直接設定します。

  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 フラグを指定して、プロキシの自動構成ファイルを自動的に検出するように関数に指示します。 WINHTTP_AUTOPROXY_AUTO_DETECT フラグを使用するには、コードで自動検出フラグ (WINHTTP_AUTO_DETECT_TYPE_DHCPWINHTTP_AUTO_DETECT_TYPE_DNS_A) の一方または両方を指定する必要があります。 このコード例では、PAC URL が事前に認識されていないため、 WinHttpGetProxyForUrl の自動検出機能を使用しています。 このシナリオで PAC URL をネットワーク上に配置できない場合、WinHttpGetProxyForUrl は失敗します (GetLastError はERROR_WINHTTP_AUTODETECTION_FAILEDを返します)。

PAC URL が事前に認識されている場合

アプリケーションが PAC URL を認識している場合は、それをWINHTTP_AUTOPROXY_OPTIONS構造で指定し、自動検出フェーズをスキップするように WinHttpGetProxyForUrl を構成できます。

たとえば、PAC ファイルが URL "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 フラグの両方が指定されている場合 (および自動 detction フラグと自動構成 URL を指定)、WinHttpGetProxyForUrl は最初に自動検出を試み、自動検出で PAC URL の検索に失敗した場合は、アプリケーションによって提供される自動構成 URL に "フォールバック" します。

WinHttpDetectAutoProxyConfigUrl 関数

WinHttpDetectAutoProxyConfigUrl 関数は、WPAD プロトコルのサブセットを実装します。これは、PAC ファイルをダウンロードまたは実行せずに、プロキシ自動構成ファイルの URL を自動検出しようとします。 この関数は、Web クライアント アプリケーションが PAC ファイル自体のダウンロードと実行を処理する必要がある特殊な状況で役立ちます。

WinHttpGetIEProxyConfigForCurrentUser 関数

WinHttpGetIEProxyConfigForCurrentUser 関数は、"WinInet.dll" を呼び出さずに、現在のアクティブなネットワーク接続の現在のユーザー インターネット エクスプローラー プロキシ設定を返します。 この関数は、対話型ユーザー アカウント ID で実行されているプロセス内で呼び出された場合にのみ役立ちます。インターネット エクスプローラー プロキシ構成を使用できない可能性があるためです。 たとえば、IIS サービス プロセスで実行されている ISAPI DLL からこの関数を呼び出しても役に立ちません。 WinHTTP ベースのアプリケーションで WinHttpGetIEProxyConfigForCurrentUser を使用するシナリオの詳細については、「 自動構成ファイルを使用しない検出」を参照してください。