Share via


Control de localizadores uniformes de recursos

Un localizador uniforme de recursos (URL) es una representación compacta de la ubicación y el método de acceso para un recurso ubicado en Internet. Cada dirección URL consta de un esquema (HTTP, HTTPS o FTP) y una cadena específica del esquema. Esta cadena también puede incluir una combinación de una ruta de acceso de directorio, una cadena de búsqueda o un nombre del recurso. Las funciones winINet proporcionan la capacidad de crear, combinar, desglosar y canónicamente las direcciones URL. Para obtener más información sobre las direcciones URL, consulte RFC-1738 en localizadores uniformes de recursos (URL).

Las funciones de dirección URL funcionan de forma orientada a tareas. No se comprueba el contenido y el formato de la dirección URL que se asigna a la función. La aplicación que realiza la llamada debe realizar un seguimiento del uso de estas funciones para asegurarse de que los datos están en el formato previsto. Por ejemplo, la función InternetCanonicalizeUrl convierte el carácter "%" en la secuencia de escape "%25" cuando no se usan marcas. Si InternetCanonicalizeUrl se usa en la dirección URL canónica, la secuencia de escape "%25" se convertirá en la secuencia de escape "%2525", que no funcionaría correctamente.

¿Qué es una dirección URL canónica?

El formato de todas las direcciones URL debe seguir la sintaxis y la semántica aceptadas para acceder a los recursos a través de Internet. La canónica es el proceso de dar formato a una dirección URL para seguir esta sintaxis y semántica aceptadas.

Los caracteres que se deben codificar incluyen los caracteres que no tengan ningún carácter gráfico correspondiente en el juego de caracteres codificados US-ASCII (hexadecimal 80-FF, que no se usan en el juego de caracteres codificados US-ASCII y hexadecimal 00-1F y 7F, que son caracteres de control), espacios en blanco, "%" (que se usa para codificar otros caracteres) y caracteres no seguros (<, >, , ", ", {, }, |, \, ^, ~, [, ] y ').

Uso de las funciones de WinINet para controlar direcciones URL

En la tabla siguiente se resumen las funciones de dirección URL.

Función Descripción
InternetCanonicalizeUrl Canónicamente la dirección URL.
InternetCombineUrl Combina direcciones URL base y relativas.
InternetCrackUrl Analiza una cadena de dirección URL en componentes.
InternetCreateUrl Crea una cadena de dirección URL a partir de componentes.
InternetOpenUrl Comienza a recuperar un recurso FTP, HTTP o HTTPS.

 

Canónico de direcciones URL

La canónica de una dirección URL es el proceso que convierte una dirección URL, que puede contener caracteres no seguros, como espacios en blanco, caracteres reservados, etc., en un formato aceptado.

La función InternetCanonicalizeUrl se puede usar para canónicor las direcciones URL. Esta función está muy orientada a tareas, por lo que la aplicación debe realizar un seguimiento de su uso con cuidado. InternetCanonicalizeUrl no comprueba que la dirección URL que se le pasa ya esté canónica y que la dirección URL que devuelve sea válida.

Las cinco marcas siguientes controlan cómo InternetCanonicalizeUrl controla una dirección URL determinada. Las marcas se pueden usar en combinación. Si no se usan marcas, la función codifica la dirección URL de forma predeterminada.

Value Significado
ICU_BROWSER_MODE No codifique ni descodifique caracteres después de "#" o "?", y no quite el espacio en blanco final después de "?". Si no se especifica este valor, se codifica toda la dirección URL y se quita el espacio en blanco final.
ICU_DECODE Convierta todas las secuencias %XX en caracteres, incluidas las secuencias de escape, antes de analizar la dirección URL.
ICU_ENCODE_SPACES_ONLY Codificar solo espacios.
ICU_NO_ENCODE No convierta caracteres no seguros en secuencias de escape.
ICU_NO_META No quite las secuencias meta (como "." y "..") de la dirección URL.

 

La marca ICU_DECODE solo se debe usar en direcciones URL canónicas, ya que supone que todas las secuencias %XX son códigos de escape y las convierte en los caracteres indicados por el código. Si la dirección URL tiene un símbolo "%" en él que no forma parte de un código de escape, ICU_DECODE todavía lo trata como uno. Esta característica puede provocar que InternetCanonicalizeUrl cree una dirección URL no válida.

Para usar InternetCanonicalizeUrl para devolver una dirección URL completamente descodificada, se deben especificar las marcas ICU_DECODE y ICU_NO_ENCODE. Esta configuración supone que la dirección URL que se pasa a InternetCanonicalizeUrl se ha canónico previamente.

Combinación de direcciones URL base y relativas

Una dirección URL relativa es una representación compacta de la ubicación de un recurso en relación con una dirección URL base absoluta. La dirección URL base debe conocerse al analizador y normalmente incluye el esquema, la ubicación de red y las partes de la ruta de acceso url. Una aplicación puede llamar a InternetCombineUrl para combinar la dirección URL relativa con su dirección URL base. InternetCombineUrl también canónicamente la dirección URL resultante.

Descifrado de direcciones URL

La función InternetCrackUrl separa una dirección URL en sus partes de componente y devuelve los componentes indicados por la estructura URL_COMPONENTS que se pasa a la función.

Los componentes que componen la estructura URL_COMPONENTS son el número de esquema, el nombre de host, el número de puerto, el nombre de usuario, la contraseña, la ruta de acceso url y la información adicional (como los parámetros de búsqueda). Cada componente, excepto el esquema y los números de puerto, tiene un miembro de cadena que contiene la información y un miembro que contiene la longitud del miembro de cadena. Los números de esquema y puerto solo tienen un miembro que almacena el valor correspondiente; ambos se devuelven en todas las llamadas correctas a InternetCrackUrl.

Para obtener el valor de un componente determinado en la estructura URL_COMPONENTS , el miembro que almacena la longitud de cadena de ese componente debe establecerse en un valor distinto de cero. El miembro de cadena puede ser la dirección de un búfer o NULL.

Si el miembro del puntero contiene la dirección de un búfer, el miembro de longitud de cadena debe contener el tamaño de ese búfer. InternetCrackUrl devuelve la información del componente como una cadena en el búfer y almacena la longitud de la cadena en el miembro de longitud de cadena.

Si el miembro del puntero es NULL, el miembro de longitud de cadena se puede establecer en cualquier valor distinto de cero. InternetCrackUrl almacena la dirección del primer carácter de la cadena de dirección URL que contiene la información del componente y establece la longitud de la cadena en el número de caracteres de la parte restante de la cadena de dirección URL que pertenece al componente.

Todos los miembros del puntero establecidos en NULL con un punto de miembro de longitud distinto de cero al punto inicial adecuado en la cadena de dirección URL. La longitud almacenada en el miembro length debe usarse para determinar el final de la información del componente individual.

Para terminar de inicializar correctamente la estructura URL_COMPONENTS , el miembro dwStructSize debe establecerse en el tamaño de la estructura URL_COMPONENTS , en bytes.

En el ejemplo siguiente se devuelven los componentes de la dirección URL en el cuadro de edición, IDC_PreOpen1 y se devuelven los componentes al cuadro de lista, IDC_PreOpenList. Para mostrar solo la información de un componente individual, esta función copia el carácter inmediatamente después de la información del componente en la cadena y lo reemplaza temporalmente por un valor 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 );
}

