Partager via


Gestion des localisateurs de ressources uniformes

Une URL (Uniform Resource Locator) est une représentation compacte de l’emplacement et de la méthode d’accès d’une ressource située sur Internet. Chaque URL se compose d’un schéma (HTTP, HTTPS ou FTP) et d’une chaîne spécifique au schéma. Cette chaîne peut également inclure une combinaison d’un chemin d’accès au répertoire, d’une chaîne de recherche ou d’un nom de la ressource. Les fonctions WinINet permettent de créer, combiner, décomposer et canoniser des URL. Pour plus d’informations sur les URL, consultez RFC-1738 on Uniform Resource Locators (URL).

Les fonctions d’URL fonctionnent de manière orientée tâches. Le contenu et le format de l’URL donnée à la fonction ne sont pas vérifiés. L’application appelante doit suivre l’utilisation de ces fonctions pour s’assurer que les données sont au format prévu. Par exemple, la fonction InternetCanonicalizeUrl convertit le caractère « % » en séquence d’échappement « %25 » lorsque vous n’utilisez aucun indicateur. Si InternetCanonicalizeUrl est utilisé sur l’URL canonique, la séquence d’échappement « %25 » est convertie en séquence d’échappement « %2525 », qui ne fonctionne pas correctement.

Qu’est-ce qu’une URL canonique ?

Le format de toutes les URL doit suivre la syntaxe et la sémantique acceptées pour accéder aux ressources via Internet. La canonisation est le processus de mise en forme d’une URL pour suivre cette syntaxe et cette sémantique acceptées.

Les caractères qui doivent être encodés incluent tous les caractères qui n’ont aucun caractère graphique correspondant dans le jeu de caractères codés US-ASCII (hexadécimal 80-FF, qui ne sont pas utilisés dans le jeu de caractères codés US-ASCII, et hexadécimaux 00-1F et 7F, qui sont des caractères de contrôle), des espaces vides, « % » (qui est utilisé pour encoder d’autres caractères) et des caractères non sécurisés (<, >, « , #, {, }, |, \, ^, ~, [, ] et ').

Utilisation des fonctions WinINet pour gérer les URL

Le tableau suivant récapitule les fonctions d’URL.

Fonction Description
InternetCanonicalizeUrl Canonique l’URL.
InternetCombineUrl Combine des URL de base et relatives.
InternetCrackUrl Analyse une chaîne d’URL dans des composants.
InternetCreateUrl Crée une chaîne d’URL à partir de composants.
InternetOpenUrl Commence la récupération d’une ressource FTP, HTTP ou HTTPS.

 

Canonisation des URL

La canonisation d’une URL est le processus qui convertit une URL, qui peut contenir des caractères non sécurisés tels que des espaces vides, des caractères réservés, etc., dans un format accepté.

La fonction InternetCanonicalizeUrl peut être utilisée pour canoniser les URL. Cette fonction étant très orientée tâches, l’application doit suivre son utilisation avec soin. InternetCanonicalizeUrl ne vérifie pas que l’URL qui lui est passée est déjà canonique et que l’URL qu’il retourne est valide.

Les cinq indicateurs suivants contrôlent la façon dont InternetCanonicalizeUrl gère une URL particulière. Les indicateurs peuvent être utilisés en combinaison. Si aucun indicateur n’est utilisé, la fonction encode l’URL par défaut.

Valeur Signification
ICU_BROWSER_MODE N’encodez pas ou ne décodez pas les caractères après « # » ou « ? », et ne supprimez pas les espaces blancs de fin après « ? ». Si cette valeur n’est pas spécifiée, l’URL entière est encodée et l’espace blanc de fin est supprimé.
ICU_DECODE Convertissez toutes les séquences %XX en caractères, y compris les séquences d’échappement, avant l’analyse de l’URL.
ICU_ENCODE_SPACES_ONLY Encoder des espaces uniquement.
ICU_NO_ENCODE Ne convertissez pas les caractères non sécurisés en séquences d’échappement.
ICU_NO_META Ne supprimez pas les séquences méta (telles que « » et « . . ») de l’URL.

 

L’indicateur ICU_DECODE doit être utilisé uniquement sur les URL canoniques, car il suppose que toutes les séquences %XX sont des codes d’échappement et les convertit en caractères indiqués par le code. Si l’URL contient un symbole « % » qui ne fait pas partie d’un code d’échappement, ICU_DECODE la traite toujours comme un. Cette caractéristique peut entraîner la création d’une URL non valide par InternetCanonicalizeUrl .

Pour utiliser InternetCanonicalizeUrl pour retourner une URL entièrement décodée, les indicateurs ICU_DECODE et ICU_NO_ENCODE doivent être spécifiés. Cette configuration suppose que l’URL passée à InternetCanonicalizeUrl a été précédemment canonisée.

Combinaison d’URL de base et d’URL relatives

Une URL relative est une représentation compacte de l’emplacement d’une ressource par rapport à une URL de base absolue. L’URL de base doit être connue de l’analyseur et inclut généralement le schéma, l’emplacement réseau et des parties du chemin d’URL. Une application peut appeler InternetCombineUrl pour combiner l’URL relative avec son URL de base. InternetCombineUrl canonise également l’URL résultante.

URL de fissuration

La fonction InternetCrackUrl sépare une URL en ses composants et retourne les composants indiqués par la structure URL_COMPONENTS qui est passée à la fonction.

Les composants qui composent la structure URL_COMPONENTS sont le numéro de schéma, le nom d’hôte, le numéro de port, le nom d’utilisateur, le mot de passe, le chemin d’URL et des informations supplémentaires (telles que les paramètres de recherche). Chaque composant, à l’exception du schéma et des numéros de port, a un membre de chaîne qui contient les informations et un membre qui contient la longueur du membre de chaîne. Le schéma et les numéros de port ont uniquement un membre qui stocke la valeur correspondante ; ils sont tous deux retournés sur tous les appels réussis à InternetCrackUrl.

Pour obtenir la valeur d’un composant particulier dans la structure URL_COMPONENTS , le membre qui stocke la longueur de chaîne de ce composant doit être défini sur une valeur différente de zéro. Le membre de chaîne peut être l’adresse d’une mémoire tampon ou NULL.

Si le membre pointeur contient l’adresse d’une mémoire tampon, le membre de longueur de chaîne doit contenir la taille de cette mémoire tampon. InternetCrackUrl retourne les informations de composant sous la forme d’une chaîne dans la mémoire tampon et stocke la longueur de chaîne dans le membre de longueur de chaîne.

Si le membre pointeur est NULL, le membre de longueur de chaîne peut être défini sur n’importe quelle valeur différente de zéro. InternetCrackUrl stocke l’adresse du premier caractère de la chaîne d’URL qui contient les informations du composant et définit la longueur de chaîne sur le nombre de caractères dans la partie restante de la chaîne d’URL qui se rapporte au composant.

Tous les membres pointeurs définis sur NULL avec un membre de longueur différente de zéro pointent vers le point de départ approprié dans la chaîne d’URL. La longueur stockée dans le membre de longueur doit être utilisée pour déterminer la fin des informations du composant individuel.

Pour terminer correctement l’initialisation de la structure URL_COMPONENTS , le membre dwStructSize doit être défini sur la taille de la structure URL_COMPONENTS , en octets.

L’exemple suivant retourne les composants de l’URL dans la zone d’édition, IDC_PreOpen1 et retourne les composants à la zone de liste, IDC_PreOpenList. Pour afficher uniquement les informations d’un composant individuel, cette fonction copie le caractère immédiatement après les informations du composant dans la chaîne et le remplace temporairement par une valeur 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 );
}

