#include "../test.h"
#define TEST(name) TEST_CASE("parse-chunks: " name, "[parse-chunks]")
TEST("trivial chunks") {
RequestParser p;
string raw =
"POST /upload HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"4\r\n"
"Wiki\r\n"
"5\r\n"
"pedia\r\n"
"E\r\n"
" in\r\n"
"\r\n"
"chunks.\r\n"
"0\r\n"
"\r\n"
;
auto result = p.parse(raw);
auto req = result.request;
CHECK(result.state == State::done);
CHECK(req->chunked);
CHECK(req->headers.fields.size() == 1);
CHECK(req->headers.get("Transfer-Encoding") == "chunked");
CHECK(req->body.parts.size() == 3);
CHECK(req->body.to_string() == "Wikipedia in\r\n\r\nchunks.");
}
TEST("chunks with extension") {
RequestParser p;
string raw =
"POST /upload HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"4;chunkextension=somevalue\r\n"
"Wiki\r\n"
"5\r\n"
"pedia\r\n"
"E\r\n"
" in\r\n"
"\r\n"
"chunks.\r\n"
"0\r\n"
"\r\n"
;
auto result = p.parse(raw);
auto req = result.request;
CHECK(result.state == State::done);
CHECK(req->headers.fields.size() == 1);
CHECK(req->headers.get("Transfer-Encoding") == "chunked");
CHECK(req->body.parts.size() == 3);
CHECK(req->body.to_string() == "Wikipedia in\r\n\r\nchunks.");
}
TEST("chunks with trailer header") {
RequestParser p;
string raw =
"POST /upload HTTP/1.1\r\n"
"Transfer-Encoding: chunked\r\n"
"Trailer: Expires\r\n"
"\r\n"
"4;chunkextension=somevalue\r\n"
"Wiki\r\n"
"5\r\n"
"pedia\r\n"
"E\r\n"
" in\r\n"
"\r\n"
"chunks.\r\n"
"0\r\n"
"Expires: Wed, 21 Oct 2015 07:28:00 GMT\r\n"
"\r\n"
;
auto result = p.parse(raw);
auto req = result.request;
CHECK(result.state == State::done);
CHECK(req->headers.fields.size() == 2);
CHECK(req->headers.get("Transfer-Encoding") == "chunked");
CHECK(req->body.parts.size() == 3);
CHECK(req->body.to_string() == "Wikipedia in\r\n\r\nchunks.");
}
TEST("fragmented chunks") {
RequestParser p;
std::vector<string> v = {
"POST /upload HTTP/1.1\r\n"
"Transfer-Enco", "ding", ": chu", "nked\r\n"
"Trailer: Expires\r\n"
"\r\n"
"4;chunkex", "tension=somevalue\r\n"
"Wiki\r\n"
"5\r\n"
"pedia\r\n"
"E\r\n"
" i", "n\r\n"
"\r\n"
"chunks.\r\n"
"0\r\n"
"Expires: Wed, 21 Oct 20", "15 07:28:00 GMT\r\n"
"\r\n"
};
RequestParser::Result result;
for (auto s : v) {
if (result.request) CHECK(result.state != State::done);
result = p.parse(s);
}
auto req = result.request;
CHECK(result.state == State::done);
CHECK(req->method_raw() == Method::Post);
CHECK(req->http_version == 11);
CHECK(req->headers.get("Transfer-Encoding") == "chunked");
CHECK(req->headers.get("Trailer") == "Expires");
CHECK(req->body.to_string() == "Wikipedia in\r\n\r\nchunks.");
}
TEST("unsupported TE") {
RequestParser p;
string raw =
"POST /upload HTTP/1.1\r\n"
"Transfer-Encoding: XXX\r\n"
;
auto result = p.parse(raw);
auto req = result.request;
CHECK(result.state == State::error);
CHECK(result.error == errc::unsupported_transfer_encoding);
}
TEST("unsupported TE (2)") {
RequestParser p;
string raw =
"POST /upload HTTP/1.1\r\n"
"Transfer-Encoding: chunked, XXX\r\n"
;
auto result = p.parse(raw);
auto req = result.request;
CHECK(result.state == State::error);
CHECK(result.error == errc::unsupported_transfer_encoding);
}