Omówienie sesji WinHTTP
Usługi HTTP systemu Microsoft Windows (WinHTTP) uwidacznia zestaw funkcji C/C++, które umożliwiają aplikacji uzyskiwanie dostępu do zasobów HTTP w sieci Web. Ten temat zawiera omówienie sposobu używania tych funkcji do interakcji z serwerem HTTP.
- Dostęp do sieci Web przy użyciu WinHTTP API
- inicjowanie WinHTTP
- Otwieranie Żądania
- dodawanie nagłówków żądań
- Wysyłanie żądania
- publikowanie danych na serwerze
- Uzyskiwanie informacji na temat żądania
- Pobieranie zasobów z sieci Web
Uzyskiwanie dostępu do sieci Web przy użyciu interfejsu API WinHTTP
Na poniższym diagramie przedstawiono kolejność, w jakiej funkcje WinHTTP są zwykle wywoływane podczas interakcji z serwerem HTTP. Zacienione pola reprezentują funkcje, które generują uchwyt HINTERNET, a zwykłe pola reprezentują funkcje używające tych uchwytów.
Inicjowanie usługi WinHTTP
Przed rozpoczęciem interakcji z serwerem należy zainicjować winHTTP, wywołując WinHttpOpen. WinHttpOpen tworzy kontekst sesji w celu zachowania szczegółowych informacji o sesji HTTP i zwraca dojście sesji. Korzystając z tego uchwytu, funkcja WinHttpConnect może następnie określić docelowy serwer HTTP lub serwer HTTPS (Bezpieczny protokół przesyłania hipertekstu).
Notatka
Wywołanie WinHttpConnect nie powoduje rzeczywistego połączenia z serwerem HTTP, dopóki żądanie nie zostanie wykonane dla określonego zasobu.
Otwieranie żądania
Funkcja WinHttpOpenRequest otwiera żądanie HTTP dla określonego zasobu i zwraca uchwyt HINTERNET, który może być używany przez inne funkcje HTTP. WinHttpOpenRequest nie wysyła żądania do serwera po wywołaniu. Funkcja WinHttpSendRequest faktycznie ustanawia połączenie za pośrednictwem sieci i wysyła żądanie.
W poniższym przykładzie pokazano przykładowe wywołanie WinHttpOpenRequest, które używa opcji domyślnych.
HINTERNET hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, NULL, NULL, 0);
Dodawanie nagłówków żądań
Funkcja WinHttpAddRequestHeaders umożliwia aplikacji dołączanie dodatkowych nagłówków żądań w formacie wolnym do dojścia żądania HTTP. Jest ona przeznaczona do użycia przez zaawansowane aplikacje, które wymagają dokładnej kontroli nad żądaniami wysyłanymi do serwera HTTP.
Funkcja WinHttpAddRequestHeaders wymaga obsługi żądania HTTP utworzonej przez WinHttpOpenRequest, ciągu znaków zawierającego nagłówki, długości nagłówków oraz wszelkich modyfikatorów.
Następujące modyfikatory mogą być używane z WinHttpAddRequestHeaders.
Modyfikator | Opis |
---|---|
WINHTTP_ADDREQ_FLAG_ADD | Dodaje nagłówek, jeśli nie istnieje. Używany z WINHTTP_ADDREQ_FLAG_REPLACE. |
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW | Dodaje nagłówek tylko wtedy, gdy jeszcze nie istnieje; w przeciwnym razie zwracany jest błąd. |
WINHTTP_ADDREQ_FLAG_COALESCE | Łączy nagłówki o tej samej nazwie. |
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA | Łączy nagłówki o tej samej nazwie za pomocą przecinka. Na przykład dodanie ciągu "Accept: text/*", a następnie "Accept: audio/*" z tą flagą tworzy jeden nagłówek "Accept: text/*, audio/*", powodując połączenie pierwszego znalezionego nagłówka. To w gestii aplikacji wywołującej jest zapewnienie spójnego schematu w odniesieniu do scalonych/oddzielnych nagłówków. |
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON | Łączy nagłówki o tej samej nazwie za pomocą średnika. |
WINHTTP_ADDREQ_FLAG_REPLACE | Zastępuje lub usuwa nagłówek. Jeśli wartość pola nagłówka jest pusta i nagłówek zostanie znaleziony, to jest on usuwany. Jeśli wartość nagłówka nie jest pusta, wartość nagłówka zostanie zamieniona. |
Wysyłanie żądania
Funkcja WinHttpSendRequest ustanawia połączenie z serwerem i wysyła żądanie do określonej lokacji. Ta funkcja wymaga uchwytu HINTERNET utworzonego przez WinHttpOpenRequest. WinHttpSendRequest może również wysyłać dodatkowe nagłówki lub informacje opcjonalne. Opcjonalne informacje są zwykle używane w przypadku operacji zapisujących informacje na serwerze, takich jak PUT i POST.
Po wysłaniu żądania przez funkcję WinHttpSendRequest aplikacja może użyć funkcji WinHttpReadData i WinHttpQueryDataAvailable na uchwyt HINTERNET do pobrania zasobów serwera.
Publikowanie danych na serwerze
Aby wysłać dane na serwer, czasownik HTTP w wywołaniu WinHttpOpenRequest musi być jednym z dwóch: POST lub PUT. Po wywołaniu WinHttpSendRequest należy ustawić parametr dwTotalLength na rozmiar danych w bajtach. Następnie użyj WinHttpWriteData, aby opublikować dane na serwerze.
Alternatywnie ustaw parametr lpOptional WinHttpSendRequest na adres buforu zawierającego dane do opublikowania na serwerze. W przypadku korzystania z tej techniki należy ustawić zarówno dwOptionalLength, jak i dwTotalLength parametrów WinHttpSendRequest jako rozmiar publikowanych danych. Wywołanie WinHttpSendRequest w ten sposób eliminuje konieczność wywoływania WinHttpWriteData.
Uzyskiwanie informacji o żądaniu
Funkcja WinHttpQueryHeaders umożliwia aplikacji pobieranie informacji o żądaniu HTTP. Funkcja wymaga HINTERNET utworzonego przez WinHttpOpenRequest, wartości poziomu informacji i długości buforu. WinHttpQueryHeaders również akceptuje bufor, który przechowuje informacje i indeks nagłówka zero, który wylicza wiele nagłówków o tej samej nazwie.
Użyj dowolnych poziomów informacji znalezionych na stronie Flagi informacji o zapytaniach z modyfikatorem, aby kontrolować format przechowywania informacji w parametrze lpvBuffer funkcji WinHttpQueryHeaders.
Pobieranie zasobów z sieci Web
Po otwarciu żądania za pomocą funkcji WinHttpOpenRequest, wysyłanie go do serwera za pomocą WinHttpSendRequesti przygotowanie dojścia żądania w celu odebrania odpowiedzi za pomocą WinHttpReceiveResponseaplikacja może użyć WinHttpReadData i funkcji WinHttpQueryDataAvailable w celu pobrania zasobu z serwera HTTP.
Poniższy przykładowy kod pokazuje, jak pobrać zasób z bezpiecznymi semantykami transakcji. Przykładowy kod inicjuje interfejs programowania aplikacji WinHTTP (API), wybiera docelowy serwer HTTPS, a następnie otwiera i wysyła żądanie dla tego bezpiecznego zasobu. WinHttpQueryDataAvailable służy do obsługi żądań w celu określenia ilości dostępnych danych do pobrania, a następnie WinHttpReadData jest używana do odczytywania tych danych. Ten proces jest powtarzany do momentu pobrania i wyświetlenia całego dokumentu.
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 );