httpuv emits duplicate 'Date' response header when one is already supplied
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 64/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Área
- backend-api-design
Línea de trabajo
Lee src/httpresponse.h y el manejo de cabeceras en src/webapplication.cpp, empezando por listToResponse() y su uso de addHeader() y setHeader(). El issue también menciona una ruta estática independiente para cabeceras personalizadas que quizá haya que investigar. Reprodúcelo con el ejemplo de R proporcionado y curl; se considera terminado cuando la respuesta contiene exactamente un campo Date válido, tanto si la aplicación proporciona uno como si lo omite.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- C
- Estrellas
- 252
- Forks
- 87
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de rstudio/httpuv
-
Dificultad 4/5 3-5 días Aptitud para principiantes 46/100
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
-
Use `{cli}` for errorsAbiertofeature good first issue :heart: help wanted :heart: upkeep
Dificultad 3/5 1-2 días Aptitud para principiantes 25/100
Todos los issues de rstudio/httpuv
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
severity: low
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
luainkernel/lunatik#2530 ·
Los mantenedores suelen responder en 1 día
-
polygonToCells CLI silently drops vertices when whitespace precedes a coordinate's closing bracketAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
Los mantenedores suelen responder en 1 día
-
issue: bug report
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 2 días