http2: content-encoding is incorrectly listed in kSingleValueHeaders

Abierto Apto para principiantes
#67,151 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@inoway46 ya está trabajando en esto.

Desde el 1/11/2026.

  • #67184 de @inoway46 — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
74/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
javascript, node.js

Línea de trabajo

Lee lib/internal/http2/util.js y céntrate en kSingleValueHeaders y en las rutas mapToHeaders y buildNgHeaderString. Comprueba cómo se gestionan los valores content-encoding duplicados en cada dirección; el trabajo está terminado cuando los valores entrantes se combinan en orden y varios valores salientes ya no provocan ERR_HTTP2_HEADER_SINGLE_VALUE.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

confirmed-bug http2
Version

v26.13.0

Platform

Subsystem

No response

What steps will reproduce the bug?

Drafted by Gemini 4 Argon.

In lib/internal/http2/util.js, HTTP2_HEADER_CONTENT_ENCODING is listed in kSingleValueHeaders:

  • Incoming (mapToHeaders): When an HTTP/2 peer sends multiple content-encoding header lines (e.g., content-encoding: gzip twice on Google Drive viewer endpoints), only the first value is kept in headers['content-encoding'] and subsequent values are silently dropped (even with strictSingleValueFields: false from #59917). As a result, HTTP/2 clients only decompress the first layer and treat the still-compressed payload as decoded data, and reverse proxies forwarding headers strip the remaining encoding layers so downstream browsers fail to decode the response.
  • Outgoing (buildNgHeaderString): Passing multiple content-encoding values throws ERR_HTTP2_HEADER_SINGLE_VALUE by default, preventing servers and proxies from sending or forwarding multi-value content-encoding headers.
Evidence
  1. HTTP Semantics — RFC 9110 §8.4 (Content-Encoding) & §5.3:

    Content-Encoding = #content-coding

    If one or more encodings have been applied to a representation, the sender that applied the encodings MUST generate a Content-Encoding header field that lists the content codings in the order in which they were applied.

    Because Content-Encoding uses the #element list ABNF production, multiple content-encoding header field lines are valid per RFC 9110 §5.3 and must be combined in order with ', ' rather than discarded.

  2. HTTP/2 & HPACK — RFC 9113 §8.2.1 & RFC 7541:
    HTTP/2 only forbids connection-specific headers (connection, transfer-encoding, keep-alive, upgrade, proxy-connection); for all other fields, RFC 9113 §8.2.1 inherits RFC 9110 §5.3, allowing list-based headers to be transmitted as multiple separate HPACK header field entries (each referencing HPACK static table index 26 content-encoding). nghttp2 itself accepts multiple content-encoding entries and delivers all of them in rawHeaders—the truncation happens purely in Node's JS kSingleValueHeaders check.

  3. node:http consistency: lib/_http_incoming.js (_addHeaderLine) does not treat content-encoding as single-value and joins duplicate lines with ', '.

Removing HTTP2_HEADER_CONTENT_ENCODING from kSingleValueHeaders fixes both directions.

Compatibility
  • No type change: headers['content-encoding'] remains string | undefined (mapToHeaders joins non-single-value headers with ', '), and single content-encoding responses are unaffected.
  • Incoming duplicate headers: headers['content-encoding'] becomes 'gzip, br' instead of 'gzip' (matching what a single content-encoding: gzip, br header or node:http already produces). Callers doing exact single-token checks (headers['content-encoding'] === 'gzip') without splitting on ',' may stop matching when a peer sends multiple lines.
  • Outgoing validation: Passing multiple content-encoding values will succeed instead of throwing ERR_HTTP2_HEADER_SINGLE_VALUE (potentially semver-major per Node's error-removal policy).
How often does it reproduce? Is there a required condition?
What is the expected behavior? Why is that the expected behavior?
What do you see instead?
Additional information

No response

Lenguaje dominante
JavaScript
Estrellas
123k
Forks
39.3k
Merge medio
4 d 15 h
PR fusionados (30 d)
238

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de nodejs/node

Todos los issues de nodejs/node

Issues similares

Más issues de JavaScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.