From ee91f41be33f83530e9e8d2a9091aeb9fe781a4e Mon Sep 17 00:00:00 2001 From: qicosmos Date: Mon, 23 Dec 2024 17:06:37 +0800 Subject: [PATCH] fix async upload --- .../standalone/cinatra/coro_http_client.hpp | 2 + src/coro_http/tests/test_cinatra.cpp | 85 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/include/ylt/standalone/cinatra/coro_http_client.hpp b/include/ylt/standalone/cinatra/coro_http_client.hpp index 10056329c..f6ae118bf 100644 --- a/include/ylt/standalone/cinatra/coro_http_client.hpp +++ b/include/ylt/standalone/cinatra/coro_http_client.hpp @@ -1101,6 +1101,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/src/coro_http/tests/test_cinatra.cpp b/src/coro_http/tests/test_cinatra.cpp index 2194542a4..584b500fa 100644 --- a/src/coro_http/tests/test_cinatra.cpp +++ b/src/coro_http/tests/test_cinatra.cpp @@ -885,6 +885,91 @@ 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); + auto result = co_await client.async_request(uri, http_method::GET, + req_context<>{}, {}, 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 << oubuf.data() << "\n"; + + std::string_view out_view1(oubuf.data(), out_view.size()); + assert(out_view == out_view1); + assert(result.resp_body != out_view1); + + result = co_await client.async_request(uri, http_method::GET, + req_context<>{}, {}, oubuf); + std::cout << oubuf.data() << "\n"; + + std::string_view out_view2(oubuf.data(), result.resp_body.size()); + assert(out_view2 == "test"); + assert(out_view2 == result.resp_body); + }; + + 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)); +} + TEST_CASE("test multipart and chunked return error") { coro_http_server server(1, 8090); server.set_http_handler(