Share via


Behandeln von Uniform Resource Locators

Ein Uniform Resource Locator (URL) ist eine kompakte Darstellung des Standorts und der Zugriffsmethode für eine Ressource im Internet. Jede URL besteht aus einem Schema (HTTP, HTTPS oder FTP) und einer schemaspezifischen Zeichenfolge. Diese Zeichenfolge kann auch eine Kombination aus einem Verzeichnispfad, einer Suchzeichenfolge oder einem Namen der Ressource enthalten. Die WinINet-Funktionen bieten die Möglichkeit, URLs zu erstellen, zu kombinieren, aufzuschlüsseln und zu kanonisieren. Weitere Informationen zu URLs finden Sie unter RFC-1738 zu Uniform Resource Locators (URL).

Die URL-Funktionen funktionieren aufgabenorientiert. Der Inhalt und das Format der URL, die der Funktion zugewiesen wird, werden nicht überprüft. Die aufrufende Anwendung sollte die Verwendung dieser Funktionen nachverfolgen, um sicherzustellen, dass die Daten im vorgesehenen Format vorliegen. Die InternetCanonicalizeUrl-Funktion konvertiert beispielsweise das Zeichen "%" in die Escapesequenz "%25", wenn keine Flags verwendet werden. Wenn InternetCanonicalizeUrl für die kanonisierte URL verwendet wird, wird die Escapesequenz "%25" in die Escapesequenz "%2525" konvertiert, was nicht ordnungsgemäß funktioniert.

Was ist eine kanonisierte URL?

Das Format aller URLs muss der akzeptierten Syntax und Semantik entsprechen, um über das Internet auf Ressourcen zuzugreifen. Bei der Kanonisierung wird eine URL gemäß dieser akzeptierten Syntax und Semantik formatiert.

