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

Merge pull request #644 from capnproto/full-bodied-gets

Support sending GETs with bodies.
parents 5e7eb1d8 bfd0001a
...@@ -699,6 +699,38 @@ kj::ArrayPtr<const HttpRequestTestCase> requestTestCases() { ...@@ -699,6 +699,38 @@ kj::ArrayPtr<const HttpRequestTestCase> requestTestCases() {
{{HttpHeaderId::HOST, HUGE_STRING}}, {{HttpHeaderId::HOST, HUGE_STRING}},
uint64_t(0), {} uint64_t(0), {}
}, },
{
"GET /foo/bar HTTP/1.1\r\n"
"Content-Length: 6\r\n"
"Host: example.com\r\n"
"\r\n"
"foobar",
HttpMethod::GET,
"/foo/bar",
{{HttpHeaderId::HOST, "example.com"}},
uint64_t(6), { "foobar" },
},
{
"GET /foo/bar HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n"
"Host: example.com\r\n"
"\r\n"
"3\r\n"
"foo\r\n"
"3\r\n"
"bar\r\n"
"0\r\n"
"\r\n",
HttpMethod::GET,
"/foo/bar",
{{HttpHeaderId::HOST, "example.com"},
{HttpHeaderId::TRANSFER_ENCODING, "chunked"}},
nullptr, { "foo", "bar" },
}
}; };
// TODO(cleanup): A bug in GCC 4.8, fixed in 4.9, prevents REQUEST_TEST_CASES from implicitly // TODO(cleanup): A bug in GCC 4.8, fixed in 4.9, prevents REQUEST_TEST_CASES from implicitly
......
...@@ -2451,19 +2451,37 @@ public: ...@@ -2451,19 +2451,37 @@ public:
kj::StringPtr connectionHeaders[CONNECTION_HEADERS_COUNT]; kj::StringPtr connectionHeaders[CONNECTION_HEADERS_COUNT];
kj::String lengthStr; kj::String lengthStr;
if (method == HttpMethod::GET || method == HttpMethod::HEAD) { bool isGet = method == HttpMethod::GET || method == HttpMethod::HEAD;
// No entity-body. bool hasBody;
} else KJ_IF_MAYBE(s, expectedBodySize) {
lengthStr = kj::str(*s); KJ_IF_MAYBE(s, expectedBodySize) {
connectionHeaders[BuiltinHeaderIndices::CONTENT_LENGTH] = lengthStr; if (isGet && *s == 0) {
// GET with empty body; don't send any Content-Length.
hasBody = false;
} else {
lengthStr = kj::str(*s);
connectionHeaders[BuiltinHeaderIndices::CONTENT_LENGTH] = lengthStr;
hasBody = true;
}
} else { } else {
connectionHeaders[BuiltinHeaderIndices::TRANSFER_ENCODING] = "chunked"; if (isGet && headers.get(HttpHeaderId::TRANSFER_ENCODING) == nullptr) {
// GET with empty body; don't send any Transfer-Encoding.
hasBody = false;
} else {
// HACK: Normally GET requests shouldn't have bodies. But, if the caller set a
// Transfer-Encoding header on a GET, we use this as a special signal that it might
// actually want to send a body. This allows pass-through of a GET request with a chunked
// body to "just work". We strongly discourage writing any new code that sends
// full-bodied GETs.
connectionHeaders[BuiltinHeaderIndices::TRANSFER_ENCODING] = "chunked";
hasBody = true;
}
} }
httpOutput.writeHeaders(headers.serializeRequest(method, url, connectionHeaders)); httpOutput.writeHeaders(headers.serializeRequest(method, url, connectionHeaders));
kj::Own<kj::AsyncOutputStream> bodyStream; kj::Own<kj::AsyncOutputStream> bodyStream;
if (method == HttpMethod::GET || method == HttpMethod::HEAD) { if (!hasBody) {
// No entity-body. // No entity-body.
httpOutput.finishBody(); httpOutput.finishBody();
bodyStream = heap<HttpNullEntityWriter>(); bodyStream = heap<HttpNullEntityWriter>();
......
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