Функции AutoProxy WinHTTP

WinHTTP реализует протокол WPAD, используя функцию WinHttpGetProxyForUrl , а также две вспомогательные служебные функции: WinHttpDetectAutoProxyConfigUrl и WinHttpGetIEProxyConfigForCurrentUser.

Поддержка AutoProxy не полностью интегрирована в стек HTTP в WinHTTP. Перед отправкой запроса приложение должно вызвать WinHttpGetProxyForUrl , чтобы получить имя прокси-сервера, а затем вызвать WinHttpSetOption с помощью WINHTTP_OPTION_PROXY , чтобы задать конфигурацию прокси-сервера для дескриптора запроса WinHTTP, созданного WinHttpOpenRequest.

Функция WinHttpGetProxyForUrl может выполнять все три шага протокола WPAD, описанные в предыдущем обзоре: (1) обнаружение URL-адреса PAC, (2) скачивание файла скрипта PAC, (3) выполнение кода скрипта и возврат конфигурации прокси-сервера в WINHTTP_PROXY_INFO структуре. При необходимости, если приложению заранее известен URL-адрес PAC, его можно указать в WinHttpGetProxyForUrl.

В следующем примере кода используется autoproxy. Он настраивает HTTP-запрос GET путем создания подключения к сеансу WinHTTP и дескрипторов запросов. Вызов 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_AUTO_DETECT в структуре WINHTTP_AUTOPROXY_OPTIONS . Использование флага WINHTTP_AUTOPROXY_AUTO_DETECT требует, чтобы код указал один или оба флага автоматического обнаружения (WINHTTP_AUTO_DETECT_TYPE_DHCP, WINHTTP_AUTO_DETECT_TYPE_DNS_A). В примере кода используется функция автоматического обнаружения WinHttpGetProxyForUrl , так как URL-адрес PAC неизвестен заранее. Если URL-адрес PAC не может быть найден в сети в этом сценарии, WinHttpGetProxyForUrl завершается ошибкой (GetLastError возвращает ERROR_WINHTTP_AUTODETECTION_FAILED).

Если URL-адрес PAC известен заранее

Если приложение знает URL-адрес PAC, оно может указать его в структуре 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 (а также флаги автозаписи и URL-адрес автоматической настройки), WinHttpGetProxyForUrl сначала пытается выполнить автоматическое обнаружение, а затем, если автоматическому обнаружению не удается найти URL-адрес PAC, он возвращается к URL-адресу автоматической настройки, предоставленному приложением.

Функция WinHttpDetectAutoProxyConfigUrl

Функция WinHttpDetectAutoProxyConfigUrl реализует подмножество протокола WPAD: она пытается автоматически обнаружить URL-адрес файла автоматической настройки прокси-сервера, не скачивая и не выполняя PAC-файл. Эта функция полезна в особых ситуациях, когда веб-клиентское приложение должно обрабатывать скачивание и выполнение самого PAC-файла.

Функция WinHttpGetIEProxyConfigForCurrentUser

Функция WinHttpGetIEProxyConfigForCurrentUser возвращает параметры прокси-сервера Обозреватель текущего пользователя для текущего активного сетевого подключения без вызова WinInet.dll. Эта функция полезна только при вызове в процессе, который выполняется с интерактивным удостоверением учетной записи пользователя, так как в противном случае конфигурация прокси-сервера Обозреватель Интернета не будет доступна. Например, было бы нежелательно вызывать эту функцию из библиотеки DLL ISAPI, работающей в процессе службы IIS. Дополнительные сведения и сценарий, в котором приложение на основе WinHTTP будет использовать WinHttpGetIEProxyConfigForCurrentUser, см. в разделе Обнаружение без файла автоматической настройки.