protocolo - Encabezados HTTP personalizados: convenciones de nombres
http para dummies (6)
Varios de nuestros usuarios nos han pedido que incluyamos datos relativos a su cuenta en los encabezados HTTP de las solicitudes que les enviamos, o incluso las respuestas que reciben de nuestra API. ¿Cuál es la convención general para agregar encabezados HTTP personalizados, en términos de denominación , formato , etc.?
Además, siéntase libre de publicar cualquier uso inteligente de estos que haya encontrado en la web; Estamos tratando de implementar esto usando lo mejor que hay como objetivo :)
El formato para los encabezados HTTP se define en la especificación HTTP. Voy a hablar sobre HTTP 1.1, para el que la especificación es RFC 2616 . En la sección 4.2, ''Encabezados de mensajes'', se define la estructura general de un encabezado:
message-header = field-name ":" [ field-value ]
field-name = token
field-value = *( field-content | LWS )
field-content = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, separators, and quoted-string>
Esta definición se basa en dos pilares principales, token y TEXT. Ambos se definen en la sección 2.2, ''Reglas básicas''. El token es:
token = 1*<any CHAR except CTLs or separators>
A su vez descansa sobre CHAR, CTL y separadores:
CHAR = <any US-ASCII character (octets 0 - 127)>
CTL = <any US-ASCII control character
(octets 0 - 31) and DEL (127)>
separators = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "/" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
TEXTO es:
TEXT = <any OCTET except CTLs,
but including LWS>
Donde LWS es un espacio en blanco lineal, cuya definición no reproduciré, y OCTET es:
OCTET = <any 8-bit sequence of data>
Hay una nota que acompaña a la definición:
The TEXT rule is only used for descriptive field contents and values
that are not intended to be interpreted by the message parser. Words
of *TEXT MAY contain characters from character sets other than ISO-
8859-1 [22] only when encoded according to the rules of RFC 2047
[14].
Entonces, dos conclusiones. En primer lugar, está claro que el nombre del encabezado debe estar compuesto de un subconjunto de caracteres ASCII: alfanuméricos, algunos signos de puntuación, no mucho más. En segundo lugar, no hay nada en la definición de un valor de encabezado que lo restrinja a ASCII o excluya los caracteres de 8 bits: está compuesto explícitamente de octetos, con solo los caracteres de control bloqueados (tenga en cuenta que CR y LF se consideran controles). Además, el comentario sobre la producción de TEXTO implica que los octetos deben interpretarse como que están en ISO-8859-1, y que existe un mecanismo de codificación (que es horrible, por cierto) para representar caracteres fuera de esa codificación.
Entonces, para responder a @BalusC en particular, es bastante claro que de acuerdo con la especificación, los valores de encabezado están en ISO-8859-1. He enviado caracteres altos-8859-1 (específicamente, algunas vocales acentuadas como se usan en francés) en un encabezado de Tomcat, y Firefox las interpretó correctamente, por lo que hasta cierto punto, esto funciona tanto en la práctica como en la teoría. (aunque este era un encabezado de ubicación, que contiene una URL, y estos caracteres no son legales en las URL, por lo que en realidad era ilegal, ¡pero bajo una regla diferente!).
Dicho esto, no confiaría en que ISO-8859-1 funcionara en todos los servidores, proxies y clientes, por lo que me atendría a ASCII como una cuestión de programación defensiva.
El registro del nombre del campo del encabezado se define en RFC3864 , y no hay nada especial con "X-".
Por lo que puedo decir, no hay pautas para los encabezados privados; En caso de duda, evítalos. O eche un vistazo al marco de extensión HTTP ( RFC 2774 ).
Sería interesante entender más del caso de uso; ¿Por qué no se puede agregar la información al cuerpo del mensaje?
En junio de 2012, la desestimación de la recomendación de usar el prefijo "X-" se convirtió en oficial como RFC 6648 . A continuación se presentan citas de relevancia:
3. Recomendaciones para los creadores de nuevos parámetros.
...
- NO DEBE prefijar sus nombres de parámetros con "X-" o construcciones similares.
4. Recomendaciones para diseñadores de protocolos.
...
NO DEBE prohibir que se registren los parámetros con un prefijo "X-" o construcciones similares.
NO DEBE estipular que un parámetro con un prefijo "X-" o construcciones similares deba entenderse como no estandarizado.
NO DEBE estipular que un parámetro sin un prefijo "X-" o construcciones similares debe entenderse como estandarizado.
Tenga en cuenta que "NO DEBE" ("desalentado") no es lo mismo que "NO DEBE" ("prohibido"), consulte también RFC 2119 para otra especificación sobre esas palabras clave. En otras palabras, puede seguir usando los encabezados con el prefijo "X-", pero no se recomienda y no puede documentarlos como si fueran estándares públicos.
En junio de 2011, se publicó el primer borrador de IETF para desaprobar la recomendación de usar el prefijo "X-" para encabezados no estándar. La razón es que cuando los encabezados no estándar con el prefijo "X-" se convierten en estándar, al eliminar el prefijo "X-" se rompe la compatibilidad hacia atrás, lo que obliga a los protocolos de aplicación a admitir ambos nombres (por ejemplo, x-gzip
y gzip
ahora son equivalentes). Entonces, la recomendación es simplemente nombrarlos con sensatez sin el prefijo "X-".
La recomendación fue comenzar su nombre con "X-". Por ejemplo, X-Forwarded-For
, X-Requested-With
. Esto también se menciona en la sección 5 de RFC 2047 .
La pregunta lleva a releer. La pregunta real no es similar a los prefijos de proveedores en las propiedades de CSS, donde es apropiado realizar pruebas de futuro y pensar en el soporte de proveedores y en los estándares oficiales. La pregunta real que se hace es más parecida a la elección de nombres de parámetros de consulta de URL A nadie le debe importar lo que sea. Pero el espacio entre los nombres de los personalizados es perfectamente válido, común y correcto.
Razón fundamental:
Se trata de convenciones entre desarrolladores para encabezados personalizados, específicos de la aplicación , " datos relevantes para su cuenta ", que no tienen nada que ver con proveedores, organismos de estándares o protocolos que deben ser implementados por terceros, excepto que el desarrollador en cuestión simplemente debe evitar los nombres de encabezados que puedan tener otro uso previsto para servidores, servidores proxy o clientes. Por esta razón, los ejemplos de "X-Gzip / Gzip" y "X-Forwarded-For / Forwarded-For" son discutibles. La pregunta planteada es acerca de las convenciones en el contexto de una API privada, similar a las convenciones de nombres de parámetros de consulta de URL. Es una cuestión de preferencia y espacio entre los nombres; las preocupaciones acerca de que "X-ClientDataFoo" sea compatible con cualquier proxy o proveedor sin la "X" están claramente fuera de lugar.
No hay nada especial o mágico en el prefijo "X-", pero ayuda a aclarar que es un encabezado personalizado. De hecho, RFC-6648 y otros ayudan a reforzar el caso para el uso de un prefijo "X-", ya que, a medida que los proveedores de clientes y servidores HTTP abandonan el prefijo: su API privada, específica de la aplicación, datos personales el mecanismo de aprobación se está aislando aún mejor contra las colisiones de espacio de nombres con el pequeño número de nombres de encabezados reservados oficiales. Dicho esto, mi preferencia y recomendación personal es ir un paso más allá y hacer, por ejemplo, "X-ACME-ClientDataFoo" (si su compañía de widgets es "ACME").
En mi humilde opinión, la especificación IETF no es lo suficientemente específica para responder a la pregunta del OP, porque no distingue entre casos de uso completamente diferentes: (A) los proveedores que presentan nuevas características de aplicación global como "Forwarded-For" por un lado, vs. (B) los desarrolladores de aplicaciones que pasan cadenas específicas de la aplicación a / desde el cliente y el servidor. La especificación solo se refiere a la primera, (A). La pregunta aquí es si hay convenciones para (B). Existen. Implican agrupar los parámetros alfabéticamente y separarlos de los muchos encabezados de tipo (A) relevantes para los estándares. El uso del prefijo "X-" o "X-ACME-" es conveniente y legítimo para (B), y no está en conflicto con (A). Cuantos más vendedores dejen de usar "X-" para (A), más claramente se distinguirán los (B).
Ejemplo:
Google (que tiene un poco de peso en los diversos organismos de estándares) es, a partir de hoy, 20141102 en esta ligera edición a mi respuesta, actualmente usa "X-Mod-Pagespeed" para indicar la versión de su módulo Apache involucrado en transformando una respuesta dada. ¿Alguien realmente está sugiriendo que Google debería usar "Mod-Pagespeed", sin la "X-", y / o pedirle al IETF que bendiga su uso?
Resumen:
Si está utilizando encabezados HTTP personalizados (como una alternativa a veces apropiada para las cookies) dentro de su aplicación para pasar datos a / desde su servidor, y estos encabezados, explícitamente, NO están destinados a ser utilizados fuera del contexto de su aplicación. separarlos con un prefijo "X-" o "X-FOO-" es una convención razonable y común.
Modificar, o más correctamente, agregar encabezados HTTP adicionales es una excelente herramienta de depuración de código, si no otra cosa.
Cuando una solicitud de URL devuelve una redirección o una imagen, no hay una "página" html para escribir temporalmente los resultados del código de depuración, al menos no una que esté visible en un navegador.
Un enfoque es escribir los datos en un archivo de registro local y ver ese archivo más adelante. Otra es agregar temporalmente encabezados HTTP que reflejen los datos y las variables que se están depurando.
Regularmente agrego encabezados HTTP adicionales como X-fubar-somevar: o X-testing-someresult: para probar cosas, y he encontrado muchos errores que de otro modo habrían sido muy difíciles de rastrear.
RFC6648 recomienda que asuma que su encabezado personalizado "podría volverse estandarizado, público, comúnmente implementado o utilizable en múltiples implementaciones". Por lo tanto, recomienda no prefijarlo con "X-" o construcciones similares.
Sin embargo, hay una excepción "cuando es extremadamente improbable que [su encabezado] alguna vez se estandarice". Para dichos encabezados de "implementación específica y uso privado", el RFC indica que un espacio de nombres como un prefijo de proveedor está justificado.