CAPÍTULO 33 · PARTE III

HTTP: mensajes, semántica, estado y intermediarios

Cómo interpretar mensajes HTTP y separar framing, semántica, estado de aplicación, cachés e intermediarios, con controles para acotar claims sobre autorización, revalidación y discrepancias de parsing.

Nivel N2–N3 · Estado published

La misma petición puede tener varias interpretaciones válidas

Un cliente recibe 200 OK al solicitar /facturas/17, pero la factura que ve pertenece a otra cuenta. En otro caso, una petición POST alcanza un gateway, éste reintenta hacia el origen y el usuario observa un único botón pulsado dos veces. En un tercero, un CDN sirve una representación antigua aunque el origen ya haya cambiado. Ninguna de estas situaciones se explica diciendo sólo «HTTP funcionó» o «HTTP falló». Hay que separar el mensaje que se intercambió, la semántica que el protocolo atribuye a la operación, el estado que se conserva entre peticiones y los intermediarios que pudieron terminar o transformar cada tramo.

HTTP (Hypertext Transfer Protocol) define una interfaz uniforme para transferir representaciones de recursos. No define por sí solo la identidad de una persona, la autorización de una acción, la corrección del negocio ni la topología concreta de una aplicación. Este capítulo construye un modelo operativo de HTTP para leer requests, responses, fields, content, métodos, códigos de estado, cachés, cookies y proxies sin atribuir a una capa garantías que pertenecen a otra.

La semántica se trata separada del framing (delimitación y codificación de mensajes en una conexión). HTTP/1.1 usa una sintaxis textual y reglas de longitud y transferencia; HTTP/2 y HTTP/3 usan frames binarios, streams y mecanismos distintos de transporte. Esa diferencia cambia cómo se representan y encaminan los bytes, pero no convierte automáticamente un GET en otra operación ni hace que HTTPS cambie la semántica HTTP. Las traducciones entre versiones deben conservar la semántica aplicable y pueden introducir límites de implementación.

Comparación entre componentes observables de request/response y su significado semántico, con límites explícitos.
Mensaje, framing y semántica responden preguntas distintas.

Un status o field no prueba autorización ni negocio.

Pregunta rectora, alcance y resultados

La pregunta del capítulo es: ¿qué se puede afirmar sobre una operación HTTP a partir de sus mensajes, su estado y sus puntos de observación, y qué queda fuera de esa evidencia?

Al terminar, el lector debe poder:

Se presupone el modelo de capas, TCP, DNS y direccionamiento de los capítulos 25–32. Quedan fuera la especificación completa de TLS, los detalles de una aplicación concreta, las políticas de identidad de cada proveedor y la explotación contra sistemas de terceros.

Mensaje, semántica y framing son preguntas distintas

Un HTTP message es un request o un response. El request tiene una request-line en HTTP/1.1, fields y, cuando corresponde, content; el response tiene status-line, fields y content. RFC 9110 describe la semántica y la sintaxis común de mensajes en §§5–10, mientras RFC 9112 define el framing de HTTP/1.1 en §§6–6.3. Conviene mantener tres preguntas separadas:

  1. ¿Qué bytes o frames se recibieron? Es una cuestión de framing, transporte, parser y punto de captura.
  2. ¿Qué mensaje se pudo construir? Es una cuestión de sintaxis, campos obligatorios, target y reglas de la versión.
  3. ¿Qué significa la operación? Es la semántica de método, target, status, representación y estado de la aplicación.

En HTTP/1.1, un ejemplo sintético de request es:

GET /reports/17?view=summary HTTP/1.1
Host: portal.example.test
Accept: application/json
If-None-Match: "r17-v8"

La línea inicial contiene método, request-target y versión. Host identifica el host solicitado dentro del contexto del request; puede influir en el enrutamiento virtual, pero no es por sí solo una identidad autenticada del cliente ni del servicio. Accept expresa preferencias de representación; no obliga al servidor a producirlas. If-None-Match es una condición para reutilización o transferencia, no una credencial.

