2010-07-08 13 views
9

Per MSDN¿HttpUtility.UrlEncode coincide con la especificación de 'x-www-form-urlencoded'?

URLEncode convierte los caracteres de la siguiente manera:

  • espacios se convierten() para signos más (+).
  • Los caracteres no alfanuméricos se escapan a su representación hexadecimal.

que es similar, pero no exactamente lo mismo que W3C

application/x-www-form-urlencoded

Este es el tipo de contenido predeterminado. Los formularios enviados con este tipo de contenido se deben codificar de la siguiente manera:

  1. Se han escapado los nombres de control y los valores. Los caracteres de espacio se sustituyen por caracteres '+' y, a continuación reservados se evitan como se describe en RFC1738, sección 2.2: no alfanuméricos caracteres se sustituyen por '% HH', una señal ciento y dos dígitos hexadecimales que representan el Código ASCII de el personaje. Los saltos de línea son representados como pares "CR LF" (es decir, '% 0D% 0A').

  2. Los nombres/valores de control se enumeran en el orden en que aparecen en el documento . El nombre está separado de el valor por '=' y los pares de nombre/valor están separados el uno del otro por '&'.

 

Mi pregunta es, ¿alguien ha hecho el trabajo para determinar si URLEncode produce datos urlencoded forma www-x-válidos?

Respuesta

5

Bueno, la documentación que ha vinculado es para IIS 6 Server.UrlEncode, pero su título parece preguntar acerca de .NET System.Web.HttpUtility.UrlEncode. Usando una herramienta como Reflector, podemos ver la implementación de este último y determinar si cumple con la especificación W3C.

Aquí está la rutina de codificación que finalmente se llama (nota, se define para una matriz de bytes, y otras sobrecargas que toman cadenas finalmente convierten esas cadenas en matrices de bytes y llaman a este método). Llamarías esto para cada nombre y valor de control (para evitar el escape de los caracteres reservados = & utilizados como separadores).

protected internal virtual byte[] UrlEncode(byte[] bytes, int offset, int count) 
{ 
    if (!ValidateUrlEncodingParameters(bytes, offset, count)) 
    { 
     return null; 
    } 
    int num = 0; 
    int num2 = 0; 
    for (int i = 0; i < count; i++) 
    { 
     char ch = (char) bytes[offset + i]; 
     if (ch == ' ') 
     { 
      num++; 
     } 
     else if (!HttpEncoderUtility.IsUrlSafeChar(ch)) 
     { 
      num2++; 
     } 
    } 
    if ((num == 0) && (num2 == 0)) 
    { 
     return bytes; 
    } 
    byte[] buffer = new byte[count + (num2 * 2)]; 
    int num4 = 0; 
    for (int j = 0; j < count; j++) 
    { 
     byte num6 = bytes[offset + j]; 
     char ch2 = (char) num6; 
     if (HttpEncoderUtility.IsUrlSafeChar(ch2)) 
     { 
      buffer[num4++] = num6; 
     } 
     else if (ch2 == ' ') 
     { 
      buffer[num4++] = 0x2b; 
     } 
     else 
     { 
      buffer[num4++] = 0x25; 
      buffer[num4++] = (byte) HttpEncoderUtility.IntToHex((num6 >> 4) & 15); 
      buffer[num4++] = (byte) HttpEncoderUtility.IntToHex(num6 & 15); 
     } 
    } 
    return buffer; 
} 

public static bool IsUrlSafeChar(char ch) 
{ 
    if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) || ((ch >= '0') && (ch <= '9'))) 
    { 
     return true; 
    } 
    switch (ch) 
    { 
     case '(': 
     case ')': 
     case '*': 
     case '-': 
     case '.': 
     case '_': 
     case '!': 
      return true; 
    } 
    return false; 
} 

La primera parte de los recuentos de rutina el número de caracteres que necesitan ser reemplazados (espacios y caracteres no seguros URL).La segunda parte de la rutina asigna un nuevo buffer y realiza sustituciones:

  1. Url caracteres seguros se mantienen lo es: a-z A-Z 0-9()*-._!
  2. Los espacios se convierten en signos más
  3. Todos los demás caracteres se convierten en %HH

estados RFC1738 (énfasis mío):

Así, sólo ALPHANUM erics, los caracteres especiales "$ -_. +! * '()," y
caracteres reservados utilizados para sus fines reservados pueden ser utilizados
sin codificar dentro de una URL.

Por otra parte, los caracteres que no son necesarios para codificar
(incluyendo caracteres alfanuméricos) puede ser codificada dentro de la
parte específica del esquema de una dirección URL, siempre y cuando no están siendo utilizados para una reservada
propósito.

El conjunto de caracteres Url Safe permitidos por UrlEncode es un subconjunto de los caracteres especiales definidos en RFC1738. A saber, los caracteres $, faltan y serán codificados por UrlEncode incluso cuando la especificación dice que son seguros. Dado que puede usarse sin codificar (y no debe), aún cumple con la especificación para codificarlos (y el segundo párrafo lo establece explícitamente).

Con respecto a los saltos de línea, si la entrada tiene una secuencia CR LF, se escapará %0D%0A. Sin embargo, si la entrada tiene solo LF, se escapará %0A (por lo que no hay normalización de saltos de línea en esta rutina).

línea de base: cumple la especificación mientras que, además codifica $,, y la persona que llama es responsable de proporcionar los saltos de línea adecuadamente normalizados en la entrada.

+1

¡Excelente respuesta! Yo diría que la codificación de salto de línea no cumple técnicamente con la especificación, pero para fines prácticos está lo suficientemente cerca. – hemp

Cuestiones relacionadas