diff --git a/.github/workflows/linux_llvm_cov.yml b/.github/workflows/linux_llvm_cov.yml index a9906dba8..7a48f3040 100644 --- a/.github/workflows/linux_llvm_cov.yml +++ b/.github/workflows/linux_llvm_cov.yml @@ -32,11 +32,12 @@ jobs: ls mkdir build && cd build CC=clang-17 CXX=clang++-17 cmake .. -DCOVERAGE_TEST=ON -DENABLE_SSL=ON - make -j test_rpc - export LLVM_PROFILE_FILE="test_rpc-%m.profraw" - ./tests/test_rpc - llvm-profdata merge -sparse test_rpc-*.profraw -o test_rpc.profdata - llvm-cov show ./tests/test_rpc -instr-profile=test_rpc.profdata -format=html -output-dir=../.coverage_llvm_cov -ignore-filename-regex="thirdparty|asio" -show-instantiations=false + make -j + export LLVM_PROFILE_FILE="test_ylt-%m.profraw" + cd output + ./tests/coro_io_test ./tests/coro_rpc_test ./tests/easylog_test ./tests/struct_pack_test ./tests/struct_pack_test_with_optimize + llvm-profdata merge -sparse test_ylt-*.profraw -o test_ylt.profdata + llvm-cov show ./tests/coro_io_test ./tests/coro_rpc_test ./tests/easylog_test ./tests/struct_pack_test ./tests/struct_pack_test_with_optimize -instr-profile=test_ylt.profdata -format=html -output-dir=../.coverage_llvm_cov -ignore-filename-regex="thirdparty|asio" -show-instantiations=false echo "Done!" - name: Upload Coverage Results @@ -51,7 +52,7 @@ jobs: echo "Code Coverage Report" > tmp.log echo "for detail, [goto summary](https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }}/actions/runs/${{github.run_id}}) download Artifacts `llvm-cov`" >> tmp.log echo "\`\`\`" >> tmp.log - llvm-cov report ./tests/test_rpc -instr-profile=test_rpc.profdata -ignore-filename-regex="thirdparty|asio" -show-region-summary=false >> tmp.log + llvm-cov report ./tests/coro_io_test ./tests/coro_rpc_test ./tests/easylog_test ./tests/struct_pack_test ./tests/struct_pack_test_with_optimize -instr-profile=test_ylt.profdata -ignore-filename-regex="thirdparty|asio" -show-region-summary=false >> tmp.log echo "\`\`\`" >> tmp.log - name: Create Comment diff --git a/coverage_gen.sh b/coverage_gen.sh index cf99f07ad..d6e976f95 100644 --- a/coverage_gen.sh +++ b/coverage_gen.sh @@ -25,18 +25,18 @@ mkdir build && cd build || exit 1 export CC=clang export CXX=clang++ cmake .. -DCOVERAGE_TEST=ON -DENABLE_SSL=ON -make -j test_rpc +make -j -# warning: test_rpc.profraw: malformed instrumentation profile data +# warning: test_ylt.profraw: malformed instrumentation profile data # error: no profile can be merged # add %m to fix the bug on ARM # https://groups.google.com/g/llvm-dev/c/oaA58fbNMGg # https://github.com/llvm/llvm-project/issues/50966 -export LLVM_PROFILE_FILE="coro_rpc_test-%m.profraw" +export LLVM_PROFILE_FILE="ylt_test-%m.profraw" ls -cd tests -./test_rpc -llvm-profdata merge -sparse coro_rpc_test-*.profraw -o coro_rpc_test.profdata -llvm-cov show ./coro_rpc_test -instr-profile=test_rpc.profdata -format=html -output-dir=../../.coverage_llvm_cov -ignore-filename-regex="async_simple|thirdparty|tests|asio|util|logging|struct_pack" -show-instantiations=false +cd output +./tests/coro_io_test ./tests/coro_rpc_test ./tests/easylog_test ./tests/struct_pack_test ./tests/struct_pack_test_with_optimize +llvm-profdata merge -sparse ylt_test-*.profraw -o ylt_test.profdata +llvm-cov show ./tests/coro_io_test ./tests/coro_rpc_test ./tests/easylog_test ./tests/struct_pack_test ./tests/struct_pack_test_with_optimize -instr-profile=test_ylt.profdata -format=html -output-dir=../../.coverage_llvm_cov -ignore-filename-regex="thirdparty|asio" -show-instantiations=false echo 'Done!!!' fi diff --git a/include/ylt/thirdparty/cinatra/coro_http_client.hpp b/include/ylt/thirdparty/cinatra/coro_http_client.hpp index 3d8b46b29..34219e57e 100644 --- a/include/ylt/thirdparty/cinatra/coro_http_client.hpp +++ b/include/ylt/thirdparty/cinatra/coro_http_client.hpp @@ -246,7 +246,7 @@ class coro_http_client : public std::enable_shared_from_this { return true; } - [[nodiscard]] bool init_ssl(int verify_mode = asio::ssl::verify_peer, + [[nodiscard]] bool init_ssl(int verify_mode = asio::ssl::verify_none, std::string full_path = "", const std::string &sni_hostname = "") { std::string base_path; diff --git a/include/ylt/thirdparty/cinatra/coro_http_response.hpp b/include/ylt/thirdparty/cinatra/coro_http_response.hpp index 4b8c3b88e..d035a466c 100644 --- a/include/ylt/thirdparty/cinatra/coro_http_response.hpp +++ b/include/ylt/thirdparty/cinatra/coro_http_response.hpp @@ -12,6 +12,9 @@ #include "async_simple/coro/SyncAwait.h" #include "cookie.hpp" #include "define.h" +#ifdef CINATRA_ENABLE_GZIP +#include "gzip.hpp" +#endif #include "response_cv.hpp" #include "time_util.hpp" #include "utils.hpp" @@ -46,9 +49,29 @@ class coro_http_response { content_ = std::move(content); has_set_content_ = true; } - void set_status_and_content(status_type status, std::string content = "") { + void set_status_and_content( + status_type status, std::string content = "", + content_encoding encoding = content_encoding::none) { status_ = status; - content_ = std::move(content); +#ifdef CINATRA_ENABLE_GZIP + if (encoding == content_encoding::gzip) { + std::string encode_str; + bool r = gzip_codec::compress( + std::string_view(content.data(), content.length()), 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 +#endif + { + content_ = std::move(content); + } has_set_content_ = true; } void set_delay(bool r) { delay_ = r; } diff --git a/src/coro_http/examples/example.cpp b/src/coro_http/examples/example.cpp index 9ba4fb353..607310e44 100644 --- a/src/coro_http/examples/example.cpp +++ b/src/coro_http/examples/example.cpp @@ -405,6 +405,41 @@ async_simple::coro::Lazy basic_usage() { #endif } +#ifdef CINATRA_ENABLE_GZIP +std::string_view get_header_value(auto &resp_headers, std::string_view key) { + for (const auto &[k, v] : resp_headers) { + if (k == key) + return v; + } + return {}; +} + +void test_gzip() { + coro_http_server server(1, 8090); + server.set_http_handler( + "/gzip", [](coro_http_request &req, coro_http_response &res) { + assert(req.get_header_value("Content-Encoding") == "gzip"); + res.set_status_and_content(status_type::ok, "hello world", + content_encoding::gzip); + }); + server.async_start(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + coro_http_client client{}; + std::string uri = "http://127.0.0.1:8090/gzip"; + client.add_header("Content-Encoding", "gzip"); + auto result = async_simple::coro::syncAwait(client.async_get(uri)); + auto content = get_header_value(result.resp_headers, "Content-Encoding"); + assert(get_header_value(result.resp_headers, "Content-Encoding") == "gzip"); + std::string decompress_data; + bool ret = gzip_codec::uncompress(result.resp_body, decompress_data); + assert(ret == true); + assert(decompress_data == "hello world"); + server.stop(); +} +#endif + int main() { async_simple::coro::syncAwait(basic_usage()); async_simple::coro::syncAwait(use_aspects()); @@ -412,5 +447,8 @@ int main() { async_simple::coro::syncAwait(use_websocket()); async_simple::coro::syncAwait(chunked_upload_download()); async_simple::coro::syncAwait(byte_ranges_download()); +#ifdef CINATRA_ENABLE_GZIP + test_gzip(); +#endif return 0; } \ No newline at end of file