httpuv emits duplicate 'Date' response header when one is already supplied
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 64/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Ambito
- backend-api-design
Direzione di ricerca
Leggi src/httpresponse.h e la gestione degli header in src/webapplication.cpp, iniziando da listToResponse() e dal suo uso di addHeader() e setHeader(). L’issue menziona anche un percorso statico separato per gli header personalizzati, che potrebbe richiedere un’indagine. Riproduci il problema con l’esempio R fornito e curl; il lavoro è completato quando la risposta contiene esattamente un campo Date valido, sia che l’applicazione ne fornisca uno sia che lo ometta.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- C
- Stelle
- 252
- Fork
- 87
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di rstudio/httpuv
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 46/100
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
-
Use `{cli}` for errorsApertafeature good first issue :heart: help wanted :heart: upkeep
Difficoltà 3/5 1-2 giorni Idoneità per principianti 25/100
Tutte le issue di rstudio/httpuv
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
severity: low
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
luainkernel/lunatik#2530 ·
I maintainer di solito rispondono entro 1 giorno
-
polygonToCells CLI silently drops vertices when whitespace precedes a coordinate's closing bracketAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
issue: bug report
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 2 giorni