El response correspondiente podría ser:

HTTP/1.1 304 Not Modified
Date: Sun, 04 Oct 2026 14:00:00 GMT
ETag: "r17-v8"
Vary: Accept-Encoding

304 no es un error ni contiene la representación; indica, bajo las reglas de validación, que una caché puede reutilizar su copia. En otro momento, el mismo recurso podría responder 200 con Content-Type: application/json, Content-Length y content. El status y los fields describen el response; ninguno prueba que una operación de negocio haya sido autorizada o completada.

La terminología importa. Recurso es la abstracción identificada por un target y su contexto; representación es una forma transferida del estado o metadatos del recurso, con media type y codificación. Una representación JSON no es «el recurso» como objeto único. Dos representaciones —por ejemplo, JSON y HTML— pueden corresponder al mismo recurso; una respuesta puede no transferir content aunque refiera al recurso mediante Location o un status de redirección.

RFC 9110 separa fields generales, de request, de response y de representación. Un field no es una variable universal con significado fuera del contrato que lo define. Content-Type describe el media type del content; Content-Encoding describe codificaciones aplicadas; Authorization lleva credenciales según un esquema, pero la decisión de autorización la toma el servidor o un componente delegado. El significado de un field depende de su sintaxis, contexto y versión, no de que su nombre parezca autoexplicativo. RFC 9110, §§5–8

Del target al resultado: método, recurso y status

El request-target puede adoptar formas origin-form, absolute-form, authority-form o asterisk-form en HTTP/1.1 según el contexto; los proxies y métodos como CONNECT hacen que la forma sea material. La origin-form, como /reports/17, es habitual en requests dirigidos a un origen. En un proxy, la absolute-form puede incluir el URI completo. Confundir target con identidad del servidor lleva a errores: el nombre, la ruta y el campo Host participan en selección y semántica, pero no prueban que el peer de red sea el recurso lógico esperado. RFC 9112, §3; RFC 9110, §7

El método expresa la intención semántica de la petición. GET solicita una representación; HEAD solicita los metadatos que podría generar un GET, pero la respuesta no incluye content: el servidor debería enviar los mismos fields, aunque puede omitir algunos fields relacionados con el payload conforme a RFC 9110 §9.3.2. POST solicita que el recurso procese el content según su propia semántica; PUT solicita crear o reemplazar el estado de un recurso identificado por el target; DELETE solicita eliminar su asociación o estado según la semántica del recurso. Estas frases no son promesas de una aplicación concreta: la especificación deja precondiciones, autorización, validación y errores observables.

Safe no significa sin efectos

Un método safe es aquel cuyo propósito solicitado por el cliente es de sólo lectura u observación. RFC 9110 §9.2.1 aclara que el servidor puede registrar la petición, cobrar por una consulta, actualizar métricas o producir otros efectos laterales; lo que no debe hacer es atribuir al cliente una solicitud de cambio de estado cuando éste eligió un método safe. GET puede disparar analítica o trabajo de caché, y una aplicación defectuosa puede cambiar estado al procesarlo. Por eso «GET nunca causa efectos» es falso como afirmación operacional. El control profesional verifica la semántica realmente implementada y restringe acciones mutantes a métodos y autorización adecuados.

Idempotent describe el efecto intencional, no el número de intentos

Una petición es idempotent cuando varias peticiones idénticas tienen el mismo efecto intencional sobre el servidor que una sola, aunque cada respuesta o efecto incidental pueda diferir. RFC 9110 §9.2.2 define PUT, DELETE y los métodos safe como idempotentes por su semántica; POST no lo es por defecto. Un PUT que reemplaza un documento puede generar logs, métricas o una nueva marca de tiempo en cada intento sin cambiar el resultado intencional del recurso. Idempotencia tampoco garantiza que la operación sea autorizada, que el recurso exista o que un proxy reintente de forma segura.

