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() {
{{HttpHeaderId::HOST, HUGE_STRING}},
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
......
......@@ -2451,19 +2451,37 @@ public:
kj::StringPtr connectionHeaders[CONNECTION_HEADERS_COUNT];
kj::String lengthStr;
if (method == HttpMethod::GET || method == HttpMethod::HEAD) {
// No entity-body.
} else KJ_IF_MAYBE(s, expectedBodySize) {
lengthStr = kj::str(*s);
connectionHeaders[BuiltinHeaderIndices::CONTENT_LENGTH] = lengthStr;
bool isGet = method == HttpMethod::GET || method == HttpMethod::HEAD;
bool hasBody;
KJ_IF_MAYBE(s, expectedBodySize) {
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 {
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));
kj::Own<kj::AsyncOutputStream> bodyStream;
if (method == HttpMethod::GET || method == HttpMethod::HEAD) {
if (!hasBody) {
// No entity-body.
httpOutput.finishBody();
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