Funções Do WinHTTP AutoProxy

O WinHTTP implementa o protocolo WPAD usando a função WinHttpGetProxyForUrl juntamente com duas funções de utilitário de suporte, WinHttpDetectAutoProxyConfigUrl e WinHttpGetIEProxyConfigForCurrentUser.

O suporte a AutoProxy não está totalmente integrado à pilha HTTP no WinHTTP. Antes de enviar uma solicitação, o aplicativo deve chamar WinHttpGetProxyForUrl para obter o nome de um servidor proxy e, em seguida, chamar WinHttpSetOption usando WINHTTP_OPTION_PROXY para definir a configuração de proxy no identificador de solicitação WinHTTP criado por WinHttpOpenRequest.

A função WinHttpGetProxyForUrl pode executar todas as três etapas do protocolo WPAD descritas na visão geral anterior: (1) descobrir a URL pac, (2) baixar o arquivo de script PAC, (3) executar o código de script e retornar a configuração de proxy em uma estrutura WINHTTP_PROXY_INFO . Opcionalmente, se o aplicativo souber com antecedência a URL pac, ele poderá especificar isso para WinHttpGetProxyForUrl.

O código de exemplo a seguir usa autoproxia. Ele configura uma solicitação HTTP GET criando primeiro os identificadores de solicitação e conexão de sessão WinHTTP. A chamada WinHttpOpen especifica WINHTTP_ACCESS_TYPE_NO_PROXY para a configuração de proxy inicial, para indicar que as solicitações são enviadas diretamente ao servidor de destino por padrão. Usando a reprodução automática, ele define a configuração de proxy diretamente no identificador de solicitação.

  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 );

No código de exemplo fornecido, a chamada para WinHttpGetProxyForUrl instrui a função a descobrir automaticamente o arquivo de configuração automática do proxy especificando o sinalizador WINHTTP_AUTOPROXY_AUTO_DETECT na estrutura WINHTTP_AUTOPROXY_OPTIONS . O uso do sinalizador WINHTTP_AUTOPROXY_AUTO_DETECT requer que o código especifique um ou ambos os sinalizadores de detecção automática (WINHTTP_AUTO_DETECT_TYPE_DHCPWINHTTP_AUTO_DETECT_TYPE_DNS_A). O código de exemplo usa o recurso de detecção automática do WinHttpGetProxyForUrl porque a URL pac não é conhecida com antecedência. Se uma URL PAC não puder ser localizada na rede nesse cenário, WinHttpGetProxyForUrl falhará (GetLastError retornará ERROR_WINHTTP_AUTODETECTION_FAILED).

Se a URL pac for conhecida com antecedência

Se o aplicativo souber a URL pac, ele poderá especificá-la na estrutura WINHTTP_AUTOPROXY_OPTIONS e configurar WinHttpGetProxyForUrl para ignorar a fase de detecção automática.

Por exemplo, se um arquivo PAC estiver disponível na rede local na URL , "https://InternalSite/proxy-config.pac", a chamada para WinHttpGetProxyForUrl será a seguinte.

//
// 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 ) )
{
  //...

Se a estrutura de WINHTTP_AUTOPROXY_OPTIONS especificar sinalizadores WINHTTP_AUTOPROXY_AUTO_DETECT e WINHTTP_AUTOPROXY_CONFIG_URL (e especificar sinalizadores de detecção automática e uma URL de configuração automática), WinHttpGetProxyForUrl primeiro tentará a detecção automática e, se a detecção automática não localizar uma URL PAC, "retornará" à URL de configuração automática fornecida pelo aplicativo.

A função WinHttpDetectAutoProxyConfigUrl

A função WinHttpDetectAutoProxyConfigUrl implementa um subconjunto do protocolo WPAD: ela tenta detectar automaticamente a URL do arquivo de configuração automática do proxy, sem baixar ou executar o arquivo PAC. Essa função é útil em situações especiais em que um aplicativo cliente Web deve lidar com o download e a execução do próprio arquivo PAC.

A função WinHttpGetIEProxyConfigForCurrentUser

A função WinHttpGetIEProxyConfigForCurrentUser retorna as configurações de proxy de Explorer de Internet do usuário atual para a conexão de rede ativa atual, sem chamar para "WinInet.dll". Essa função só é útil quando chamada dentro de um processo que está em execução em uma identidade de conta de usuário interativa, pois nenhuma configuração de proxy de Explorer da Internet provavelmente estará disponível de outra forma. Por exemplo, não seria útil chamar essa função de uma DLL ISAPI em execução no processo de serviço do IIS. Para obter mais informações e um cenário em que um aplicativo baseado em WinHTTP usaria WinHttpGetIEProxyConfigForCurrentUser, confira Descoberta sem um arquivo de configuração automática.