type - protocolo http cabeceras




Encabezados HTTP personalizados: convenciones de nombres (4)

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?


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.





http-headers