|
|
@@ -11054,6 +11054,47 @@ static const char GZIPPED_HELLO_WORLD[] = {
|
|
|
// as "fibre" look like Brotli, and turned a multi-coding value like
|
|
|
// "gzip, br" into a Brotli-labeled body, so a decompressor was run over data
|
|
|
// it was never meant to see.
|
|
|
+// RFC 9110 Section 5.3: a Content-Encoding split over several field lines is
|
|
|
+// the same message as the comma-joined one, so both have to be read the same
|
|
|
+// way. Reading only the first line made "gzip" followed by "gzip" look like a
|
|
|
+// single gzip coding, and a body the sender says was encoded twice was handed
|
|
|
+// back after one pass, still compressed but presented as decoded.
|
|
|
+TEST(ContentEncodingTest, DuplicateFieldLinesAreTheSameAsTheJoinedValue) {
|
|
|
+ const std::string body = "\xff\xd8\xff\xe0 not really a jpeg";
|
|
|
+
|
|
|
+ Server svr;
|
|
|
+ svr.Get("/split", [&](const Request & /*req*/, Response &res) {
|
|
|
+ res.set_content(body, "image/jpeg");
|
|
|
+ res.headers.emplace("Content-Encoding", "gzip");
|
|
|
+ res.headers.emplace("Content-Encoding", "gzip");
|
|
|
+ });
|
|
|
+ svr.Get("/joined", [&](const Request & /*req*/, Response &res) {
|
|
|
+ res.set_content(body, "image/jpeg");
|
|
|
+ res.set_header("Content-Encoding", "gzip, gzip");
|
|
|
+ });
|
|
|
+
|
|
|
+ auto port = svr.bind_to_any_port(HOST);
|
|
|
+ thread t = thread([&]() { svr.listen_after_bind(); });
|
|
|
+ auto se = detail::scope_exit([&] {
|
|
|
+ svr.stop();
|
|
|
+ t.join();
|
|
|
+ ASSERT_FALSE(svr.is_running());
|
|
|
+ });
|
|
|
+
|
|
|
+ svr.wait_until_ready();
|
|
|
+
|
|
|
+ Client cli(HOST, port);
|
|
|
+
|
|
|
+ // Two codings is not something cpp-httplib decodes, so both representations
|
|
|
+ // take the pass-through path rather than one of them being gunzipped once.
|
|
|
+ for (const char *path : {"/split", "/joined"}) {
|
|
|
+ auto res = cli.Get(path);
|
|
|
+ ASSERT_TRUE(res) << path << " -> " << to_string(res.error());
|
|
|
+ EXPECT_EQ(StatusCode::OK_200, res->status) << path;
|
|
|
+ EXPECT_EQ(body, res->body) << path;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
TEST(ContentEncodingTest, SubstringOfACodingIsNotTheCoding) {
|
|
|
const std::string body = "\xff\xd8\xff\xe0 not really a jpeg";
|
|
|
|