Commit d2ec1420 authored by Kenton Varda's avatar Kenton Varda

Fix bug with HTTP entities with `Content-Length: 0`.

The entity-body would never be marked "done", breaking the pipeline for subsequent requests/responses.

(In practice `Content-Length: 0` is rare since normally only GET requests don't have content and they don't pass `Content-Length` at all.)
parent 55d04e58
......@@ -850,6 +850,47 @@ kj::ArrayPtr<const HttpTestCase> pipelineTestCases() {
},
},
// Throw a zero-size request/response into the pipeline to check for a bug that existed with
// them previously.
{
{
"POST /foo HTTP/1.1\r\n"
"Content-Length: 0\r\n"
"\r\n",
HttpMethod::POST, "/foo", {}, uint64_t(0), {},
},
{
"HTTP/1.1 200 OK\r\n"
"Content-Length: 0\r\n"
"\r\n",
200, "OK", {}, uint64_t(0), {}
},
},
// Also a zero-size chunked request/response.
{
{
"POST /foo HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"0\r\n"
"\r\n",
HttpMethod::POST, "/foo", {}, nullptr, {},
},
{
"HTTP/1.1 200 OK\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"0\r\n"
"\r\n",
200, "OK", {}, nullptr, {}
},
},
{
{
"POST /bar HTTP/1.1\r\n"
......
......@@ -1369,12 +1369,15 @@ public:
class HttpFixedLengthEntityWriter final: public kj::AsyncOutputStream {
public:
HttpFixedLengthEntityWriter(HttpOutputStream& inner, uint64_t length)
: inner(inner), length(length) {}
: inner(inner), length(length) {
if (length == 0) inner.finishBody();
}
~HttpFixedLengthEntityWriter() noexcept(false) {
if (length > 0) inner.abortBody();
}
Promise<void> write(const void* buffer, size_t size) override {
if (size == 0) return kj::READY_NOW;
KJ_REQUIRE(size <= length, "overwrote Content-Length");
length -= size;
......@@ -1384,6 +1387,7 @@ public:
uint64_t size = 0;
for (auto& piece: pieces) size += piece.size();
if (size == 0) return kj::READY_NOW;
KJ_REQUIRE(size <= length, "overwrote Content-Length");
length -= size;
......@@ -1391,6 +1395,7 @@ public:
}
Maybe<Promise<uint64_t>> tryPumpFrom(AsyncInputStream& input, uint64_t amount) override {
if (amount == 0) return Promise<uint64_t>(uint64_t(0));
KJ_REQUIRE(amount <= length, "overwrote Content-Length");
length -= amount;
......
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