Přehled relací WinHTTP

Služba Microsoft Windows HTTP Services (WinHTTP) zveřejňuje sadu funkcí C/C++, které vaší aplikaci umožňují přístup k prostředkům HTTP na webu. Toto téma obsahuje přehled o tom, jak se tyto funkce používají k interakci se serverem HTTP.

Použití rozhraní WINHTTP API pro přístup k webu

Následující diagram znázorňuje pořadí, ve kterém se funkce WinHTTP obvykle volají při interakci se serverem HTTP. Stínovaná pole představují funkce, které generují hinternet úchyt, zatímco prosté rámečky představují funkce, které používají tyto úchyty.

funkce, které vytvářejí popisovače

Inicializace WinHTTP

Před interakcí se serverem musí být WinHTTP inicializován voláním WinHttpOpen. WinHttpOpen vytvoří kontext relace pro zachování podrobností o relaci HTTP a vrátí popisovač relace. Pomocí tohoto popisovače může funkce WinHttpConnect zadat cílový server HTTP nebo HTTPS (Secure Hypertext Transfer Protocol).

Poznámka

Volání WinHttpConnect nemá za následek skutečné připojení k serveru HTTP, dokud nebude proveden požadavek na konkrétní prostředek.

 

Otevření žádosti

Funkce WinHttpOpenRequest otevře požadavek HTTP na konkrétní prostředek a vrátí popisovač HINTERNET, který mohou používat ostatní funkce HTTP. WinHttpOpenRequest neodesílá požadavek na server při zavolání. Funkce WinHttpSendRequest ve skutečnosti vytvoří připojení přes síť a odešle požadavek.

Následující příklad ukazuje ukázkové volání WinHttpOpenRequest, která používá výchozí možnosti.

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

Přidání hlaviček požadavků

Funkce WinHttpAddRequestHeaders umožňuje aplikaci připojit k popisovači požadavku HTTP další hlavičky požadavku ve volném formátu. Je určen pro použití sofistikovanými aplikacemi, které vyžadují přesnou kontrolu nad požadavky odesílané na server HTTP.

Funkce WinHttpAddRequestHeaders vyžaduje popisovač požadavku HTTP vytvořený funkcí WinHttpOpenRequest, řetězec obsahující hlavičky, délku hlaviček a všechny modifikátory.

Následující modifikátory lze použít s WinHttpAddRequestHeaders.

Modifikátor Popis
WINHTTP_ADDREQ_FLAG_ADD Přidá záhlaví, pokud neexistuje. Používá se s WINHTTP_ADDREQ_FLAG_REPLACE.
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW Přidá záhlaví pouze v případě, že ještě neexistuje; v opačném případě se vrátí chyba.
WINHTTP_ADDREQ_FLAG_COALESCE Sloučí záhlaví se stejným názvem.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA Sloučí záhlaví stejného názvu pomocí čárky. Například přidání "Accept: text/*" následované "Accept: audio/*" s tímto příznakem vytvoří jedno společné záhlaví "Accept: text/*, audio/*", což způsobí spojení do prvního nalezeného záhlaví. Je na volající aplikaci, aby se zajistilo soudržné schéma s ohledem na sloučené nebo samostatné hlavičky.
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON Sloučí záhlaví stejného názvu pomocí středníku.
WINHTTP_ADDREQ_FLAG_REPLACE Nahradí nebo odebere záhlaví. Pokud je hodnota záhlaví prázdná a záhlaví je nalezeno, odebere se. Pokud hodnota záhlaví není prázdná, nahradí se hodnota záhlaví.

 

Odeslání požadavku

Funkce WinHttpSendRequest vytvoří připojení k serveru a odešle požadavek na zadanou lokalitu. Tato funkce vyžaduje popisovač HINTERNET vytvořený WinHttpOpenRequest. WinHttpSendRequest může také odesílat další hlavičky nebo volitelné informace. Volitelné informace se obvykle používají pro operace, které zapisuje informace na server, jako je PUT a POST.

Jakmile funkce WinHttpSendRequest odešle požadavek, může aplikace použít funkce WinHttpReadData a WinHttpQueryDataAvailable na handle HINTERNET ke stažení prostředků serveru.

Publikování dat na server

Pokud chcete publikovat data na server, příkaz HTTP při volání WinHttpOpenRequest musí být POST nebo PUT. Když se volá WinHttpSendRequest, měl by být parametr dwTotalLength nastaven na velikost dat v bajtech. Pak pomocí WinHttpWriteData publikovat data na server.

Případně nastavte parametr lpOptionalWinHttpSendRequest na adresu vyrovnávací paměti obsahující data, která se mají odeslat na server. Při použití této techniky je nutné nastavit parametry dwOptionalLength a dwTotalLength u WinHttpSendRequest tak, aby odpovídaly velikosti dat, která se publikují. Volání WinHttpSendRequest tímto způsobem eliminuje potřebu volat WinHttpWriteData.

Získání informací o žádosti

Funkce WinHttpQueryHeaders umožňuje aplikaci načíst informace o požadavku HTTP. Tato funkce vyžaduje popisovač HINTERNET vytvořený WinHttpOpenRequest, hodnotu úrovně informací a délku vyrovnávací paměti. WinHttpQueryHeaders přijímá také vyrovnávací paměť, která ukládá informace a index hlaviček založený na nule, který vytvoří výčet více hlaviček se stejným názvem.

Pro kontrolu formátu, ve kterém jsou informace uložené v parametru lpvBuffer u WinHttpQueryHeaders, použijte některou z hodnot úrovně informací nalezených na stránce Query Info Flags s modifikátorem.

Stahování zdrojů z webu

Po otevření požadavku pomocí funkce WinHttpOpenRequest odešlete ho na server s WinHttpSendRequesta připravte popisovač požadavku na příjem odpovědi s WinHttpReceiveResponse, aplikace může použít WinHttpReadData a WinHttpQueryDataAvailable funkce ke stažení prostředku ze serveru HTTP.

Následující ukázkový kód ukazuje, jak stáhnout prostředek s zabezpečenou sémantikou transakcí. Ukázkový kód inicializuje programovací rozhraní aplikace WinHTTP (API), vybere cílový server HTTPS a pak se otevře a odešle požadavek na tento zabezpečený prostředek. WinHttpQueryDataAvailable se používá s popisovačem požadavku k určení, kolik dat je možné stáhnout, a pak WinHttpReadData se použije ke čtení těchto dat. Tento proces se opakuje, dokud se celý dokument nenačte a nezobrazí.

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