Skip to content

Commit

Permalink
feat: add compress api for coro client
Browse files Browse the repository at this point in the history
  • Loading branch information
helintongh committed Jun 10, 2024
1 parent 314c475 commit 90a0cfe
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 2 deletions.
34 changes: 33 additions & 1 deletion include/cinatra/coro_http_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,18 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
if (is_redirect)
redirect_uri_ = parser_.get_header_value("Location");

#ifdef CINATRA_ENABLE_GZIP
if (!parser_.get_header_value("Content-Encoding").empty()) {
if (parser_.get_header_value("Content-Encoding") == "gzip")
encoding_type_ = content_encoding::gzip;
else if (parser_.get_header_value("Content-Encoding") == "deflate")
encoding_type_ = content_encoding::deflate;
}
else {
encoding_type_ = content_encoding::none;
}
#endif

size_t content_len = (size_t)parser_.body_len();
#ifdef BENCHMARK_TEST
total_len_ = parser_.total_len();
Expand Down Expand Up @@ -1541,7 +1553,26 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
}

std::string_view reply(data_ptr, content_len);
data.resp_body = reply;
#ifdef CINATRA_ENABLE_GZIP
if (encoding_type_ == content_encoding::gzip) {
std::string unziped_str;
bool r = gzip_codec::uncompress(reply, unziped_str);
if (r)
data.resp_body = unziped_str;
else
data.resp_body = reply;
}
else if (encoding_type_ == content_encoding::deflate) {
std::string inflate_str;
bool r = gzip_codec::inflate(reply, inflate_str);
if (r)
data.resp_body = inflate_str;
else
data.resp_body = reply;
}
else
#endif
data.resp_body = reply;

head_buf_.consume(content_len);
}
Expand Down Expand Up @@ -2066,6 +2097,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
bool enable_ws_deflate_ = false;
bool is_server_support_ws_deflate_ = false;
std::string inflate_str_;
content_encoding encoding_type_ = content_encoding::none;
#endif

#ifdef BENCHMARK_TEST
Expand Down
15 changes: 15 additions & 0 deletions include/cinatra/coro_http_request.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,21 @@ class coro_http_request {

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

content_encoding get_encoding_type() {
auto encoding_type = get_header_value("Content-Encoding");
if (!encoding_type.empty()) {
if (encoding_type.find("gzip") != std::string_view::npos)
return content_encoding::gzip;
else if (encoding_type.find("deflate") != std::string_view::npos)
return content_encoding::deflate;
else
return content_encoding::none;
}
else {
return content_encoding::none;
}
}

content_type get_content_type() {
if (is_chunked())
return content_type::chunked;
Expand Down
12 changes: 12 additions & 0 deletions include/cinatra/coro_http_response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ class coro_http_response {
set_content(std::move(encode_str));
}
}
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");
}
else {
add_header("Content-Encoding", "deflate");
set_content(std::move(deflate_str));
}
}
else
#endif
{
Expand Down
1 change: 1 addition & 0 deletions include/cinatra/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum class http_method {
OPTIONS,
DEL,
};
enum class content_encoding { gzip, deflate, none };
constexpr inline auto GET = http_method::GET;
constexpr inline auto POST = http_method::POST;
constexpr inline auto DEL = http_method::DEL;
Expand Down
1 change: 0 additions & 1 deletion include/cinatra/response_cv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "define.h"

namespace cinatra {
enum class content_encoding { gzip, none };

enum class status_type {
init,
Expand Down
53 changes: 53 additions & 0 deletions tests/test_cinatra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,59 @@ TEST_CASE("test for gzip") {
CHECK(decompress_data == "hello world");
server.stop();
}

TEST_CASE("test encoding type") {
coro_http_server server(1, 9001);

server.set_http_handler<GET, POST>("/get", [](coro_http_request &req,
coro_http_response &resp) {
auto encoding_type = req.get_encoding_type();

if (encoding_type ==
content_encoding::gzip) { // only post request have this field
std::string decode_str;
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);
});

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);
co_return;
});

server.async_start();
std::this_thread::sleep_for(std::chrono::milliseconds(100));

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

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

coro_http_client client3{};
std::unordered_map<std::string, std::string> headers = {
{"Content-Encoding", "gzip"},
};
std::string ziped_str;
std::string_view data = "Hello World";
gzip_codec::compress(data, ziped_str);
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");
server.stop();
}
#endif

#ifdef CINATRA_ENABLE_SSL
Expand Down

0 comments on commit 90a0cfe

Please sign in to comment.