|
@@ -3015,8 +3015,10 @@ TEST(GzipDecompressor, ChunkedDecompression) {
|
|
|
httplib::detail::gzip_compressor compressor;
|
|
httplib::detail::gzip_compressor compressor;
|
|
|
bool result = compressor.compress(
|
|
bool result = compressor.compress(
|
|
|
data.data(), data.size(),
|
|
data.data(), data.size(),
|
|
|
- /*last=*/true, [&](const char *compressed_data_chunk, size_t compressed_data_size) {
|
|
|
|
|
- compressed_data.insert(compressed_data.size(), compressed_data_chunk, compressed_data_size);
|
|
|
|
|
|
|
+ /*last=*/true,
|
|
|
|
|
+ [&](const char *compressed_data_chunk, size_t compressed_data_size) {
|
|
|
|
|
+ compressed_data.insert(compressed_data.size(), compressed_data_chunk,
|
|
|
|
|
+ compressed_data_size);
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|
|
|
ASSERT_TRUE(result);
|
|
ASSERT_TRUE(result);
|
|
@@ -3035,8 +3037,11 @@ TEST(GzipDecompressor, ChunkedDecompression) {
|
|
|
std::min(compressed_data.size() - chunk_begin, chunk_size);
|
|
std::min(compressed_data.size() - chunk_begin, chunk_size);
|
|
|
bool result = decompressor.decompress(
|
|
bool result = decompressor.decompress(
|
|
|
compressed_data.data() + chunk_begin, current_chunk_size,
|
|
compressed_data.data() + chunk_begin, current_chunk_size,
|
|
|
- [&](const char *decompressed_data_chunk, size_t decompressed_data_chunk_size) {
|
|
|
|
|
- decompressed_data.insert(decompressed_data.size(), decompressed_data_chunk, decompressed_data_chunk_size);
|
|
|
|
|
|
|
+ [&](const char *decompressed_data_chunk,
|
|
|
|
|
+ size_t decompressed_data_chunk_size) {
|
|
|
|
|
+ decompressed_data.insert(decompressed_data.size(),
|
|
|
|
|
+ decompressed_data_chunk,
|
|
|
|
|
+ decompressed_data_chunk_size);
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|
|
|
ASSERT_TRUE(result);
|
|
ASSERT_TRUE(result);
|
|
@@ -4974,5 +4979,48 @@ TEST(MultipartFormDataTest, LargeData) {
|
|
|
svr.stop();
|
|
svr.stop();
|
|
|
t.join();
|
|
t.join();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+TEST(MultipartFormDataTest, WithPreamble) {
|
|
|
|
|
+ Server svr;
|
|
|
|
|
+ svr.Post("/post", [&](const Request &req, Response &res) {
|
|
|
|
|
+ res.set_content("ok", "text/plain");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ thread t = thread([&] { svr.listen(HOST, PORT); });
|
|
|
|
|
+ while (!svr.is_running()) {
|
|
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const std::string body =
|
|
|
|
|
+ "This is the preamble. It is to be ignored, though it\r\n"
|
|
|
|
|
+ "is a handy place for composition agents to include an\r\n"
|
|
|
|
|
+ "explanatory note to non-MIME conformant readers.\r\n"
|
|
|
|
|
+ "\r\n"
|
|
|
|
|
+ "\r\n"
|
|
|
|
|
+ "--simple boundary\r\n"
|
|
|
|
|
+ "Content-Disposition: form-data; name=\"field1\"\r\n"
|
|
|
|
|
+ "\r\n"
|
|
|
|
|
+ "value1\r\n"
|
|
|
|
|
+ "--simple boundary\r\n"
|
|
|
|
|
+ "Content-Disposition: form-data; name=\"field2\"; "
|
|
|
|
|
+ "filename=\"example.txt\"\r\n"
|
|
|
|
|
+ "\r\n"
|
|
|
|
|
+ "value2\r\n"
|
|
|
|
|
+ "--simple boundary--\r\n"
|
|
|
|
|
+ "This is the epilogue. It is also to be ignored.\r\n";
|
|
|
|
|
+
|
|
|
|
|
+ std::string content_type =
|
|
|
|
|
+ R"(multipart/form-data; boundary="simple boundary")";
|
|
|
|
|
+
|
|
|
|
|
+ Client cli(HOST, PORT);
|
|
|
|
|
+ auto res = cli.Post("/post", body, content_type.c_str());
|
|
|
|
|
+
|
|
|
|
|
+ ASSERT_TRUE(res);
|
|
|
|
|
+ EXPECT_EQ(200, res->status);
|
|
|
|
|
+
|
|
|
|
|
+ svr.stop();
|
|
|
|
|
+ t.join();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|