Unverified Commit 394643ba authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #659 from capnproto/head-content-length

Allow app to send arbitrary Content-Length/Transfer-Encoding in HEAD responses.
parents 9ec2faa7 be9b18c5
......@@ -768,6 +768,20 @@ kj::ArrayPtr<const HttpResponseTestCase> responseTestCases() {
HttpMethod::HEAD,
},
{
"HTTP/1.1 200 OK\r\n"
"Content-Length: foobar\r\n"
"Content-Type: text/plain\r\n"
"\r\n",
200, "OK",
{{HttpHeaderId::CONTENT_TYPE, "text/plain"},
{HttpHeaderId::CONTENT_LENGTH, "foobar"}},
123, {},
HttpMethod::HEAD,
},
{
"HTTP/1.1 200 OK\r\n"
"Content-Length: 8\r\n"
......
......@@ -489,6 +489,7 @@ namespace BuiltinHeaderIndices {
#undef HEADER_ID
};
constexpr uint HEAD_RESPONSE_CONNECTION_HEADERS_COUNT = BuiltinHeaderIndices::CONTENT_LENGTH;
constexpr uint CONNECTION_HEADERS_COUNT = BuiltinHeaderIndices::SEC_WEBSOCKET_KEY;
constexpr uint WEBSOCKET_CONNECTION_HEADERS_COUNT = BuiltinHeaderIndices::HOST;
......@@ -3539,7 +3540,19 @@ private:
connectionHeaders[BuiltinHeaderIndices::TRANSFER_ENCODING] = "chunked";
}
httpOutput.writeHeaders(headers.serializeResponse(statusCode, statusText, connectionHeaders));
// For HEAD requests, if the application specified a Content-Length or Transfer-Encoding
// header, use that instead of whatever we decided above.
kj::ArrayPtr<kj::StringPtr> connectionHeadersArray = connectionHeaders;
if (method == HttpMethod::HEAD) {
if (headers.get(HttpHeaderId::CONTENT_LENGTH) != nullptr ||
headers.get(HttpHeaderId::TRANSFER_ENCODING) != nullptr) {
connectionHeadersArray = connectionHeadersArray
.slice(0, HEAD_RESPONSE_CONNECTION_HEADERS_COUNT);
}
}
httpOutput.writeHeaders(headers.serializeResponse(
statusCode, statusText, connectionHeadersArray));
kj::Own<kj::AsyncOutputStream> bodyStream;
if (method == HttpMethod::HEAD) {
......
......@@ -128,13 +128,15 @@ public:
#define KJ_HTTP_FOR_EACH_BUILTIN_HEADER(MACRO) \
/* Headers that are always read-only. */ \
MACRO(CONNECTION, "Connection") \
MACRO(CONTENT_LENGTH, "Content-Length") \
MACRO(KEEP_ALIVE, "Keep-Alive") \
MACRO(TE, "TE") \
MACRO(TRAILER, "Trailer") \
MACRO(TRANSFER_ENCODING, "Transfer-Encoding") \
MACRO(UPGRADE, "Upgrade") \
\
/* Headers that are read-only except in the case of a response to a HEAD request. */ \
MACRO(CONTENT_LENGTH, "Content-Length") \
MACRO(TRANSFER_ENCODING, "Transfer-Encoding") \
\
/* Headers that are read-only for WebSocket handshakes. */ \
MACRO(SEC_WEBSOCKET_KEY, "Sec-WebSocket-Key") \
MACRO(SEC_WEBSOCKET_VERSION, "Sec-WebSocket-Version") \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment