Información general sobre sesiones winHTTP

Los servicios HTTP de Microsoft Windows (WinHTTP) exponen un conjunto de funciones de C/C++ que permiten a la aplicación acceder a recursos HTTP en la Web. En este tema se proporciona información general sobre cómo se usan estas funciones para interactuar con un servidor HTTP.

Uso de la API de WinHTTP para acceder a la Web

En el diagrama siguiente se muestra el orden en el que normalmente se llama a las funciones WinHTTP al interactuar con un servidor HTTP. Los cuadros sombreados representan funciones que generan un identificador HINTERNET , mientras que los cuadros sin formato representan funciones que usan esos identificadores.

funciones que crean identificadores

Inicialización de WinHTTP

Antes de interactuar con un servidor, WinHTTP debe inicializarse llamando a WinHttpOpen. WinHttpOpen crea un contexto de sesión para mantener detalles sobre la sesión HTTP y devuelve un identificador de sesión. Con este identificador, la función WinHttpConnect puede especificar un servidor http de destino o protocolo seguro de transferencia de hipertexto (HTTPS).

Nota

Una llamada a WinHttpConnect no da lugar a una conexión real con el servidor HTTP hasta que se realiza una solicitud para un recurso específico.

 

Abrir una solicitud

La función WinHttpOpenRequest abre una solicitud HTTP para un recurso determinado y devuelve un identificador HINTERNET que las demás funciones HTTP pueden usar. WinHttpOpenRequest no envía la solicitud al servidor cuando se llama a . La función WinHttpSendRequest establece realmente una conexión a través de la red y envía la solicitud.

En el ejemplo siguiente se muestra una llamada de ejemplo a WinHttpOpenRequest que usa las opciones predeterminadas.

HINTERNET hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, NULL, NULL, 0);

Agregar encabezados de solicitud

La función WinHttpAddRequestHeaders permite a una aplicación anexar encabezados de solicitud de formato libre adicionales al identificador de solicitud HTTP. Está diseñado para su uso por aplicaciones sofisticadas que requieren un control preciso sobre las solicitudes enviadas al servidor HTTP.

La función WinHttpAddRequestHeaders requiere un identificador de solicitud HTTP creado por WinHttpOpenRequest, una cadena que contiene los encabezados, la longitud de los encabezados y los modificadores.

Los siguientes modificadores se pueden usar con WinHttpAddRequestHeaders.

Modificador Descripción
WINHTTP_ADDREQ_FLAG_ADD Agrega el encabezado si no existe. Se usa con WINHTTP_ADDREQ_FLAG_REPLACE.
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW Agrega el encabezado solo si aún no existe; de lo contrario, se devuelve un error.
WINHTTP_ADDREQ_FLAG_COALESCE Combina encabezados con el mismo nombre.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA Combina encabezados del mismo nombre con una coma. Por ejemplo, al agregar "Accept: text/*" seguido de "Accept: audio/*" con esta marca se forma el encabezado único "Accept: text/*, audio/*", lo que hace que se combine el primer encabezado encontrado. Es la aplicación que realiza la llamada para garantizar un esquema cohesivo con respecto a encabezados combinados o independientes.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON Combina encabezados del mismo nombre con un punto y coma.
WINHTTP_ADDREQ_FLAG_REPLACE Reemplaza o quita un encabezado. Si el valor del encabezado está vacío y se encuentra el encabezado, se quita. Si el valor del encabezado no está vacío, se reemplaza el valor del encabezado.

 

Envío de una solicitud

La función WinHttpSendRequest establece una conexión con el servidor y envía la solicitud al sitio especificado. Esta función requiere un identificador HINTERNET creado por WinHttpOpenRequest. WinHttpSendRequest también puede enviar encabezados adicionales o información opcional. La información opcional se usa generalmente para las operaciones que escriben información en el servidor, como PUT y POST.

Una vez que la función WinHttpSendRequest envía la solicitud, la aplicación puede usar las funciones WinHttpReadData y WinHttpQueryDataAvailable en el identificador HINTERNET para descargar los recursos del servidor.

Publicar datos en el servidor

Para publicar datos en un servidor, el verbo HTTP de la llamada a WinHttpOpenRequest debe ser POST o PUT. Cuando se llama a WinHttpSendRequest , el parámetro dwTotalLength debe establecerse en el tamaño de los datos en bytes. A continuación, use WinHttpWriteData para publicar los datos en el servidor.

Como alternativa, establezca el parámetro lpOptional de WinHttpSendRequest en la dirección de un búfer que contiene los datos que se van a publicar en el servidor. Al usar esta técnica, debe establecer los parámetros dwOptionalLength y dwTotalLength de WinHttpSendRequest para que sean el tamaño de los datos que se publican. Llamar a WinHttpSendRequest de esta manera elimina la necesidad de llamar a WinHttpWriteData.

Obtener información sobre una solicitud

La función WinHttpQueryHeaders permite a una aplicación recuperar información sobre una solicitud HTTP. La función requiere un identificador HINTERNET creado por WinHttpOpenRequest, un valor de nivel de información y una longitud del búfer. WinHttpQueryHeaders también acepta un búfer que almacena la información y un índice de encabezado basado en cero que enumera varios encabezados con el mismo nombre.

Use cualquiera de los valores de nivel de información que se encuentran en la página Marcas de información de consulta con un modificador para controlar el formato en el que la información se almacena en el parámetro lpvBuffer de WinHttpQueryHeaders.

Descarga de recursos desde la Web

Después de abrir una solicitud con la función WinHttpOpenRequest, enviarlo al servidor con WinHttpSendRequest y preparar el identificador de solicitud para recibir una respuesta con WinHttpReceiveResponse, la aplicación puede usar las funciones WinHttpReadData y WinHttpQueryDataAvailable para descargar el recurso desde el servidor HTTP.

En el código de ejemplo siguiente se muestra cómo descargar un recurso con semántica de transacciones seguras. El código de ejemplo inicializa la interfaz de programación de aplicaciones (API) WinHTTP, selecciona un servidor HTTPS de destino y, a continuación, abre y envía una solicitud para este recurso seguro. WinHttpQueryDataAvailable se usa con el identificador de solicitud para determinar la cantidad de datos disponibles para su descarga y, a continuación, Se usa WinHttpReadData para leer esos datos. Este proceso se repite hasta que se ha recuperado y mostrado todo el documento.

  DWORD dwSize = 0;
  DWORD dwDownloaded = 0;
  LPSTR pszOutBuffer;
  BOOL  bResults = FALSE;
  HINTERNET  hSession = NULL, 
             hConnect = NULL,
             hRequest = NULL;

  // Use WinHttpOpen to obtain a session handle.
  hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                          WINHTTP_NO_PROXY_NAME, 
                          WINHTTP_NO_PROXY_BYPASS, 0 );

  // Specify an HTTP server.
  if( hSession )
    hConnect = WinHttpConnect( hSession, L"www.microsoft.com",
                               INTERNET_DEFAULT_HTTPS_PORT, 0 );

  // Create an HTTP request handle.
  if( hConnect )
    hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
                                   NULL, WINHTTP_NO_REFERER, 
                                   WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                   WINHTTP_FLAG_SECURE );

  // Send a request.
  if( hRequest )
    bResults = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                   WINHTTP_NO_REQUEST_DATA, 0, 
                                   0, 0 );


  // End the request.
  if( bResults )
    bResults = WinHttpReceiveResponse( hRequest, NULL );

  // Keep checking for data until there is nothing left.
  if( bResults )
  {
    do 
    {
      // Check for available data.
      dwSize = 0;
      if( !WinHttpQueryDataAvailable( hRequest, &dwSize ) )
        printf( "Error %u in WinHttpQueryDataAvailable.\n",
                GetLastError( ) );

      // Allocate space for the buffer.
      pszOutBuffer = new char[dwSize+1];
      if( !pszOutBuffer )
      {
        printf( "Out of memory\n" );
        dwSize=0;
      }
      else
      {
        // Read the data.
        ZeroMemory( pszOutBuffer, dwSize+1 );

        if( !WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                              dwSize, &dwDownloaded ) )
          printf( "Error %u in WinHttpReadData.\n", GetLastError( ) );
        else
          printf( "%s", pszOutBuffer );

        // Free the memory allocated to the buffer.
        delete [] pszOutBuffer;
      }
    } while( dwSize > 0 );
  }


  // Report any errors.
  if( !bResults )
    printf( "Error %d has occurred.\n", GetLastError( ) );

  // Close any open handles.
  if( hRequest ) WinHttpCloseHandle( hRequest );
  if( hConnect ) WinHttpCloseHandle( hConnect );
  if( hSession ) WinHttpCloseHandle( hSession );