mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
Added 'compress' option to POST, PUT and PATCH.
This commit is contained in:
parent
380f725713
commit
bea3ebd7af
2 changed files with 69 additions and 92 deletions
107
httplib.h
107
httplib.h
|
@ -589,36 +589,37 @@ public:
|
|||
std::shared_ptr<Response> Head(const char *path, const Headers &headers);
|
||||
|
||||
std::shared_ptr<Response> Post(const char *path, const std::string &body,
|
||||
const char *content_type);
|
||||
const char *content_type, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Post(const char *path, const Headers &headers,
|
||||
const std::string &body,
|
||||
const char *content_type);
|
||||
const char *content_type,
|
||||
bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Post(const char *path, const Params ¶ms);
|
||||
std::shared_ptr<Response> Post(const char *path, const Params ¶ms, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Post(const char *path, const Headers &headers,
|
||||
const Params ¶ms);
|
||||
const Params ¶ms, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Post(const char *path,
|
||||
const MultipartFormDataItems &items);
|
||||
const MultipartFormDataItems &items, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Post(const char *path, const Headers &headers,
|
||||
const MultipartFormDataItems &items);
|
||||
const MultipartFormDataItems &items, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Put(const char *path, const std::string &body,
|
||||
const char *content_type);
|
||||
const char *content_type, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Put(const char *path, const Headers &headers,
|
||||
const std::string &body,
|
||||
const char *content_type);
|
||||
const char *content_type, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Patch(const char *path, const std::string &body,
|
||||
const char *content_type);
|
||||
const char *content_type, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Patch(const char *path, const Headers &headers,
|
||||
const std::string &body,
|
||||
const char *content_type);
|
||||
const char *content_type, bool compress = false);
|
||||
|
||||
std::shared_ptr<Response> Delete(const char *path);
|
||||
|
||||
|
@ -3119,14 +3120,14 @@ inline std::shared_ptr<Response> Client::Head(const char *path,
|
|||
|
||||
inline std::shared_ptr<Response> Client::Post(const char *path,
|
||||
const std::string &body,
|
||||
const char *content_type) {
|
||||
return Post(path, Headers(), body, content_type);
|
||||
const char *content_type, bool compress) {
|
||||
return Post(path, Headers(), body, content_type, compress);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response> Client::Post(const char *path,
|
||||
const Headers &headers,
|
||||
const std::string &body,
|
||||
const char *content_type) {
|
||||
const char *content_type, bool compress) {
|
||||
Request req;
|
||||
req.method = "POST";
|
||||
req.headers = headers;
|
||||
|
@ -3135,18 +3136,25 @@ inline std::shared_ptr<Response> Client::Post(const char *path,
|
|||
req.headers.emplace("Content-Type", content_type);
|
||||
req.body = body;
|
||||
|
||||
if (compress) {
|
||||
if (!detail::compress(req.body)) {
|
||||
return nullptr;
|
||||
}
|
||||
req.headers.emplace("Content-Encoding", "gzip");
|
||||
}
|
||||
|
||||
auto res = std::make_shared<Response>();
|
||||
|
||||
return send(req, *res) ? res : nullptr;
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response> Client::Post(const char *path,
|
||||
const Params ¶ms) {
|
||||
return Post(path, Headers(), params);
|
||||
const Params ¶ms, bool compress) {
|
||||
return Post(path, Headers(), params, compress);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response>
|
||||
Client::Post(const char *path, const Headers &headers, const Params ¶ms) {
|
||||
Client::Post(const char *path, const Headers &headers, const Params ¶ms, bool compress) {
|
||||
std::string query;
|
||||
for (auto it = params.begin(); it != params.end(); ++it) {
|
||||
if (it != params.begin()) { query += "&"; }
|
||||
|
@ -3155,58 +3163,53 @@ Client::Post(const char *path, const Headers &headers, const Params ¶ms) {
|
|||
query += detail::encode_url(it->second);
|
||||
}
|
||||
|
||||
return Post(path, headers, query, "application/x-www-form-urlencoded");
|
||||
return Post(path, headers, query, "application/x-www-form-urlencoded", compress);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response>
|
||||
Client::Post(const char *path, const MultipartFormDataItems &items) {
|
||||
return Post(path, Headers(), items);
|
||||
Client::Post(const char *path, const MultipartFormDataItems &items, bool compress) {
|
||||
return Post(path, Headers(), items, compress);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response>
|
||||
Client::Post(const char *path, const Headers &headers,
|
||||
const MultipartFormDataItems &items) {
|
||||
Request req;
|
||||
req.method = "POST";
|
||||
req.headers = headers;
|
||||
req.path = path;
|
||||
|
||||
const MultipartFormDataItems &items, bool compress) {
|
||||
auto boundary = detail::make_multipart_data_boundary();
|
||||
|
||||
req.headers.emplace("Content-Type",
|
||||
"multipart/form-data; boundary=" + boundary);
|
||||
std::string body;
|
||||
|
||||
for (const auto &item : items) {
|
||||
req.body += "--" + boundary + "\r\n";
|
||||
req.body += "Content-Disposition: form-data; name=\"" + item.name + "\"";
|
||||
body += "--" + boundary + "\r\n";
|
||||
body += "Content-Disposition: form-data; name=\"" + item.name + "\"";
|
||||
if (!item.filename.empty()) {
|
||||
req.body += "; filename=\"" + item.filename + "\"";
|
||||
body += "; filename=\"" + item.filename + "\"";
|
||||
}
|
||||
req.body += "\r\n";
|
||||
body += "\r\n";
|
||||
if (!item.content_type.empty()) {
|
||||
req.body += "Content-Type: " + item.content_type + "\r\n";
|
||||
body += "Content-Type: " + item.content_type + "\r\n";
|
||||
}
|
||||
req.body += "\r\n";
|
||||
req.body += item.content + "\r\n";
|
||||
body += "\r\n";
|
||||
body += item.content + "\r\n";
|
||||
}
|
||||
|
||||
req.body += "--" + boundary + "--\r\n";
|
||||
body += "--" + boundary + "--\r\n";
|
||||
|
||||
auto res = std::make_shared<Response>();
|
||||
|
||||
return send(req, *res) ? res : nullptr;
|
||||
std::string content_type = "multipart/form-data; boundary=" + boundary;
|
||||
return Post(path, headers, body, content_type.c_str(), compress);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response> Client::Put(const char *path,
|
||||
const std::string &body,
|
||||
const char *content_type) {
|
||||
return Put(path, Headers(), body, content_type);
|
||||
const char *content_type,
|
||||
bool compress) {
|
||||
return Put(path, Headers(), body, content_type, compress);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response> Client::Put(const char *path,
|
||||
const Headers &headers,
|
||||
const std::string &body,
|
||||
const char *content_type) {
|
||||
const char *content_type,
|
||||
bool compress) {
|
||||
Request req;
|
||||
req.method = "PUT";
|
||||
req.headers = headers;
|
||||
|
@ -3215,6 +3218,13 @@ inline std::shared_ptr<Response> Client::Put(const char *path,
|
|||
req.headers.emplace("Content-Type", content_type);
|
||||
req.body = body;
|
||||
|
||||
if (compress) {
|
||||
if (!detail::compress(req.body)) {
|
||||
return nullptr;
|
||||
}
|
||||
req.headers.emplace("Content-Encoding", "gzip");
|
||||
}
|
||||
|
||||
auto res = std::make_shared<Response>();
|
||||
|
||||
return send(req, *res) ? res : nullptr;
|
||||
|
@ -3222,14 +3232,16 @@ inline std::shared_ptr<Response> Client::Put(const char *path,
|
|||
|
||||
inline std::shared_ptr<Response> Client::Patch(const char *path,
|
||||
const std::string &body,
|
||||
const char *content_type) {
|
||||
return Patch(path, Headers(), body, content_type);
|
||||
const char *content_type,
|
||||
bool compress) {
|
||||
return Patch(path, Headers(), body, content_type, compress);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<Response> Client::Patch(const char *path,
|
||||
const Headers &headers,
|
||||
const std::string &body,
|
||||
const char *content_type) {
|
||||
const char *content_type,
|
||||
bool compress) {
|
||||
Request req;
|
||||
req.method = "PATCH";
|
||||
req.headers = headers;
|
||||
|
@ -3238,6 +3250,13 @@ inline std::shared_ptr<Response> Client::Patch(const char *path,
|
|||
req.headers.emplace("Content-Type", content_type);
|
||||
req.body = body;
|
||||
|
||||
if (compress) {
|
||||
if (!detail::compress(req.body)) {
|
||||
return nullptr;
|
||||
}
|
||||
req.headers.emplace("Content-Encoding", "gzip");
|
||||
}
|
||||
|
||||
auto res = std::make_shared<Response>();
|
||||
|
||||
return send(req, *res) ? res : nullptr;
|
||||
|
|
54
test/test.cc
54
test/test.cc
|
@ -1549,56 +1549,14 @@ TEST_F(ServerTest, NoGzipWithContentReceiver) {
|
|||
}
|
||||
|
||||
TEST_F(ServerTest, MultipartFormDataGzip) {
|
||||
Request req;
|
||||
req.method = "POST";
|
||||
req.path = "/gzipmultipart";
|
||||
MultipartFormDataItems items = {
|
||||
{"key1", "test", "", ""},
|
||||
{"key2", "--abcdefg123", "", ""},
|
||||
};
|
||||
|
||||
std::string host_and_port;
|
||||
host_and_port += HOST;
|
||||
host_and_port += ":";
|
||||
host_and_port += std::to_string(PORT);
|
||||
auto res = cli_.Post("/gzipmultipart", items, true);
|
||||
|
||||
req.headers.emplace("Host", host_and_port.c_str());
|
||||
req.headers.emplace("Accept", "*/*");
|
||||
req.headers.emplace("User-Agent", "cpp-httplib/0.1");
|
||||
req.headers.emplace(
|
||||
"Content-Type",
|
||||
"multipart/form-data; boundary=------------------------fcba8368a9f48c0f");
|
||||
req.headers.emplace("Content-Encoding", "gzip");
|
||||
|
||||
// compressed_body generated by creating input.txt to this file:
|
||||
/*
|
||||
--------------------------fcba8368a9f48c0f
|
||||
Content-Disposition: form-data; name="key1"
|
||||
|
||||
test
|
||||
--------------------------fcba8368a9f48c0f
|
||||
Content-Disposition: form-data; name="key2"
|
||||
|
||||
--abcdefg123
|
||||
--------------------------fcba8368a9f48c0f--
|
||||
*/
|
||||
// then running unix2dos input.txt; gzip -9 -c input.txt | xxd -i.
|
||||
uint8_t compressed_body[] = {
|
||||
0x1f, 0x8b, 0x08, 0x08, 0x48, 0xf1, 0xd4, 0x5a, 0x02, 0x03, 0x69, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x2e, 0x74, 0x78, 0x74, 0x00, 0xd3, 0xd5, 0xc5, 0x05,
|
||||
0xd2, 0x92, 0x93, 0x12, 0x2d, 0x8c, 0xcd, 0x2c, 0x12, 0x2d, 0xd3, 0x4c,
|
||||
0x2c, 0x92, 0x0d, 0xd2, 0x78, 0xb9, 0x9c, 0xf3, 0xf3, 0x4a, 0x52, 0xf3,
|
||||
0x4a, 0x74, 0x5d, 0x32, 0x8b, 0x0b, 0xf2, 0x8b, 0x33, 0x4b, 0x32, 0xf3,
|
||||
0xf3, 0xac, 0x14, 0xd2, 0xf2, 0x8b, 0x72, 0x75, 0x53, 0x12, 0x4b, 0x12,
|
||||
0xad, 0x15, 0xf2, 0x12, 0x73, 0x53, 0x6d, 0x95, 0xb2, 0x53, 0x2b, 0x0d,
|
||||
0x95, 0x78, 0xb9, 0x78, 0xb9, 0x4a, 0x52, 0x8b, 0x4b, 0x78, 0xb9, 0x74,
|
||||
0x69, 0x61, 0x81, 0x11, 0xd8, 0x02, 0x5d, 0xdd, 0xc4, 0xa4, 0xe4, 0x94,
|
||||
0xd4, 0xb4, 0x74, 0x43, 0x23, 0x63, 0x52, 0x2c, 0xd2, 0xd5, 0xe5, 0xe5,
|
||||
0x02, 0x00, 0xff, 0x0e, 0x72, 0xdf, 0xf8, 0x00, 0x00, 0x00};
|
||||
|
||||
req.body = std::string((char *)compressed_body,
|
||||
sizeof(compressed_body) / sizeof(compressed_body[0]));
|
||||
|
||||
auto res = std::make_shared<Response>();
|
||||
auto ret = cli_.send(req, *res);
|
||||
|
||||
ASSERT_TRUE(ret);
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
EXPECT_EQ(200, res->status);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue