Funciones de AutoProxy de WinHTTP

WinHTTP implementa el protocolo WPAD mediante la función WinHttpGetProxyForUrl junto con dos funciones de utilidad compatibles, WinHttpDetectAutoProxyConfigUrl y WinHttpGetIEProxyConfigForCurrentUser.

La compatibilidad con AutoProxy no está totalmente integrada en la pila HTTP en WinHTTP. Antes de enviar una solicitud, la aplicación debe llamar a WinHttpGetProxyForUrl para obtener el nombre de un servidor proxy y, a continuación, llamar a WinHttpSetOption mediante WINHTTP_OPTION_PROXY para establecer la configuración de proxy en el identificador de solicitud WinHTTP creado por WinHttpOpenRequest.

La función WinHttpGetProxyForUrl puede ejecutar los tres pasos del protocolo WPAD descrito en la información general anterior: (1) detectar la dirección URL de PAC, (2) descargar el archivo de script PAC, (3) ejecutar el código de script y devolver la configuración del proxy en una estructura de WINHTTP_PROXY_INFO . Opcionalmente, si la aplicación conoce de antemano la dirección URL de PAC, puede especificarla en WinHttpGetProxyForUrl.

En el código de ejemplo siguiente se usa autoproxy. Configura una solicitud HTTP GET creando primero los identificadores de conexión y solicitud de la sesión winHTTP. La llamada a WinHttpOpen especifica WINHTTP_ACCESS_TYPE_NO_PROXY para la configuración de proxy inicial, para indicar que las solicitudes se envían directamente al servidor de destino de forma predeterminada. Con autoproxy, establece la configuración de proxy directamente en el identificador de solicitud.

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

En el código de ejemplo proporcionado, la llamada a WinHttpGetProxyForUrl indica a la función que detecte automáticamente el archivo de configuración automática del proxy especificando la marca WINHTTP_AUTOPROXY_AUTO_DETECT en la estructura WINHTTP_AUTOPROXY_OPTIONS . El uso de la marca WINHTTP_AUTOPROXY_AUTO_DETECT requiere que el código especifique una o ambas marcas de detección automática (WINHTTP_AUTO_DETECT_TYPE_DHCP, WINHTTP_AUTO_DETECT_TYPE_DNS_A). El código de ejemplo usa la característica de detección automática de WinHttpGetProxyForUrl porque la dirección URL de PAC no se conoce de antemano. Si no se puede encontrar una dirección URL de PAC en la red en este escenario, WinHttpGetProxyForUrl produce un error (GetLastError devuelve ERROR_WINHTTP_AUTODETECTION_FAILED).

Si la dirección URL de PAC se conoce de antemano

Si la aplicación conoce la dirección URL de PAC, puede especificarla en la estructura de WINHTTP_AUTOPROXY_OPTIONS y configurar WinHttpGetProxyForUrl para omitir la fase de detección automática.

Por ejemplo, si un archivo PAC está disponible en la red local en la dirección URL, "https://InternalSite/proxy-config.pac"; la llamada a WinHttpGetProxyForUrl tendría el siguiente aspecto.

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

Si la estructura de WINHTTP_AUTOPROXY_OPTIONS especifica tanto marcas de WINHTTP_AUTOPROXY_AUTO_DETECT comode WINHTTP_AUTOPROXY_CONFIG_URL (y especifica marcas de detción automática y una dirección URL de configuración automática), WinHttpGetProxyForUrl intenta primero la detección automática y, a continuación, si la detección automática no encuentra una dirección URL de PAC, "retrocede" a la dirección URL de configuración automática proporcionada por la aplicación.

Función WinHttpDetectAutoProxyConfigUrl

La función WinHttpDetectAutoProxyConfigUrl implementa un subconjunto del protocolo WPAD: intenta detectar automáticamente la dirección URL del archivo de configuración automática del proxy, sin descargar ni ejecutar el archivo PAC. Esta función es útil en situaciones especiales en las que una aplicación cliente web debe controlar la descarga y ejecución del propio archivo PAC.

Función WinHttpGetIEProxyConfigForCurrentUser

La función WinHttpGetIEProxyConfigForCurrentUser devuelve la configuración actual del proxy de Internet Explorer del usuario para la conexión de red activa actual, sin llamar a "WinInet.dll". Esta función solo es útil cuando se llama dentro de un proceso que se ejecuta en una identidad de cuenta de usuario interactiva, ya que es probable que no haya ninguna configuración de proxy de Internet Explorer disponible en caso contrario. Por ejemplo, no sería útil llamar a esta función desde un archivo DLL isAPI que se ejecuta en el proceso del servicio IIS. Para obtener más información y un escenario en el que una aplicación basada en WinHTTPHTTP usaría WinHttpGetIEProxyConfigForCurrentUser, consulte Detección sin un archivo de configuración automática.