Création d’URL

La fonction InternetCreateUrl utilise les informations de la structure URL_COMPONENTS pour créer un localisateur de ressources uniformes.

Les composants qui composent la structure URL_COMPONENTS sont le schéma, le nom d’hôte, le numéro de port, le nom d’utilisateur, le mot de passe, le chemin d’URL et des informations supplémentaires (telles que les paramètres de recherche). Chaque composant, à l’exception du numéro de port, a un membre de chaîne qui contient les informations et un membre qui contient la longueur du membre de chaîne.

Pour chaque composant requis, le membre du pointeur doit contenir l’adresse de la mémoire tampon contenant les informations. Le membre de longueur doit être défini sur zéro si le membre pointeur contient l’adresse d’une chaîne terminée à zéro ; le membre de longueur doit être défini sur la longueur de chaîne si le membre pointeur contient l’adresse d’une chaîne qui n’est pas terminée à zéro. Le membre pointeur de tous les composants qui ne sont pas requis doit être NULL.

Accès direct aux URL

Les ressources FTP et HTTP sur Internet sont accessibles directement à l’aide des fonctions InternetOpenUrl, InternetReadFile et InternetFindNextFile . InternetOpenUrl ouvre une connexion à la ressource à l’URL passée à la fonction . Lorsque cette connexion est établie, il existe deux étapes possibles. Tout d’abord, si la ressource est un fichier, InternetReadFile peut le télécharger ; deuxièmement, si la ressource est un répertoire, InternetFindNextFile peut énumérer les fichiers dans le répertoire (sauf lors de l’utilisation de proxys CERN). Pour plus d’informations sur InternetReadFile, consultez Lecture de fichiers. Pour plus d’informations sur InternetFindNextFile, consultez Recherche du fichier suivant.

Pour les applications qui doivent fonctionner via un proxy CERN, InternetOpenUrl peut être utilisé pour accéder aux répertoires et fichiers FTP. Les requêtes FTP sont empaquetées pour ressembler à une requête HTTP, ce que le proxy CERN accepterait.

InternetOpenUrl utilise le handle HINTERNET créé par la fonction InternetOpen et l’URL de la ressource. L’URL doit inclure le schéma (http:, ftp:, fichier : [pour un fichier local] ou https : [pour la sécurisation du protocole hypertexte]) et l’emplacement réseau (par www.microsoft.comexemple ). L’URL peut également inclure un chemin d’accès (par exemple, /isapi/gomscom.asp ? TARGET=/windows/feature/) et nom de la ressource (par exemple, default.htm). Pour les requêtes HTTP ou HTTPS, des en-têtes supplémentaires peuvent être inclus.

InternetQueryDataAvailable, InternetFindNextFile, InternetReadFile et InternetSetFilePointer (URL HTTP ou HTTPS uniquement) peuvent utiliser le handle créé par InternetOpenUrl pour télécharger la ressource.

Le diagramme suivant illustre les handles à utiliser avec chaque fonction.

handles à utiliser avec des fonctions

Le handle HINTERNET racine créé par InternetOpen est utilisé par InternetOpenUrl. Le handle HINTERNET créé par InternetOpenUrl peut être utilisé par InternetQueryDataAvailable, InternetReadFile, InternetFindNextFile (non indiqué ici) et InternetSetFilePointer (URL HTTP ou HTTPS uniquement).

Pour plus d’informations, consultez Handles HINTERNET.

Notes

WinINet ne prend pas en charge les implémentations de serveur. En outre, il ne doit pas être utilisé à partir d’un service. Pour les implémentations de serveur ou les services, utilisez Microsoft Windows HTTP Services (WinHTTP).