Zeichen, die codiert werden müssen, enthalten alle Zeichen, die kein entsprechendes Grafisches Zeichen im US-ASCII-codierten Zeichensatz enthalten (hexadezimal 80-FF, die nicht im US-ASCII-codierten Zeichensatz verwendet werden, und hexadezimal 00-1F und 7F, bei denen es sich um Steuerzeichen handelt), Leerzeichen, "%" (das zum Codieren anderer Zeichen verwendet wird) und unsichere Zeichen (<, ,, >", #, {, }, |, \, ^, ~, [, ], und ') werden nicht verwendet.

Verwenden der WinINet-Funktionen zum Behandeln von URLs

In der folgenden Tabelle sind die URL-Funktionen zusammengefasst.

Funktion BESCHREIBUNG
InternetCanonicalizeUrl Kanonisiert die URL.
InternetCombineUrl Kombiniert Basis- und relative URLs.
InternetCrackUrl Analysiert eine URL-Zeichenfolge in Komponenten.
InternetCreateUrl Erstellt eine URL-Zeichenfolge aus Komponenten.
InternetOpenUrl Beginnt mit dem Abrufen einer FTP-, HTTP- oder HTTPS-Ressource.

 

Kanonisieren von URLs

Das Kanonisieren einer URL ist der Prozess, der eine URL, die unsichere Zeichen wie Leerzeichen, reservierte Zeichen usw. enthalten kann, in ein akzeptiertes Format konvertiert.

Die InternetCanonicalizeUrl-Funktion kann verwendet werden, um URLs zu kanonisieren. Diese Funktion ist sehr aufgabenorientiert, daher sollte die Anwendung ihre Verwendung sorgfältig nachverfolgen. InternetCanonicalizeUrl überprüft nicht, ob die an sie übergebene URL bereits kanonisch ist und dass die zurückgegebene URL gültig ist.

Die folgenden fünf Flags steuern, wie InternetCanonicalizeUrl eine bestimmte URL verarbeitet. Die Flags können in Kombination verwendet werden. Wenn keine Flags verwendet werden, codiert die Funktion die URL standardmäßig.

Wert Bedeutung
ICU_BROWSER_MODE Codieren oder decodieren Sie keine Zeichen nach "#" oder "?", und entfernen Sie den nachfolgenden Leerraum nach "?" nicht. Wenn dieser Wert nicht angegeben wird, wird die gesamte URL codiert, und der nachfolgende Leerraum wird entfernt.
ICU_DECODE Konvertieren Sie alle %XX-Sequenzen in Zeichen, einschließlich Escapesequenzen, bevor die URL analysiert wird.
ICU_ENCODE_SPACES_ONLY Codieren Sie nur Leerzeichen.
ICU_NO_ENCODE Konvertieren Sie keine unsicheren Zeichen in Escapesequenzen.
ICU_NO_META Entfernen Sie keine Metasequenzen (z. B. "." und "..") aus der URL.

 

Das ICU_DECODE-Flag sollte nur für kanonisierte URLs verwendet werden, da es davon ausgeht, dass alle %XX-Sequenzen Escapecodes sind und sie in die vom Code angegebenen Zeichen konvertiert. Wenn die URL ein "%"-Symbol enthält, das nicht Teil eines Escapecodes ist, behandelt ICU_DECODE sie trotzdem als eins. Dieses Merkmal kann dazu führen , dass InternetCanonicalizeUrl eine ungültige URL erstellt.

Um internetCanonicalizeUrl zum Zurückgeben einer vollständig decodierten URL zu verwenden, müssen die Flags ICU_DECODE und ICU_NO_ENCODE angegeben werden. Bei diesem Setup wird davon ausgegangen, dass die AN InternetCanonicalizeUrl übergebene URL zuvor kanonischisiert wurde.

Kombinieren von Basis- und relativen URLs

Eine relative URL ist eine kompakte Darstellung des Speicherorts einer Ressource relativ zu einer absoluten Basis-URL. Die Basis-URL muss dem Parser bekannt sein und enthält in der Regel das Schema, den Netzwerkspeicherort und Teile des URL-Pfads. Eine Anwendung kann InternetCombineUrl aufrufen, um die relative URL mit ihrer Basis-URL zu kombinieren. InternetCombineUrl kanonisiert auch die resultierende URL.

Knacken von URLs

Die InternetCrackUrl-Funktion trennt eine URL in ihre Komponententeile und gibt die Komponenten zurück, die durch die URL_COMPONENTS-Struktur angegeben sind, die an die Funktion übergeben wird.

Die Komponenten, aus denen die URL_COMPONENTS Struktur besteht, sind die Schemanummer, der Hostname, die Portnummer, der Benutzername, das Kennwort, der URL-Pfad und zusätzliche Informationen (z. B. Suchparameter). Jede Komponente, mit Ausnahme des Schemas und der Portnummern, verfügt über einen Zeichenfolgenmember, der die Informationen enthält, und ein Element, das die Länge des Zeichenfolgenelements enthält. Das Schema und die Portnummern verfügen nur über ein Element, das den entsprechenden Wert speichert. beide werden bei allen erfolgreichen Aufrufen von InternetCrackUrl zurückgegeben.

Um den Wert einer bestimmten Komponente in der URL_COMPONENTS-Struktur abzurufen, muss das Element, das die Zeichenfolgenlänge dieser Komponente speichert, auf einen Wert ohne Zero festgelegt werden. Das Zeichenfolgenelement kann entweder die Adresse eines Puffers oder NULL sein.

Wenn das Zeigermember die Adresse eines Puffers enthält, muss der Zeichenfolgenlängenmember die Größe dieses Puffers enthalten. InternetCrackUrl gibt die Komponenteninformationen als Zeichenfolge im Puffer zurück und speichert die Zeichenfolgenlänge im Zeichenfolgenlängenelement.

Wenn der Zeigermember NULL ist, kann der Zeichenfolgenlängenmember auf einen beliebigen Wert ohne Zero festgelegt werden. InternetCrackUrl speichert die Adresse des ersten Zeichens der URL-Zeichenfolge, die die Komponenteninformationen enthält, und legt die Zeichenfolgenlänge auf die Anzahl der Zeichen im verbleibenden Teil der URL-Zeichenfolge fest, die sich auf die Komponente bezieht.

Alle Zeigermember, die auf NULL festgelegt sind, wobei ein Member ohne Zerolänge auf den entsprechenden Startpunkt in der URL-Zeichenfolge zeigt. Die im Längenelement gespeicherte Länge muss verwendet werden, um das Ende der Informationen der einzelnen Komponente zu bestimmen.

Um die URL_COMPONENTS-Struktur ordnungsgemäß zu initialisieren, muss der dwStructSize-Member auf die Größe der URL_COMPONENTS-Struktur in Bytes festgelegt werden.

Im folgenden Beispiel werden die Komponenten der URL im Bearbeitungsfeld zurückgegeben, IDC_PreOpen1, und die Komponenten werden an das Listenfeld zurückgegeben, IDC_PreOpenList. Um nur die Informationen für eine einzelne Komponente anzuzeigen, kopiert diese Funktion das Zeichen unmittelbar nach den Informationen der Komponente in der Zeichenfolge und ersetzt es vorübergehend durch NULL.

#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <wininet.h>
#include <stdlib.h>

#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "user32.lib")

#define  CRACKER_BUFFER_SIZE           MAX_PATH

// For sample source code implementing the InternetErrorOut( ) 
// function referenced below, see the "Handling Errors" topic  
// under "Using WinInet"
extern BOOL WINAPI InternetErrorOut( HWND hWnd, DWORD dwError,
                                     LPCTSTR szFailingFunctionName );

// Forward declaration of listUrlPart helper functions:
BOOL listURLpart( HWND hDlg, int nListBoxID, 
                  LPTSTR szPartName, LPTSTR part, DWORD partLength );
BOOL listURLpart( HWND hDlg, int nListBoxID, 
                  LPTSTR szPartName, int partValue );

// Static list describing the URL Scheme types 
// enumerated in INTERNET_SCHEME:
TCHAR* schemeType[] =
{
  TEXT( "[Partial URL]" ),                //  0
  TEXT( "[Unknown scheme]" ),             //  1
  TEXT( "[Default scheme]" ),             //  2
  TEXT( "FTP" ),                          //  3
  TEXT( "Gopher" ),                       //  4
  TEXT( "HTTP" ),                         //  5
  TEXT( "HTTPS" ),                        //  6
  TEXT( "File" ),                         //  7
  TEXT( "News" ),                         //  8
  TEXT( "MailTo" ),                       //  9
  TEXT( "Socks" ),                        // 10
  TEXT( "JavaScript" ),                   // 11
  TEXT( "VBScript" )                      // 12
};
#define  CRACKER_SCHEME_TYPE_ARRAY_SIZE      13

BOOL WINAPI Cracker( HWND hDlg, int nURLtextBoxId, int nListBoxId )
{
   int i, j;
   TCHAR* failedFunctionName;
   TCHAR URL_buffer[CRACKER_BUFFER_SIZE];

   URL_COMPONENTS URLparts;

   URLparts.dwStructSize = sizeof( URLparts );

   // The following elements determine which components are displayed
   URLparts.dwSchemeLength    = 1;
   URLparts.dwHostNameLength  = 1;
   URLparts.dwUserNameLength  = 1;
   URLparts.dwPasswordLength  = 1;
   URLparts.dwUrlPathLength   = 1;
   URLparts.dwExtraInfoLength = 1;

   URLparts.lpszScheme     = NULL;
   URLparts.lpszHostName   = NULL;
   URLparts.lpszUserName   = NULL;
   URLparts.lpszPassword   = NULL;
   URLparts.lpszUrlPath    = NULL;
   URLparts.lpszExtraInfo  = NULL;

   SendDlgItemMessage( hDlg, nListBoxId, LB_RESETCONTENT, 0, 0 );
   if( !GetDlgItemText( hDlg, nURLtextBoxId, 
                        URL_buffer, CRACKER_BUFFER_SIZE ) )
   {
       failedFunctionName = TEXT( "GetDlgItemText" );
       goto CrackerError_01;
   }

   if( FAILED( StringCchLength( URL_buffer, CRACKER_BUFFER_SIZE, 
                                (size_t*) &i ) ) )
   {
       failedFunctionName = TEXT( "StringCchLength" );
       goto CrackerError_01;
   }

   if( !InternetCrackUrl( URL_buffer, (DWORD)_tcslen( URL_buffer ), 0, 
                          &URLparts ) )
   {
       failedFunctionName = TEXT( "InternetCrackUrl" );
       goto CrackerError_01;
   }

   failedFunctionName = TEXT( "listURLpart" );

   i = URLparts.nScheme + 2;
   if( ( i >= 0 ) && ( i < CRACKER_SCHEME_TYPE_ARRAY_SIZE ) )
   {
       StringCchLength( schemeType[i], 
                        CRACKER_BUFFER_SIZE, 
                        (size_t*) &j );
       if( !listURLpart( hDlg, nListBoxId, 
                         TEXT("Scheme type"), 
                         schemeType[i], j ))
           goto CrackerError_01;
   }

   if( !listURLpart( hDlg, nListBoxId, TEXT( "Scheme text" ), 
                     URLparts.lpszScheme, 
                     URLparts.dwSchemeLength ) ||
       !listURLpart( hDlg, nListBoxId, TEXT( "Host name" ), 
                     URLparts.lpszHostName, 
                     URLparts.dwHostNameLength) ||
       !listURLpart( hDlg, nListBoxId, TEXT( "Port number" ), 
                     (int) URLparts.nPort ) ||
       !listURLpart( hDlg, nListBoxId, TEXT( "User name" ), 
                     URLparts.lpszUserName, 
                     URLparts.dwUserNameLength) ||
       !listURLpart( hDlg, nListBoxId, TEXT( "Password" ), 
                     URLparts.lpszPassword, 
                     URLparts.dwPasswordLength) ||
       !listURLpart( hDlg, nListBoxId, TEXT( "Path" ), 
                     URLparts.lpszUrlPath, 
                     URLparts.dwUrlPathLength) ||
       !listURLpart( hDlg, nListBoxId, TEXT( "Extra information"), 
                     URLparts.lpszExtraInfo, 
                     URLparts.dwExtraInfoLength))
           goto CrackerError_01;

   return( TRUE );

CrackerError_01:
// For sample source code of the InternetErrorOut( ) function 
// referenced below, see the "Handling Errors" 
// topic under "Using WinInet"
   InternetErrorOut( hDlg, GetLastError( ), failedFunctionName );
   return FALSE;
}

// listURLpart( ) helper function for string parts
BOOL listURLpart( HWND hDlg, int nListBoxId, 
                  LPTSTR szPartName, LPTSTR part, DWORD partLength )
{
  TCHAR outputBuffer[CRACKER_BUFFER_SIZE];
  LPTSTR nextStart;
  size_t nextSize;

  if( partLength == 0 )  // Just skip empty ones
    return( TRUE );

  if( FAILED( StringCchCopyEx( outputBuffer, 
                              (size_t) CRACKER_BUFFER_SIZE,
                               szPartName, &nextStart, 
                               &nextSize, 0 ) ) ||
      FAILED( StringCchCopyEx( nextStart, nextSize, TEXT( ": " ), 
                               &nextStart, &nextSize, 0 ) ) ||
      FAILED( StringCchCopyNEx( nextStart, nextSize, part, 
                                (size_t) partLength,
                                &nextStart, &nextSize, 0 ) ) )
    return( FALSE );

  *nextStart = 0;
  if( SendDlgItemMessage( hDlg, nListBoxId, LB_ADDSTRING, 0, 
                          (LPARAM)outputBuffer ) < 0 )
    return( FALSE );
  return( TRUE );
}

// listURLpart( ) helper function for numeric parts
BOOL listURLpart( HWND hDlg, int nListBoxId, 
                  LPTSTR szPartName, int partValue )
{
  TCHAR outputBuffer[CRACKER_BUFFER_SIZE];

  if( FAILED( StringCchPrintf( outputBuffer, 
                               (size_t) CRACKER_BUFFER_SIZE,
                               TEXT( "%s: %d" ), szPartName, 
                               partValue ) ) ||
      ( SendDlgItemMessage( hDlg, nListBoxId, LB_ADDSTRING, 0, 
                            (LPARAM)outputBuffer ) < 0 ) )
    return( FALSE );
  return( TRUE );
}

Erstellen von URLs

Die InternetCreateUrl-Funktion verwendet die Informationen in der URL_COMPONENTS-Struktur , um einen Uniform Resource Locator zu erstellen.

Die Komponenten, aus denen die URL_COMPONENTS Struktur besteht, sind das Schema, der Hostname, die Portnummer, der Benutzername, das Kennwort, der URL-Pfad und zusätzliche Informationen (z. B. Suchparameter). Jede Komponente mit Ausnahme der Portnummer verfügt über ein Zeichenfolgenelement, das die Informationen enthält, und ein Element, das die Länge des Zeichenfolgenmembers enthält.

Für jede erforderliche Komponente sollte der Zeigermember die Adresse des Puffers enthalten, der die Informationen enthält. Das Längenelement sollte auf 0 festgelegt werden, wenn der Zeigermember die Adresse einer Zeichenfolge mit null beendeter Zeichenfolge enthält. Das Längenelement sollte auf die Zeichenfolgenlänge festgelegt werden, wenn der Zeigermember die Adresse einer Zeichenfolge enthält, die nicht mit Null beendet ist. Der Zeigermember aller komponenten, die nicht erforderlich sind, muss NULL sein.

Direkter Zugriff auf URLs

Auf FTP- und HTTP-Ressourcen im Internet kann direkt über die Funktionen InternetOpenUrl, InternetReadFile und InternetFindNextFile zugegriffen werden. InternetOpenUrl öffnet eine Verbindung mit der Ressource an der URL, die an die Funktion übergeben wird. Wenn diese Verbindung hergestellt wird, gibt es zwei mögliche Schritte. Erstens, wenn es sich bei der Ressource um eine Datei handelt, kann InternetReadFile sie herunterladen. Wenn es sich bei der Ressource um ein Verzeichnis handelt, kann InternetFindNextFile die Dateien im Verzeichnis aufzählen (außer wenn CERN-Proxys verwendet werden). Weitere Informationen zu InternetReadFile finden Sie unter Lesen von Dateien. Weitere Informationen zu InternetFindNextFile finden Sie unter Suchen der nächsten Datei.

Für Anwendungen, die über einen CERN-Proxy betrieben werden müssen, kann InternetOpenUrl für den Zugriff auf FTP-Verzeichnisse und -Dateien verwendet werden. Die FTP-Anforderungen werden so gepackt, dass sie wie eine HTTP-Anforderung aussehen, die der CERN-Proxy akzeptiert.

InternetOpenUrl verwendet das von der InternetOpen-Funktion erstellte HINTERNET-Handle und die URL der Ressource. Die URL muss das Schema (http:, ftp:, file: [für eine lokale Datei] oder https: [für Hypertextprotokollsicherheit]) und den Netzwerkspeicherort (z www.microsoft.com. B. ) enthalten. Die URL kann auch einen Pfad enthalten (z. B. /isapi/gomscom.asp? TARGET=/windows/feature/) und Ressourcenname (z. B. default.htm). Für HTTP- oder HTTPS-Anforderungen können zusätzliche Header eingeschlossen werden.

InternetQueryDataAvailable, InternetFindNextFile, InternetReadFile und InternetSetFilePointer (nur HTTP- oder HTTPS-URLs) können das von InternetOpenUrl erstellte Handle verwenden, um die Ressource herunterzuladen.

Das folgende Diagramm veranschaulicht, welche Handles mit jeder Funktion verwendet werden sollen.

Handles für die Verwendung mit Funktionen

Das von InternetOpen erstellte HINTERNET-Stammhandle wird von InternetOpenUrl verwendet. Das von InternetOpenUrl erstellte HINTERNET-Handle kann von InternetQueryDataAvailable, InternetReadFile, InternetFindNextFile (hier nicht angezeigt) und InternetSetFilePointer (nur HTTP- oder HTTPS-URLs) verwendet werden.

Weitere Informationen finden Sie unter HINTERNET Handles.

Hinweis

WinINet unterstützt keine Serverimplementierungen. Darüber hinaus sollte es nicht von einem Dienst aus verwendet werden. Verwenden Sie für Serverimplementierungen oder Dienste Microsoft Windows HTTP Services (WinHTTP).