Übersicht über WinHTTP-Sitzungen
Die Microsoft Windows HTTP-Dienste (WinHTTP) machen eine Reihe von C/C++-Funktionen verfügbar, mit denen Ihre Anwendung auf HTTP-Ressourcen im Web zugreifen kann. Dieses Thema bietet eine Übersicht darüber, wie diese Funktionen für die Interaktion mit einem HTTP-Server verwendet werden.
- Verwenden der WinHTTP-API für den Zugriff auf das Web
- Initialisieren von WinHTTP
- Öffnen einer Anforderung
- Hinzufügen von Anforderungsheadern
- Senden einer Anforderung
- Bereitstellen von Daten auf dem Server
- Abrufen von Informationen zu einer Anforderung
- Herunterladen von Ressourcen aus dem Web
Verwenden der WinHTTP-API für den Zugriff auf das Web
Das folgende Diagramm zeigt die Reihenfolge, in der WinHTTP-Funktionen normalerweise aufgerufen werden, wenn sie mit einem HTTP-Server interagieren. Die schattierten Felder stellen Funktionen dar, die ein HINTERNET-Handle generieren, während die einfachen Felder Funktionen darstellen, die diese Handles verwenden.
Initialisieren von WinHTTP
Vor der Interaktion mit einem Server muss WinHTTP durch Aufrufen von WinHttpOpen initialisiert werden. WinHttpOpen erstellt einen Sitzungskontext, um Details zur HTTP-Sitzung zu verwalten, und gibt ein Sitzungshandle zurück. Mithilfe dieses Handles kann die WinHttpConnect-Funktion dann einen HTTP- oder HTTPS-Zielserver (Secure Hypertext Transfer Protocol) angeben.
Hinweis
Ein Aufruf von WinHttpConnect führt erst dann zu einer tatsächlichen Verbindung mit dem HTTP-Server, wenn eine Anforderung für eine bestimmte Ressource gestellt wird.
Öffnen einer Anforderung
Die WinHttpOpenRequest-Funktion öffnet eine HTTP-Anforderung für eine bestimmte Ressource und gibt ein HINTERNET-Handle zurück, das von den anderen HTTP-Funktionen verwendet werden kann. WinHttpOpenRequest sendet die Anforderung beim Aufruf nicht an den Server. Die WinHttpSendRequest-Funktion stellt tatsächlich eine Verbindung über das Netzwerk her und sendet die Anforderung.
Das folgende Beispiel zeigt einen Beispielaufruf von WinHttpOpenRequest , der die Standardoptionen verwendet.
HINTERNET hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, NULL, NULL, 0);
Hinzufügen von Anforderungsheadern
Die WinHttpAddRequestHeaders-Funktion ermöglicht es einer Anwendung, zusätzliche Freiformat-Anforderungsheader an das HTTP-Anforderungshandle anzufügen. Es ist für die Verwendung durch anspruchsvolle Anwendungen vorgesehen, die eine präzise Kontrolle über die an den HTTP-Server gesendeten Anforderungen erfordern.
Die WinHttpAddRequestHeaders-Funktion erfordert ein von WinHttpOpenRequest erstelltes HTTP-Anforderungshandle, eine Zeichenfolge, die die Header, die Länge der Header und alle Modifizierer enthält.
Die folgenden Modifizierer können mit WinHttpAddRequestHeaders verwendet werden.
Modifizierer | BESCHREIBUNG |
---|---|
WINHTTP_ADDREQ_FLAG_ADD | Fügt den Header hinzu, wenn er nicht vorhanden ist. Wird mit WINHTTP_ADDREQ_FLAG_REPLACE verwendet. |
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW | Fügt den Header nur hinzu, wenn er noch nicht vorhanden ist. Andernfalls wird ein Fehler zurückgegeben. |
WINHTTP_ADDREQ_FLAG_COALESCE | Führt Kopfzeilen mit demselben Namen zusammen. |
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA | Führt Kopfzeilen mit demselben Namen mithilfe eines Kommas zusammen. Wenn Sie beispielsweise "Accept: text/*" gefolgt von "Accept: audio/*" mit diesem Flag hinzufügen, entsteht der einzelne Header "Accept: text/*, audio/*", sodass der erste gefundene Header zusammengeführt wird. Es liegt an der aufrufenden Anwendung, ein zusammenhängendes Schema in Bezug auf zusammengeführte/separate Header sicherzustellen. |
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON | Führt Kopfzeilen mit demselben Namen mithilfe eines Semikolons zusammen. |
WINHTTP_ADDREQ_FLAG_REPLACE | Ersetzt oder entfernt einen Header. Wenn der Headerwert leer ist und der Header gefunden wird, wird er entfernt. Wenn der Headerwert nicht leer ist, wird der Headerwert ersetzt. |
Senden einer Anforderung
Die WinHttpSendRequest-Funktion stellt eine Verbindung mit dem Server her und sendet die Anforderung an den angegebenen Standort. Diese Funktion erfordert ein von WinHttpOpenRequesterstelltes HINTERNET-Handle. WinHttpSendRequest kann auch zusätzliche Header oder optionale Informationen senden. Die optionalen Informationen werden im Allgemeinen für Vorgänge verwendet, die Informationen auf den Server schreiben, z. B. PUT und POST.
Nachdem die WinHttpSendRequest-Funktion die Anforderung gesendet hat, kann die Anwendung die Funktionen WinHttpReadData und WinHttpQueryDataAvailable im HINTERNET-Handle verwenden, um die Ressourcen des Servers herunterzuladen.
Bereitstellen von Daten auf dem Server
Um Daten auf einem Server zu posten, muss das HTTP-Verb im Aufruf von WinHttpOpenRequest entweder POST oder PUT sein. Wenn WinHttpSendRequest aufgerufen wird, sollte der dwTotalLength-Parameter auf die Größe der Daten in Bytes festgelegt werden. Verwenden Sie dann WinHttpWriteData , um die Daten auf dem Server zu veröffentlichen.
Alternativ können Sie den lpOptional-Parameter von WinHttpSendRequest auf die Adresse eines Puffers festlegen, der Daten enthält, die auf dem Server bereitgestellt werden sollen. Wenn Sie dieses Verfahren verwenden, müssen Sie sowohl die Parameter dwOptionalLength als auch dwTotalLength von WinHttpSendRequest auf die Größe der bereitgestellten Daten festlegen. Durch das Aufrufen von WinHttpSendRequest auf diese Weise ist es nicht mehr erforderlich , WinHttpWriteData aufzurufen.
Abrufen von Informationen zu einer Anforderung
Mit der WinHttpQueryHeaders-Funktion kann eine Anwendung Informationen zu einer HTTP-Anforderung abrufen. Die Funktion erfordert ein von WinHttpOpenRequesterstelltes HINTERNET-Handle, einen Wert auf Informationsebene und eine Pufferlänge. WinHttpQueryHeaders akzeptiert auch einen Puffer, der die Informationen speichert, und einen nullbasierten Headerindex, der mehrere Header mit demselben Namen aufzählt.
Verwenden Sie einen der Werte der Informationsebene, die auf der Seite Abfrageinformationsflags gefunden werden, mit einem Modifizierer, um das Format zu steuern, in dem die Informationen im lpvBuffer-Parameter von WinHttpQueryHeaders gespeichert werden.
Herunterladen von Ressourcen aus dem Web
Nach dem Öffnen einer Anforderung mit der WinHttpOpenRequest-Funktion , dem Senden an den Server mit WinHttpSendRequest und dem Vorbereiten des Anforderungshandles zum Empfangen einer Antwort mit WinHttpReceiveResponse kann die Anwendung die Funktionen WinHttpReadData und WinHttpQueryDataAvailable verwenden, um die Ressource vom HTTP-Server herunterzuladen.
Der folgende Beispielcode zeigt, wie Sie eine Ressource mit sicherer Transaktionssemantik herunterladen. Der Beispielcode initialisiert die WinHTTP-Api (Application Programming Interface), wählt einen HTTPS-Zielserver aus, öffnet und sendet eine Anforderung für diese sichere Ressource. WinHttpQueryDataAvailable wird mit dem Anforderungshandle verwendet, um zu bestimmen, wie viele Daten zum Herunterladen verfügbar sind, und dann wird WinHttpReadData verwendet, um diese Daten zu lesen. Dieser Vorgang wird wiederholt, bis das gesamte Dokument abgerufen und angezeigt wurde.
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 );