Skip to content

Commit

Permalink
feat: add multiple encoding type support
Browse files Browse the repository at this point in the history
  • Loading branch information
helintongh committed Jun 11, 2024
1 parent 90a0cfe commit c46cbf5
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 21 deletions.
6 changes: 4 additions & 2 deletions include/cinatra/coro_http_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1438,9 +1438,11 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {

#ifdef CINATRA_ENABLE_GZIP
if (!parser_.get_header_value("Content-Encoding").empty()) {
if (parser_.get_header_value("Content-Encoding") == "gzip")
if (parser_.get_header_value("Content-Encoding").find("gzip") !=
std::string_view::npos)
encoding_type_ = content_encoding::gzip;
else if (parser_.get_header_value("Content-Encoding") == "deflate")
else if (parser_.get_header_value("Content-Encoding").find("deflate") !=
std::string_view::npos)
encoding_type_ = content_encoding::deflate;
}
else {
Expand Down
4 changes: 4 additions & 0 deletions include/cinatra/coro_http_request.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ class coro_http_request {

bool is_req_ranges() { return parser_.is_req_ranges(); }

std::string get_accept_encoding() {
return std::string(get_header_value("Accept-Encoding"));
}

content_encoding get_encoding_type() {
auto encoding_type = get_header_value("Content-Encoding");
if (!encoding_type.empty()) {
Expand Down
59 changes: 42 additions & 17 deletions include/cinatra/coro_http_response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,63 @@ class coro_http_response {
}
void set_status_and_content(
status_type status, std::string content = "",
content_encoding encoding = content_encoding::none) {
set_status_and_content_view(status, std::move(content), encoding, false);
content_encoding encoding = content_encoding::none,
std::string client_encoding_type = "") {
set_status_and_content_view(status, std::move(content), encoding, false,
client_encoding_type);
}

template <typename String>
void set_status_and_content_view(
status_type status, String content = "",
content_encoding encoding = content_encoding::none, bool is_view = true) {
content_encoding encoding = content_encoding::none, bool is_view = true,
std::string_view client_encoding_type = "") {
status_ = status;
#ifdef CINATRA_ENABLE_GZIP
if (encoding == content_encoding::gzip) {
std::string encode_str;
bool r = gzip_codec::compress(content, encode_str, true);
if (!r) {
set_status_and_content(status_type::internal_server_error,
"gzip compress error");
if (client_encoding_type.empty() ||
client_encoding_type.find("gzip") != std::string_view::npos) {
std::string encode_str;
bool r = gzip_codec::compress(content, encode_str, true);
if (!r) {
set_status_and_content(status_type::internal_server_error,
"gzip compress error");
}
else {
add_header("Content-Encoding", "gzip");
set_content(std::move(encode_str));
}
}
else {
add_header("Content-Encoding", "gzip");
set_content(std::move(encode_str));
if (is_view) {
content_view_ = content;
}
else {
content_ = std::move(content);
}
}
}
else if (encoding == content_encoding::deflate) {
std::string deflate_str;
bool r = gzip_codec::deflate(content, deflate_str);
if (!r) {
set_status_and_content(status_type::internal_server_error,
"deflate compress error");
if (client_encoding_type.empty() ||
client_encoding_type.find("deflate") != std::string_view::npos) {
std::string deflate_str;
bool r = gzip_codec::deflate(content, deflate_str);
if (!r) {
set_status_and_content(status_type::internal_server_error,
"deflate compress error");
}
else {
add_header("Content-Encoding", "deflate");
set_content(std::move(deflate_str));
}
}
else {
add_header("Content-Encoding", "deflate");
set_content(std::move(deflate_str));
if (is_view) {
content_view_ = content;
}
else {
content_ = std::move(content);
}
}
}
else
Expand Down
28 changes: 26 additions & 2 deletions tests/test_cinatra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,32 @@ TEST_CASE("test encoding type") {
bool r = gzip_codec::uncompress(req.get_body(), decode_str);
CHECK(decode_str == "Hello World");
}
resp.set_status_and_content(status_type::ok, "ok", content_encoding::gzip);
resp.set_status_and_content(status_type::ok, "ok", content_encoding::gzip,
req.get_accept_encoding());
CHECK(resp.content() != "ok");
});

server.set_http_handler<GET>(
"/coro",
[](coro_http_request &req,
coro_http_response &resp) -> async_simple::coro::Lazy<void> {
resp.set_status_and_content(status_type::ok, "ok",
content_encoding::deflate);
content_encoding::deflate,
req.get_accept_encoding());
CHECK(resp.content() != "ok");
co_return;
});

server.set_http_handler<GET>(
"/only_gzip",
[](coro_http_request &req,
coro_http_response &resp) -> async_simple::coro::Lazy<void> {
resp.set_status_and_content(status_type::ok, "ok",
content_encoding::gzip,
req.get_accept_encoding());
// client4 accept-encoding not allow gzip, response content no
// compression
CHECK(resp.content() == "ok");
co_return;
});

Expand Down Expand Up @@ -107,6 +124,13 @@ TEST_CASE("test encoding type") {
result = async_simple::coro::syncAwait(client3.async_post(
"http://127.0.0.1:9001/get", ziped_str, req_content_type::none, headers));
CHECK(result.resp_body == "ok");

coro_http_client client4{};
client4.add_header("Accept-Encoding", "deflate");
result = async_simple::coro::syncAwait(
client4.async_get("http://127.0.0.1:9001/only_gzip"));
CHECK(result.resp_body == "ok");

server.stop();
}
#endif
Expand Down

0 comments on commit c46cbf5

Please sign in to comment.