Panoramica delle sessioni WinHTTP

Microsoft Windows HTTP Services (WinHTTP) espone un set di funzioni C/C++ che consentono all'applicazione di accedere alle risorse HTTP sul Web. In questo argomento viene fornita una panoramica del modo in cui queste funzioni vengono usate per interagire con un server HTTP.

Uso dell'API WinHTTP per accedere al Web

Il diagramma seguente illustra l'ordine in cui le funzioni WinHTTP vengono in genere chiamate durante l'interazione con un server HTTP. Le caselle ombreggiate rappresentano funzioni che generano un handle DELL'interfaccia UTENTE, mentre le caselle semplici rappresentano le funzioni che usano tali handle.

funzioni che creano handle

Inizializzazione di WinHTTP

Prima di interagire con un server, WinHTTP deve essere inizializzato chiamando WinHttpOpen. WinHttpOpen crea un contesto di sessione per mantenere i dettagli sulla sessione HTTP e restituisce un handle di sessione. Usando questo handle, la funzione WinHttpConnect è quindi in grado di specificare un server HTTP o HTTPS (Secure Hypertext Transfer Protocol) di destinazione.

Nota

Una chiamata a WinHttpConnect non comporta una connessione effettiva al server HTTP fino a quando non viene effettuata una richiesta per una risorsa specifica.

 

Apertura di una richiesta

La funzione WinHttpOpenRequest apre una richiesta HTTP per una determinata risorsa e restituisce un handle JSONNET che può essere usato dalle altre funzioni HTTP. WinHttpOpenRequest non invia la richiesta al server quando viene chiamato. La funzione WinHttpSendRequest stabilisce effettivamente una connessione in rete e invia la richiesta.

L'esempio seguente mostra una chiamata di esempio a WinHttpOpenRequest che usa le opzioni predefinite.

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

Aggiunta di intestazioni di richiesta

La funzione WinHttpAddRequestHeaders consente a un'applicazione di aggiungere altre intestazioni di richiesta in formato libero all'handle di richiesta HTTP. È destinato all'uso da parte di applicazioni sofisticate che richiedono un controllo preciso sulle richieste inviate al server HTTP.

La funzione WinHttpAddRequestHeaders richiede un handle di richiesta HTTP creato da WinHttpOpenRequest, una stringa contenente le intestazioni, la lunghezza delle intestazioni e tutti i modificatori.

I modificatori seguenti possono essere usati con WinHttpAddRequestHeaders.

Modificatore Descrizione
WINHTTP_ADDREQ_FLAG_ADD Aggiunge l'intestazione se non esiste. Usato con WINHTTP_ADDREQ_FLAG_REPLACE.
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW Aggiunge l'intestazione solo se non esiste già; in caso contrario, viene restituito un errore.
WINHTTP_ADDREQ_FLAG_COALESCE Unisce le intestazioni con lo stesso nome.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA Unisce le intestazioni dello stesso nome usando una virgola. Ad esempio, l'aggiunta di "Accept: text/*" seguita da "Accept: audio/*" con questo flag costituisce la singola intestazione "Accept: text/*, audio/*", causando l'unione della prima intestazione. Spetta all'applicazione chiamante garantire uno schema coesivo rispetto alle intestazioni unite/separate.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON Unisce le intestazioni con lo stesso nome usando un punto e virgola.
WINHTTP_ADDREQ_FLAG_REPLACE Sostituisce o rimuove un'intestazione. Se il valore dell'intestazione è vuoto e l'intestazione viene trovata, viene rimossa. Se il valore dell'intestazione non è vuoto, il valore dell'intestazione viene sostituito.

 

Invio di una richiesta

La funzione WinHttpSendRequest stabilisce una connessione al server e invia la richiesta al sito specificato. Questa funzione richiede un handle DELL'interfaccia UTENTE CREATA da WinHttpOpenRequest. WinHttpSendRequest può anche inviare intestazioni aggiuntive o informazioni facoltative. Le informazioni facoltative vengono in genere usate per le operazioni che scrivono informazioni nel server, ad esempio PUT e POST.

Dopo l'invio della richiesta da parte della funzione WinHttpSendRequest , l'applicazione può usare le funzioni WinHttpReadData e WinHttpQueryDataAvailable nell'handle DELLANET PER scaricare le risorse del server.

Registrazione dei dati nel server

Per pubblicare dati in un server, il verbo HTTP nella chiamata a WinHttpOpenRequest deve essere POST o PUT. Quando viene chiamato WinHttpSendRequest , il parametro dwTotalLength deve essere impostato sulle dimensioni dei dati in byte. Usare quindi WinHttpWriteData per pubblicare i dati nel server.

In alternativa, impostare il parametro lpOptional di WinHttpSendRequest sull'indirizzo di un buffer che contiene dati da pubblicare nel server. Quando si usa questa tecnica, è necessario impostare i parametri dwOptionalLength e dwTotalLength di WinHttpSendRequest in modo che siano le dimensioni dei dati inviati. La chiamata a WinHttpSendRequest in questo modo elimina la necessità di chiamare WinHttpWriteData.

Recupero di informazioni su una richiesta

La funzione WinHttpQueryHeaders consente a un'applicazione di recuperare informazioni su una richiesta HTTP. La funzione richiede un handle DELLNET creato da WinHttpOpenRequest, un valore a livello di informazioni e una lunghezza del buffer. WinHttpQueryHeaders accetta anche un buffer che archivia le informazioni e un indice di intestazione in base zero che enumera più intestazioni con lo stesso nome.

Usare uno dei valori a livello di informazioni disponibili nella pagina Flag informazioni query con un modificatore per controllare il formato in cui le informazioni vengono archiviate nel parametro lpvBuffer di WinHttpQueryHeaders.

Download di risorse dal Web

Dopo aver aperto una richiesta con la funzione WinHttpOpenRequest , inviarla al server con WinHttpSendRequest e preparare l'handle di richiesta per ricevere una risposta con WinHttpReceiveResponse, l'applicazione può usare le funzioni WinHttpReadData e WinHttpQueryDataAvailable per scaricare la risorsa dal server HTTP.

Il codice di esempio seguente illustra come scaricare una risorsa con semantica di transazione sicura. Il codice di esempio inizializza l'API (Application Programming Interface) WinHTTP, seleziona un server HTTPS di destinazione e quindi apre e invia una richiesta per questa risorsa protetta. WinHttpQueryDataAvailable viene usato con l'handle di richiesta per determinare la quantità di dati disponibili per il download e quindi WinHttpReadData viene usato per leggere tali dati. Questo processo viene ripetuto fino a quando l'intero documento non viene recuperato e visualizzato.

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