httpuv emits duplicate 'Date' response header when one is already supplied
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 64/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
調査の方向性
src/httpresponse.hとsrc/webapplication.cppのヘッダー処理を読み、listToResponse()と、それがaddHeader()およびsetHeader()を使う箇所から調べてください。issueでは、カスタムヘッダー用の別個の静的な経路にも触れており、調査が必要になる場合があります。提供されたRの例とcurlで再現してください。アプリケーションがDateフィールドを指定する場合も省略する場合も、レスポンスに有効なDateフィールドがちょうど1つ含まれれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Description
When an application response already includes a Date header, httpuv 1.6.17 sends a second Date field line, instead of preserving or replacing the supplied value.
Impact
RFC 9110 Sections 5.3 and 6.6.1 make Date a single HTTP-date field, not a list. Because Date is not list-valued, combining repeated lines with commas would produce a value that does not match the Date grammar. Clients, caches, or intermediaries may therefore reject or ignore the timestamp. This is an interoperability/conformance issue rather than an immediate security issue.
If the two dates differ, recipients that recover by selecting one field line may disagree about when the response originated; caches also use Date when calculating response age, so this can lead to inconsistent freshness handling.
Background
We found this while inspecting the raw response headers from our application during a cache-policy review. The application uses Plumber2, which runs on Fiery and uses reqres for request/response handling. The first Date is added by reqres 1.2.0 when it formats the response; our route does not set it. httpuv then adds a second Date to the wire response.
I searched the httpuv, Fiery, reqres, and Plumber2 issue trackers for matching reports and did not find one.
We reduced the behavior to the httpuv-only example below to isolate the HTTP server layer.
Environment
- R 4.6.2
- httpuv 1.6.17
Steps to reproduce
Save this as date-header-mwe.R:
message("Starting server at http://127.0.0.1:8081/ (press Ctrl+C to stop)")
httpuv::runServer(
host = "127.0.0.1",
port = 8081,
app = list(
call = function(req) {
list(
status = 200L,
headers = list(
# simulate an application-supplied Date. httpuv will add another Date automatically.
Date = format(Sys.time(), "%a, %d %b %Y %H:%M:%S GMT", tz = "GMT")
),
body = ""
)
}
)
)
Start the server:
Rscript date-header-mwe.R
In another process, send a request to the server:
curl -sS -D - -o /dev/null http://127.0.0.1:8081/
Actual behavior
HTTP/1.1 200 OK
Date: Thu, 05 Nov 2026 17:01:29 GMT
Date: Thu, 05 Nov 2026 17:01:29 GMT
Content-Length: 0
The date and header order may vary, but the response contains two Date field lines.
Expected behavior
HTTP/1.1 200 OK
Date: Thu, 05 Nov 2026 17:01:29 GMT
Content-Length: 0
The response should contain one valid Date field line. The server may use its own timestamp or an application-supplied timestamp, but should not emit both.
Possible patch
I'm personally new to httpuv, but to be as solution-oriented as possible, here's an AI-generated patch, which may fix this issue...
In v1.6.17, HttpResponse adds a default Date in its constructor (src/httpresponse.h). The listToResponse() path in src/webapplication.cpp then appends each R-supplied response header with addHeader(). For a supplied Date, using the existing case-insensitive setHeader() method instead would replace the default while preserving append behavior for other headers.
Illustrative patch for listToResponse() (a regression test should cover supplied and omitted Date):
diff --git a/src/webapplication.cpp b/src/webapplication.cpp
--- a/src/webapplication.cpp
+++ b/src/webapplication.cpp
@@
- pResp->addHeader(
- std::string((char*)headerNames[i], headerNames[i].size()),
- Rcpp::as<std::string>(responseHeaders[i]));
+ const std::string name((char*)headerNames[i], headerNames[i].size());
+ const std::string value = Rcpp::as<std::string>(responseHeaders[i]);
+ if (to_lower(name) == "date") {
+ pResp->setHeader(name, value);
+ } else {
+ pResp->addHeader(name, value);
+ }
This covers the R response path shown above. Static-path custom headers are added through a separate code path and would need the same Date replacement if they are intended to support user-supplied Date values too.
- 主要言語
- C
- スター
- 252
- フォーク
- 87
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
rstudio/httpuv のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 46/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 30/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
-
feature good first issue :heart: help wanted :heart: upkeep
難易度 3/5 1〜2日 初心者へのやさしさ 25/100
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
severity: low
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
luainkernel/lunatik#2530 ·
メンテナーはふだん 1 日以内に返信
-
polygonToCells CLI silently drops vertices when whitespace precedes a coordinate's closing bracketオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
メンテナーはふだん 1 日以内に返信
-
issue: bug report
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
メンテナーはふだん 2 日以内に返信