Decir que «PUT siempre crea» también es incorrecto. Si el target identifica un recurso existente, puede reemplazarlo; si no existe y se cumplen condiciones, puede crearlo; la respuesta y la política del recurso determinan el resultado. Un DELETE repetido puede devolver 404 después del primer éxito y seguir siendo idempotente en el sentido de efecto solicitado. El cliente debe distinguir la propiedad de la operación de la clase de status obtenida.

Cacheable depende del método, status y reglas de caché

Cacheable no significa «todo cliente puede guardar todo response». RFC 9110 §9.2.3 identifica métodos cuyos responses pueden almacenarse bajo condiciones, y RFC 9111 establece requisitos de caché, freshness y validación. GET y HEAD tienen semántica cacheable en condiciones normales; POST puede ser cacheable cuando la respuesta y los fields lo permiten, pero no debe asumirse una caché automática. Authorization, Cache-Control: private o información específica del usuario pueden impedir reutilización compartida. Un response 200 puede ser no almacenable o inmediatamente stale; un 304 permite validar una copia previa, no convierte la operación en pública.

La tabla resume propiedades semánticas, no una política universal:

Desliza horizontalmente para consultar todas las columnas.

Propiedad Pregunta que responde Error frecuente
safe ¿El propósito solicitado es lectura/observación? «No hay ningún efecto lateral»
idempotent ¿Repetir la petición conserva el mismo efecto intencional? «La respuesta será idéntica»
cacheable ¿Puede almacenarse/reutilizarse el response bajo estas reglas? «Todo GET se comparte»

Status: resultado del protocolo, no certificado del negocio

