http2: content-encoding is incorrectly listed in kSingleValueHeaders

Offen Anfängerfreundlich
#67,151 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@inoway46 arbeitet bereits daran.

Seit 01.11.2026.

  • #67184 von @inoway46 — offen

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
74/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
javascript, node.js
Bereich
backend, networking

Rechercherichtung

Lies lib/internal/http2/util.js und konzentriere dich auf kSingleValueHeaders sowie die Pfade mapToHeaders und buildNgHeaderString. Prüfe, wie doppelte content-encoding-Werte in jeder Richtung behandelt werden; fertig ist die Arbeit, wenn eingehende Werte in ihrer Reihenfolge zusammengeführt werden und mehrere ausgehende Werte nicht mehr ERR_HTTP2_HEADER_SINGLE_VALUE auslösen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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

Vorherrschende Sprache
JavaScript
Sterne
123k
Forks
39.3k
Ø Merge
4 T. 16 Std.
Gemergte PRs (30 T.)
227

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus nodejs/node

Alle Issues in nodejs/node

Ähnliche Issues

Weitere Issues zu JavaScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.