diff --git a/include/cinatra/coro_http_client.hpp b/include/cinatra/coro_http_client.hpp index f8d190db..71dd9519 100644 --- a/include/cinatra/coro_http_client.hpp +++ b/include/cinatra/coro_http_client.hpp @@ -1106,6 +1106,8 @@ class coro_http_client : public std::enable_shared_from_this { req_context<> ctx{content_type}; resp_data data{}; + out_buf_ = {}; + std::shared_ptr guard(nullptr, [&, this](auto) { if (!req_headers_.empty()) { req_headers_.clear(); diff --git a/include/cinatra/ylt/metric/metric_manager.hpp b/include/cinatra/ylt/metric/metric_manager.hpp index 32c5da4d..4a030ec6 100644 --- a/include/cinatra/ylt/metric/metric_manager.hpp +++ b/include/cinatra/ylt/metric/metric_manager.hpp @@ -460,10 +460,11 @@ class dynamic_metric_manager { private: void clean_label_expired() { executor_ = coro_io::create_io_context_pool(1); + auto sp = executor_; timer_ = std::make_shared(executor_->get_executor()); check_label_expired(timer_) .via(executor_->get_executor()) - .start([](auto&&) { + .start([sp](auto&&) { }); } diff --git a/tests/test_cinatra.cpp b/tests/test_cinatra.cpp index f7d75406..ff5e145d 100644 --- a/tests/test_cinatra.cpp +++ b/tests/test_cinatra.cpp @@ -913,6 +913,85 @@ TEST_CASE("test pipeline") { } #endif +enum class upload_type { send_file, chunked, multipart }; + +TEST_CASE("test out buffer and async upload ") { + coro_http_server server(1, 9000); + server.set_http_handler( + "/write_chunked", + [](coro_http_request &req, + coro_http_response &resp) -> async_simple::coro::Lazy { + resp.set_format_type(format_type::chunked); + bool ok; + if (ok = co_await resp.get_conn()->begin_chunked(); !ok) { + co_return; + } + + std::vector vec{"hello", " world", " ok"}; + + for (auto &str : vec) { + if (ok = co_await resp.get_conn()->write_chunked(str); !ok) { + co_return; + } + } + + ok = co_await resp.get_conn()->end_chunked(); + }); + server.set_http_handler( + "/normal", [](coro_http_request &req, coro_http_response &resp) { + resp.set_status_and_content(status_type::ok, "test"); + }); + server.set_http_handler( + "/more", [](coro_http_request &req, coro_http_response &resp) { + resp.set_status_and_content(status_type::ok, "test more"); + }); + + server.async_start(); + + auto lazy = [](upload_type flag) -> async_simple::coro::Lazy { + coro_http_client client{}; + std::string uri = "http://127.0.0.1:9000/normal"; + std::vector oubuf; + oubuf.resize(10); + req_context<> ctx{}; + auto result = co_await client.async_request(uri, http_method::GET, + std::move(ctx), {}, oubuf); + std::cout << oubuf.data() << "\n"; + + std::string_view out_view(oubuf.data(), result.resp_body.size()); + assert(out_view == "test"); + assert(out_view == result.resp_body); + + auto ss = std::make_shared(); + *ss << "hello world"; + + if (flag == upload_type::send_file) { + result = co_await client.async_upload("http://127.0.0.1:9000/more"sv, + http_method::POST, ss); + } + else if (flag == upload_type::chunked) { + result = co_await client.async_upload_chunked( + "http://127.0.0.1:9000/more"sv, http_method::POST, ss); + } + else if (flag == upload_type::multipart) { + client.add_str_part("test_key", "test_value"); + result = + co_await client.async_upload_multipart("http://127.0.0.1:9000/more"); + } + + std::cout << (int)flag << oubuf.data() << "\n"; + std::cout << result.resp_body << "\n"; + + std::string_view out_view1(oubuf.data(), out_view.size()); + assert(out_view == out_view1); + assert(result.resp_body != out_view1); + }; + + async_simple::coro::syncAwait(lazy(upload_type::send_file)); + async_simple::coro::syncAwait(lazy(upload_type::chunked)); + async_simple::coro::syncAwait(lazy(upload_type::multipart)); +} + async_simple::coro::Lazy send_data(auto &ch, size_t count) { for (int i = 0; i < count; i++) { co_await coro_io::async_send(ch, i);