El status code comunica una clase y una condición del response: 1xx informativo, 2xx éxito de la operación HTTP, 3xx redirección o acción adicional, 4xx error atribuido al request o a su contexto, y 5xx error del servidor. La clase ayuda a seleccionar tratamiento, pero no describe por sí sola si una orden fue aceptada, si una factura pertenece al usuario o si un pago quedó liquidado. Un servicio puede devolver 200 con {\"ok\":false} por un contrato heredado, y puede devolver 202 Accepted cuando sólo ha aceptado procesar asíncronamente, sin que la operación haya terminado. RFC 9110, §§15.1–15.6

El análisis debe conservar dos capas de resultado:

Por ejemplo, un 201 Created puede indicar que el servidor creó un recurso y devolver Location, pero la afirmación «la cuenta está activa» requiere el contrato de la aplicación y una observación posterior. Un 204 No Content no significa «sin cambios»; significa que el response no tiene content transferido en ese caso. Un 401 Unauthorized comunica un desafío o falta de credenciales válidas según el esquema, no una prueba de que el usuario sea malicioso; 403 Forbidden no identifica universalmente si la identidad se autenticó. El significado exacto debe leerse en la definición del status y en el contrato de la aplicación.

Representaciones y negociación

El servidor puede ofrecer distintas representaciones del mismo recurso. La negociación proactiva usa preferencias del request, como Accept, Accept-Language o Accept-Encoding, para seleccionar una representación antes de responder. La negociación reactiva puede devolver alternativas para que el agente elija. Ninguna forma convierte la preferencia en autorización: Accept: application/json pide un formato, no acceso a todos los datos.

Si un response varía según un field del request, Vary declara esa dimensión a las cachés. Un response que cambia según Accept-Language pero omite Vary: Accept-Language puede reutilizarse para otro idioma. Un Vary: Cookie puede reducir drásticamente la reutilización y no arregla una política de autorización mal diseñada. Vary describe una clave de selección para almacenamiento; no demuestra que el origin haya aplicado un control de acceso. RFC 9110, §12.5; RFC 9111, §4.1

Los campos de representación también necesitan contexto. Content-Type permite escoger un parser o una presentación, pero un parser que acepta más de lo declarado crea una discrepancia de implementación. Content-Encoding puede requerir una transformación antes de interpretar el media type. El tamaño de content puede venir de framing y no se debe deducir sólo de una cabecera declarativa en una captura incompleta. En cada claim hay que nombrar quién parsea, qué versión y qué límites aplica.

Estado entre requests: cookies, sesión y autorización

HTTP no mantiene por sí mismo una sesión de aplicación entre requests independientes. Una aplicación puede asociar estado mediante cookies, un token en Authorization, un identificador en la URL, una sesión en servidor o una combinación. El hecho de que un navegador envíe una cookie sólo prueba que siguió sus reglas de almacenamiento y alcance; no prueba que la cookie sea una credencial válida ni que el servidor autorice una acción.

RFC 6265 define el mecanismo canónico publicado de cookies. Set-Cookie permite que un servidor productor proponga una cookie; el user agent aplica reglas de almacenamiento, Domain, Path, Secure, HttpOnly y expiración antes de decidir cuándo devolverla mediante Cookie. Las propuestas 6265bis/Auth48 asociadas a RFC 10025 siguen en transición: la URL canónica del RFC Editor no está disponible y no se tratan como norma publicada. RFC 6265, §§4–5

Una cookie puede transportar un identificador opaco de sesión. El servidor debe resolver ese identificador, comprobar integridad/expiración y aplicar autorización en cada operación relevante. HttpOnly limita acceso desde APIs de script del navegador; no convierte el valor en una identidad criptográficamente autenticada. Secure restringe el envío a canales que el user agent considera seguros; no hace que el contenido sea correcto ni sustituye una política de autorización. Las políticas SameSite dependen del navegador, versión, contexto y configuración.

La separación mínima es:

  1. Estado de transporte: qué cookie o token viajó, con qué atributos y por qué ruta.
  2. Autenticación: qué evidencia llevó al servidor a asociar la petición con un principal.
  3. Autorización: qué política permitió o negó la acción sobre el recurso.
  4. Estado de negocio: qué transición persistió y qué evidencia la confirma.

Un Cookie: session=abc sin el log del servidor sólo muestra un campo enviado. Un Authorization: Bearer ... tampoco demuestra que el token sea válido, que no esté revocado o que conceda la operación concreta. Del mismo modo, Host selecciona contexto de destino en HTTP/1.1 y HTTP/2/3 tiene una forma equivalente mediante :authority en muchos requests, pero ninguno equivale a la identidad del peer o del principal.

Cachés, freshness, validators y revalidation

Una caché HTTP almacena respuestas para responder una petición posterior sin consultar necesariamente al origin. RFC 9111 modela la freshness con directivas, edades, tiempos y restricciones de reutilización. Cache-Control: max-age=60 expresa una vida de frescura; Age informa una edad estimada de una respuesta almacenada; no-cache suele exigir validación antes de reutilizar, mientras no-store pide no almacenar. Estos campos se interpretan junto con Date, heurísticas permitidas, shared/private cache y request directives. No basta encontrar max-age para concluir que una respuesta fue servida desde caché.

Un validator permite comprobar si una copia sigue representando el mismo estado. ETag es un validator opaco; puede ser fuerte o débil según su sintaxis y uso. Last-Modified ofrece una marca temporal con granularidad y límites de reloj. El cliente puede enviar If-None-Match o If-Modified-Since. El origin responde 304 Not Modified si la condición permite reutilizar la copia, o transfiere una representación nueva. El validator no es una firma digital ni prueba que el contenido sea correcto para el usuario; sólo sostiene una comparación bajo el recurso y las reglas declaradas. RFC 9111, §§4–5; RFC 9110, §§8.8 y 13

La seguridad depende de la clave de caché y del contexto. Si la respuesta varía según Authorization, cookie o tenant pero la caché ignora esa dimensión, la reutilización puede mezclar representaciones de principales distintos. Vary ayuda cuando el servidor declara el field relevante, pero no sustituye una configuración de caché correcta ni protege contra una implementación que deriva una clave incompleta. La prueba profesional debe comparar una petición positiva de usuario A con una negativa de usuario B, conservar headers completos, aislar una caché compartida y comprobar si el origin fue consultado en cada caso.

Intermediarios: cada salto puede tener autoridad propia

Un intermediary recibe un message y lo reenvía, transforma, almacena o genera una respuesta. Un proxy puede ser forward (elegido por el cliente) o reverse (colocado delante de un origin); un gateway puede traducir protocolos o aplicar políticas; un CDN añade almacenamiento y distribución; un tunnel reenvía bytes sin interpretar la semántica de la capa interior cuando el método y la versión lo permiten. RFC 9110 §3.7 advierte que una cadena puede contener múltiples conexiones y que un intermediario no es transparente por defecto.

Para cada tramo hay que registrar:

Via, Forwarded y campos equivalentes pueden aportar trazabilidad, pero su presencia, exactitud y confianza dependen de la cadena. Un header que declara una IP original no es una prueba de origen si un cliente puede insertarlo o si un proxy no confiable lo reescribe. El origin debe definir qué intermediarios están autorizados a afirmar identidad, scheme, host o tenant y cómo se autentica esa relación.

Una terminación de conexión divide el problema. El cliente puede hablar HTTP/2 con un edge, mientras el edge habla HTTP/1.1 con el origin. El origin no ve automáticamente el stream, la conexión, la IP de transporte o el orden exacto que vio el cliente. Para correlacionar hay que usar identificadores, timestamps con límites conocidos y logs de ambos extremos. Un CDN saludable puede servir una copia sin llegar al origin; por eso la ausencia de un log de origin no demuestra que el cliente no recibió una representación.

Cadena de navegador, edge, gateway y origin con conexiones separadas, caché en edge y autorización en el tramo final.
Cada intermediario puede terminar o generar mensajes.

La ausencia de log del origin no prueba ausencia de respuesta.

Framing de HTTP/1.1 y discrepancias de interpretación

En HTTP/1.1, la delimitación de un message body sigue reglas de RFC 9112 §6. Cuando existe un Transfer-Encoding aplicable, el parser debe seguir la codificación de transferencia; Content-Length puede declarar una longitud; ciertas respuestas no tienen body por su status o método. El manejo de whitespace, campos repetidos y combinaciones depende de la gramática de cada field y de las reglas de framing: los mensajes inválidos o cuyo framing sea inconsistente deben rechazarse, mientras los casos normalizables deben procesarse exactamente como prescriben RFC 9110 y RFC 9112. Algunos fields list-based pueden combinarse; Set-Cookie no debe combinarse de ese modo, y los casos especiales de Content-Length o Transfer-Encoding no autorizan una regla global para todos los duplicados.

Una discrepancia de framing aparece cuando dos componentes de la misma cadena adjudican fronteras distintas al body. Si un edge y un origin no aplican las mismas reglas sobre longitud, codificación, duplicados, espacios o conexiones persistentes, los bytes que uno considera parte de una petición pueden ser interpretados por el otro como el comienzo de otra. En seguridad se conoce como request smuggling, pero la etiqueta no sustituye el análisis causal.

La condición sólo es material bajo precondiciones: HTTP/1.1 o una traducción a él; una cadena con al menos dos parsers; un mensaje que cada parser acepte bajo reglas distintas; posibilidad de que la conexión persista o de que el desajuste influya en otro request; y ausencia de normalización o rechazo previo. Un parser estricto y único puede rechazar el mensaje; una conexión separada por request puede limitar el efecto; HTTP/2 o HTTP/3 no usan el mismo framing textual aunque un gateway pueda traducirlos a HTTP/1.1. El capítulo no proporciona payloads, secuencias de ataque ni instrucciones contra sistemas. El control es comparar parsers, configuración y comportamiento de rechazo en un entorno autorizado.

La afirmación correcta es condicional: «Existe riesgo de discrepancia si el componente E acepta la combinación X con una regla y el componente O la interpreta con otra, bajo una conexión y una traducción que conservan los bytes». No es correcto afirmar «todo Content-Length duplicado es vulnerable» ni «HTTP/2 elimina todos los problemas». La adjudicación requiere una matriz de versiones, parser, proxy, normalización y control positivo/negativo.

HTTP/2 y HTTP/3: framing diferente, semántica relacionada

HTTP/2 (RFC 9113) divide la comunicación en frames binarios asociados a streams multiplexados. Usa pseudo-fields como :method, :scheme, :authority y :path para representar componentes del request, y HPACK para compresión de campos. El framing no es una secuencia de líneas HTTP/1.1; una implementación no debe aplicar reglas de delimitación textual a los frames. Aun así, la operación sigue teniendo método, target, fields, content y status semánticos compatibles con HTTP. RFC 9113, §§4, 8.3 y 8.3.1

HTTP/3 (RFC 9114) lleva una semántica equivalente sobre QUIC y usa frames HTTP/3 y QPACK. Los streams y errores de transporte difieren de TCP, y un intermediario puede traducir HTTP/3 a HTTP/2 o HTTP/1.1. Esa traducción puede cambiar compresión, orden de entrega, límites y observabilidad; no debe inventar una semántica de método o status distinta. Una captura de frames HTTP/2/3 tampoco es evidencia directa de cómo el origin recibió un request tras una traducción. RFC 9114, §§2–4

La comparación útil es estructural:

Desliza horizontalmente para consultar todas las columnas.

Aspecto HTTP/1.1 HTTP/2 HTTP/3
Framing líneas, fields y reglas de body frames binarios y streams frames binarios sobre QUIC
Compresión de fields sin compresión dinámica obligatoria HPACK QPACK
Multiplexación conexiones persistentes, sin streams HTTP nativos streams multiplexados streams QUIC/HTTP multiplexados
Riesgo de análisis discrepancias de longitud/transferencia traducción, estado de stream y descompresión traducción, QUIC y QPACK
Semántica método, target, status, representación relacionada relacionada

El cuadro no es una panorámica de protocolos de transporte. Su finalidad es recordar que una misma semántica puede tener distintos puntos de observación y que cada traducción requiere un contrato explícito.

Caso conductor: Lumen y una factura que viaja por cuatro componentes

Lumen es una aplicación sintética de facturación. El navegador de Elena envía GET /invoices/17 a edge.example.test. El navegador tiene una cookie de sesión; el edge termina HTTP/2, consulta una caché y, cuando no hay una copia fresca, abre HTTP/1.1 hacia un gateway. El gateway valida un token interno, aplica rate limiting y reenvía al origin. El origin responde JSON con ETag: "invoice-17-v8", Cache-Control: private, max-age=0 y Vary: Accept-Language.

La primera observación del navegador es 200 y un JSON. Eso prueba que el navegador recibió un response HTTP con esa representación; no prueba todavía que Elena esté autorizada a ver la factura, porque la autorización puede estar mal implementada en el origin o en el gateway. El log del origin muestra una decisión tenant=acme, subject=elena, allow; esa evidencia acota la autorización en el punto que tomó la decisión, pero no prueba que el edge no tuviera una copia previa para otro tenant.

El equipo de respuesta encuentra después un Age: 45 en una variante servida por el edge, aunque el origin no registra una solicitud durante ese minuto. Si el edge es una shared cache, esa observación no es compatible con un hit conforme de la respuesta descrita: private prohíbe su almacenamiento compartido y max-age=0 la deja stale de inmediato, de modo que una copia almacenable tendría que revalidarse antes de reutilizarse. Hay que discriminar si el edge actuaba como private cache, si sirvió otra entrada o una entrada revalidada, si una política documentada transformó las directivas o si existe una misconfiguración/no conformidad. Se comparan clave de caché, Vary, Cache-Control, identidad, tenant, revalidación y logs de edge/origin. La ausencia de solicitud en el origin limita lo observado en ese tramo, pero no vuelve conforme la reutilización.

Árbol de evidencia que separa private cache, otra entrada, revalidación documentada y hit shared no conforme mediante directivas, Age, Vary, ETag y logs.
Una observación de caché necesita correlación y contexto.

Age solo no adjudica causa.

En la segunda prueba, Elena cambia Accept-Language: es a en, pero la respuesta sigue en español. Si el origin produce variantes correctas y declara Vary: Accept-Language, el edge debería separar esas entradas. Si el edge ignora Vary, el problema es de implementación/configuración de caché; si el origin no lo declara, la evidencia apunta a un contrato incompleto. El control negativo es solicitar la misma URI con un tenant distinto y una cookie distinta, esperando que no se reutilice una representación privada.

Finalmente, una actualización de la factura devuelve 202 Accepted. El navegador muestra «actualizada», pero el origin registra una cola pendiente. 202 demuestra aceptación para procesamiento, no finalización. El retest debe consultar el estado posterior con una operación autorizada y correlacionar el evento de persistencia. Si el usuario pulsa de nuevo y un gateway reintenta, la aplicación debe decidir si la operación es idempotente mediante una clave de idempotencia propia; HTTP no convierte POST en idempotente por el solo hecho de viajar sobre una conexión fiable.

Controles positivos, negativos y límites de evidencia

Un control no es una etiqueta de «seguro». Es una observación diseñada para distinguir hipótesis.

Control positivo de autorización y caché. Dos tenants solicitan una representación privada con cookies sintéticas diferentes. Se verifica que el origin registre dos decisiones y que el edge no reutilice la primera respuesta para la segunda. Se conservan key, Vary, Cache-Control, Age, status, ETag y logs correlacionados.

Control negativo de aislamiento. Repetir la solicitud del tenant B con una petición que debería ser no autorizada. Un 403 es evidencia del resultado HTTP en ese punto; hay que comprobar que no se sirvió content previamente almacenado y que el origin o el policy enforcement tomaron la decisión.

Control positivo de revalidation. Guardar una copia con ETag, esperar que sea stale, enviar If-None-Match y observar 304 cuando el validator sigue coincidiendo. Cambiar el recurso debe producir una representación nueva y un ETag distinto, si el contrato del origin usa ese validator.

Control negativo de negociación. Solicitar un media type o idioma que el origin no soporte y comprobar si responde 406, elige una alternativa documentada o devuelve un content por política. El resultado no se generaliza a todos los recursos.

Control positivo de intermediario. Correlacionar una petición con un identificador sintético en edge, gateway y origin; demostrar qué headers se transformaron y qué conexión terminó cada componente. Un response del edge sin log del origin es compatible con una caché, no una anomalía por sí misma.

Control de framing en laboratorio. Usar únicamente mensajes sintéticos no dirigidos a terceros para comparar cómo dos parsers/versiones tratan combinaciones ambiguas. El resultado debe registrar aceptación/rechazo, normalización, cierre de conexión, logs y versión. No se envían secuencias de smuggling a producción ni se infiere vulnerabilidad por una diferencia de texto sin demostrar una frontera de requests.

Límites, contraejemplos y errores que el modelo debe impedir

«HTTPS cambia HTTP». TLS protege un tramo según sus extremos y configuración; no cambia el significado de GET, POST, Cookie o ETag. Puede ocultar la observación a un intermediario que no termina TLS, y una terminación posterior crea otra frontera de confianza.

«GET nunca causa efectos». Safe limita el propósito solicitado, no logs, métricas, cobros o defectos de implementación. Un endpoint que borra con GET viola el contrato esperado; la prueba debe verificar comportamiento.

«PUT siempre crea» o «DELETE siempre devuelve 204». La semántica es idempotente, no una respuesta fija. Estado previo, precondiciones, autorización y recurso determinan el resultado.

«200 prueba éxito de negocio». Sólo prueba un status de clase éxito conforme al contrato HTTP. La decisión de dominio necesita content, evento, almacenamiento y autorización correlacionados.

«Una cookie es autenticación». Es un mecanismo para transportar estado. La autenticación y autorización dependen del servidor, del token, de la sesión y de la política.

«Host identifica al cliente o al servidor». Host/:authority participan en selección del destino virtual. No prueban identidad criptográfica, propiedad de la dirección ni autorización.

«Un proxy es transparente». Puede terminar conexiones, normalizar, filtrar, almacenar, traducir o responder localmente. Sólo un contrato y evidencia de sus campos permiten tratar una transformación como preservación.

«Vary arregla una caché». Declara dimensiones de variación; no repara una clave incompleta, una cookie ignorada o una política de almacenamiento equivocada.

«HTTP/2 o HTTP/3 eliminan request smuggling». Cambian framing, pero una traducción a HTTP/1.1, un parser defectuoso o una política de gateway puede conservar una discrepancia. La afirmación debe nombrar versiones y componentes.

Transferencia profesional: redactar un claim de HTTP

Un informe que diga «el API devolvió la factura equivocada» debe dividirse:

  1. Observación: en el edge E, en la conexión C y ventana T, se recibió 200, ETag V y content JSON con tenant A.
  2. Semántica: el request era GET a target R, con cookie S y Accept L; la operación safe no autoriza el acceso.
  3. Intermediarios: E sirvió desde caché con Age y key K, o reenvió al gateway G; se identifican transformaciones y terminaciones.
  4. Autorización: el punto P registró principal Q y decisión allow/deny, con la política vigente.
  5. Impacto observado: el navegador de tenant B presentó datos de tenant A, si se demostró con dos identidades sintéticas y contenido distintivo.
  6. Fuera de alcance: no se concluye persistencia, exfiltración masiva, causa histórica o compromiso del origin sin evidencia adicional.

La misma disciplina sirve para disponibilidad. «El POST se ejecutó dos veces» requiere correlacionar requests en edge, gateway y origin, distinguir reintento de transporte de reenvío de aplicación y mostrar dos efectos de negocio. Dos logs en un edge no prueban dos transiciones persistidas; una sola respuesta 500 no prueba que el origin no haya aplicado la primera operación.

Síntesis

HTTP es un contrato de mensajes y semántica sobre una o varias conexiones. Un request combina método, target, fields y content; un response combina status, fields y content. Recurso y representación no son sinónimos. Safe, idempotent y cacheable responden preguntas diferentes y tienen alcance, excepciones y condiciones. Cookies y tokens transportan estado, pero autenticación y autorización requieren una decisión verificable. Freshness, validators y Vary permiten reutilización y revalidación sólo dentro de una clave y política correctas. Un proxy, gateway o CDN puede observar, transformar, almacenar o responder; nunca debe asumirse transparente.

HTTP/1.1, HTTP/2 y HTTP/3 ofrecen framing distinto para una semántica relacionada. Las discrepancias de parsing de HTTP/1.1 son riesgos condicionales de una cadena concreta, no una propiedad de cualquier cabecera ni una invitación a probar sistemas ajenos. La pregunta profesional final es siempre: ¿qué componente interpretó qué mensaje, en qué versión y punto de confianza, con qué estado y evidencia, y qué parte del resultado sigue siendo una inferencia?

Problema de transferencia

Un CDN recibe GET /account/summary con una cookie de sesión y responde 200, Age: 20, Vary: Accept-Encoding. El origin no registra la solicitud. Después, un usuario de otro tenant recibe el mismo JSON. El gateway también acepta POST /account/export y devuelve 202; el cliente reintenta tras un timeout y el origin muestra un único request pero dos archivos generados. Finalmente, el edge habla HTTP/2 con el cliente y HTTP/1.1 con el origin.

Redacta un diagnóstico que: (a) separe cache hit, autorización y resultado de negocio; (b) identifique qué dimensión falta en Vary o en la clave de caché; (c) proponga un control positivo y uno negativo con identidades sintéticas; (d) distinga 202 de finalización; (e) explique qué logs y claves correlacionar para separar reintento del cliente, gateway y origin; y (f) enumere las precondiciones que tendrían que demostrarse antes de hablar de una discrepancia de framing. No aceptes como conclusión «200 prueba éxito», «la cookie autentica», «el proxy es transparente» ni «HTTP/2 elimina el problema».

Fuentes principales