http2: content-encoding is incorrectly listed in kSingleValueHeaders

Đang mở Phù hợp với người mới
#67,151 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@inoway46 đang làm issue này rồi.

Từ ngày 1/11/2026.

  • #67184 của @inoway46 — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
74/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
javascript, node.js
Lĩnh vực
backend, networking

Hướng nghiên cứu

Đọc lib/internal/http2/util.js, tập trung vào kSingleValueHeaders và các đường xử lý mapToHeaders và buildNgHeaderString. Kiểm tra cách các giá trị content-encoding trùng lặp được xử lý theo từng hướng; công việc hoàn tất khi các giá trị đầu vào được kết hợp theo thứ tự và nhiều giá trị đầu ra không còn gây ra ERR_HTTP2_HEADER_SINGLE_VALUE.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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

Ngôn ngữ chính
JavaScript
Star
123k
Fork
39.3k
Merge trung bình
4 ngày 15 giờ
Pull request đã merge (30 ngày)
238

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của nodejs/node

Tất cả issue của nodejs/node

Issue tương tự

Thêm issue về JavaScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.