Unverified Commit f73ac9f6 authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #751 from…

Merge pull request #751 from capnproto/harris/zero-length-responses-get-no-content-length-and-great-sadness

Zero-length HTTP responses get no Content-Length header
parents 5bc2d30c 48083d47
......@@ -809,6 +809,18 @@ kj::ArrayPtr<const HttpResponseTestCase> responseTestCases() {
HttpMethod::HEAD,
},
// Zero-length expected size response to HEAD request has no Content-Length header.
{
"HTTP/1.1 200 OK\r\n"
"\r\n",
200, "OK",
{},
uint64_t(0), {},
HttpMethod::HEAD,
},
{
"HTTP/1.1 200 OK\r\n"
"Content-Length: 8\r\n"
......@@ -1179,6 +1191,22 @@ kj::ArrayPtr<const HttpTestCase> pipelineTestCases() {
200, "OK", {}, 7, { "foo bar" }
},
},
// Zero-length expected size response to HEAD request has no Content-Length header.
{
{
"HEAD / HTTP/1.1\r\n"
"\r\n",
HttpMethod::HEAD, "/", {}, uint64_t(0), {},
},
{
"HTTP/1.1 200 OK\r\n"
"\r\n",
200, "OK", {}, uint64_t(0), {}, HttpMethod::HEAD,
},
},
};
// TODO(cleanup): A bug in GCC 4.8, fixed in 4.9, prevents RESPONSE_TEST_CASES from implicitly
......
......@@ -1603,6 +1603,10 @@ kj::Own<kj::AsyncInputStream> HttpInputStreamImpl::getEntityBody(
kj::Maybe<uint64_t> length;
KJ_IF_MAYBE(cl, headers.get(HttpHeaderId::CONTENT_LENGTH)) {
length = strtoull(cl->cStr(), nullptr, 10);
} else if (headers.get(HttpHeaderId::TRANSFER_ENCODING) == nullptr) {
// HACK: Neither Content-Length nor Transfer-Encoding header in response to HEAD request.
// Propagate this fact with a 0 expected body length.
length = uint64_t(0);
}
return kj::heap<HttpNullEntityReader>(*this, length);
} else if (statusCode == 204 || statusCode == 205 || statusCode == 304) {
......@@ -4384,8 +4388,14 @@ private:
if (statusCode == 204 || statusCode == 205 || statusCode == 304) {
// No entity-body.
} else KJ_IF_MAYBE(s, expectedBodySize) {
lengthStr = kj::str(*s);
connectionHeaders[HttpHeaders::BuiltinIndices::CONTENT_LENGTH] = lengthStr;
// HACK: We interpret a zero-length expected body length on responses to HEAD requests to mean
// "don't set a Content-Length header at all." This provides a way to omit a body header on
// HEAD responses with non-null-body status codes. This is a hack that *only* makes sense
// for HEAD responses.
if (method != HttpMethod::HEAD || *s > 0) {
lengthStr = kj::str(*s);
connectionHeaders[HttpHeaders::BuiltinIndices::CONTENT_LENGTH] = lengthStr;
}
} else {
connectionHeaders[HttpHeaders::BuiltinIndices::TRANSFER_ENCODING] = "chunked";
}
......
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