httpuv emits duplicate 'Date' response header when one is already supplied
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 64/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
调研方向
阅读src/httpresponse.h和src/webapplication.cpp中的头部处理,从listToResponse()及其对addHeader()和setHeader()的使用开始。issue还提到一条用于自定义头部的独立静态路径,可能需要调查。使用提供的R示例和curl复现;无论应用是否提供Date字段,响应中恰好包含一个有效的Date字段即为完成。
由索引模型根据 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 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
rstudio/httpuv 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 46/100
-
难度 5/5 一周以上 新手友好度 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
-
Status: Opened
难度 2/5 1-3 小时 新手友好度 64/100
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 72/100
FriendsofECCE/ECCE#1018 ·
-
难度 2/5 1-3 小时 新手友好度 62/100
immortalwrt/immortalwrt#2522 ·
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
severity: low
难度 2/5 1-3 小时 新手友好度 64/100
luainkernel/lunatik#2530 ·
维护者通常 1 天内回复