Creación de direcciones URL

La función InternetCreateUrl usa la información de la estructura URL_COMPONENTS para crear un localizador uniforme de recursos.

Los componentes que componen la estructura de URL_COMPONENTS son el esquema, el nombre de host, el número de puerto, el nombre de usuario, la contraseña, la ruta de acceso url y la información adicional (como los parámetros de búsqueda). Cada componente, excepto el número de puerto, tiene un miembro de cadena que contiene la información y un miembro que contiene la longitud del miembro de cadena.

Para cada componente necesario, el miembro de puntero debe contener la dirección del búfer que contiene la información. El miembro length debe establecerse en cero si el miembro de puntero contiene la dirección de una cadena terminada en cero; el miembro length debe establecerse en la longitud de cadena si el miembro del puntero contiene la dirección de una cadena que no está terminada en cero. El miembro de puntero de cualquier componente que no sea necesario debe ser NULL.

Acceso directo a las direcciones URL

Se puede acceder directamente a los recursos FTP y HTTP en Internet mediante las funciones InternetOpenUrl, InternetReadFile e InternetFindNextFile . InternetOpenUrl abre una conexión al recurso en la dirección URL que se pasa a la función. Cuando se realiza esta conexión, hay dos pasos posibles. En primer lugar, si el recurso es un archivo, InternetReadFile puede descargarlo; en segundo lugar, si el recurso es un directorio, InternetFindNextFile puede enumerar los archivos dentro del directorio (excepto cuando se usan servidores proxy CERN). Para obtener más información sobre InternetReadFile, vea Leer archivos. Para obtener más información sobre InternetFindNextFile, vea Buscar el siguiente archivo.

En el caso de las aplicaciones que necesitan operar a través de un proxy CERN, InternetOpenUrl se puede usar para acceder a los directorios y archivos FTP. Las solicitudes FTP se empaquetan para que aparezcan como una solicitud HTTP, que el proxy CERN aceptaría.

InternetOpenUrl usa el identificador HINTERNET creado por la función InternetOpen y la dirección URL del recurso. La dirección URL debe incluir el esquema (http:, ftp:, archivo: [para un archivo local] o https: [para el protocolo de hipertexto seguro]) y la ubicación de red (como www.microsoft.com). La dirección URL también puede incluir una ruta de acceso (por ejemplo, /isapi/gomscom.asp? TARGET=/windows/feature/) y nombre de recurso (por ejemplo, default.htm). En el caso de las solicitudes HTTP o HTTPS, se pueden incluir encabezados adicionales.

InternetQueryDataAvailable, InternetFindNextFile, InternetReadFile e InternetSetFilePointer (solo direcciones URL HTTP o HTTPS) pueden usar el identificador creado por InternetOpenUrl para descargar el recurso.

En el diagrama siguiente se muestran los identificadores que se van a usar con cada función.

identificadores para usar con funciones

InternetOpenl usa el identificador HINTERNET raíz creado por InternetOpen. El identificador HINTERNET creado por InternetOpenUrl puede ser utilizado por InternetQueryDataAvailable, InternetReadFile, InternetFindNextFile (no se muestra aquí) y InternetSetFilePointer (solo direcciones URL HTTP o HTTPS).

Para obtener más información, vea HINTERNET Handles(Identificadores de HINTERNET).

Nota:

WinINet no admite implementaciones de servidor. Además, no se debe usar desde un servicio. En el caso de las implementaciones de servidor o los servicios, use los servicios HTTP de Microsoft Windows (WinHTTP).