Compartir a través de


Localizadores uniformes de recursos (DIRECCIONES URL) en WinHTTP

Una dirección 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, FTP o Gopher) 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 de Servicios HTTP de Microsoft Windows (WinHTTP) proporcionan la capacidad de crear, combinar, desglosar y canónicamente las direcciones URL. Para más información, consulte RFC 1738, Localizadores uniformes de recursos y RFC 2396, Identificadores uniformes de recursos (URI): Sintaxis genérica.

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

La sintaxis y la semántica especificadas de las direcciones URL dejan espacio para la variación y el error. La canonización es el proceso de normalizar una dirección URL real en una forma correcta, estándar y "canónica".

Esto implica codificar algunos caracteres como "secuencias de escape". No es necesario codificar caracteres alfanuméricos US-ASCII (los dígitos 0-9, las letras mayúsculas A-Z y las letras minúsculas a-z). La mayoría de los demás caracteres deben tener escape, incluidos los caracteres de control, el carácter de espacio, el signo de porcentaje, "caracteres no seguros" ( <, >, ", # , {, }, |, \, ^, ~, [ , y ' ) y todos los caracteres con un punto de código superior a 127.

Uso de las funciones WinHTTP para controlar direcciones URL

WinHTTP proporciona dos funciones para controlar las direcciones URL. WinHttpCrackUrl separa una dirección URL en sus partes de componentes y WinHttpCreateUrl crea una dirección URL a partir de componentes.

Separación de direcciones URL

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

Los componentes que componen la estructura de 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; Tanto el esquema como los números de puerto se devuelven en todas las llamadas correctas a WinHttpCrackUrl.

Para recuperar 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 un puntero a un búfer o NULL.

Si el miembro del puntero contiene un puntero a un búfer, el miembro de longitud de cadena debe contener el tamaño de ese búfer. La función WinHttpCrackUrl 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 se establece en NULL, el miembro de longitud de cadena se puede establecer en cualquier valor distinto de cero. La función WinHttpCrackUrl almacena un puntero al 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 .

Creación de direcciones URL

La función WinHttpCreateUrl usa la información de la estructura de URL_COMPONENTS descrita anteriormente para crear una dirección URL.

Para cada componente necesario, el miembro de puntero debe contener un puntero al búfer que contiene la información. El miembro length debe establecerse en cero si el miembro del puntero contiene un puntero a una cadena terminada en cero; el miembro length debe establecerse en la longitud de cadena si el miembro del puntero contiene un puntero a una cadena que no está terminada en cero. El miembro de puntero de los componentes que no son necesarios debe establecerse en NULL.

Código de ejemplo

En el código de ejemplo siguiente se muestra cómo usar WinHttpCrackUrl y WinHttpCreateUrl para desensamblar una dirección URL existente, modificar uno de sus componentes y volver a ensamblarlo en una nueva dirección URL.

  URL_COMPONENTS urlComp;
  LPCWSTR pwszUrl1 = 
    L"https://search.msn.com/results.asp?RS=CHECKED&FORM=MSNH&v=1&q=wininet";
  DWORD dwUrlLen = 0;

  // Initialize the URL_COMPONENTS structure.
  ZeroMemory(&urlComp, sizeof(urlComp));
  urlComp.dwStructSize = sizeof(urlComp);

  // Set required component lengths to non-zero so that they are cracked.
  urlComp.dwSchemeLength    = (DWORD)-1;
  urlComp.dwHostNameLength  = (DWORD)-1;
  urlComp.dwUrlPathLength   = (DWORD)-1;
  urlComp.dwExtraInfoLength = (DWORD)-1;

  // Crack the URL.
  if( !WinHttpCrackUrl( pwszUrl1, (DWORD)wcslen(pwszUrl1), 0, &urlComp ) )
      printf( "Error %u in WinHttpCrackUrl.\n", GetLastError( ) );
  else
  {
    // Change the search information.  New info is the same length.
    urlComp.lpszExtraInfo = L"?RS=CHECKED&FORM=MSNH&v=1&q=winhttp";

    // Obtain the size of the new URL and allocate memory.
    WinHttpCreateUrl( &urlComp, 0, NULL, &dwUrlLen );
    LPWSTR pwszUrl2 = new WCHAR[dwUrlLen];

    // Create a new URL.
    if( !WinHttpCreateUrl( &urlComp, 0, pwszUrl2, &dwUrlLen ) )
      printf( "Error %u in WinHttpCreateUrl.\n", GetLastError( ) );
    else
    {
      // Show both URLs.
      printf( "Old URL:  %S\nNew URL:  %S\n", pwszUrl1, pwszUrl2 );
    }

    // Free allocated memory.
    delete [] pwszUrl2;
  }