diff --git a/README.md b/README.md index 0acf467a..d4c0b677 100644 --- a/README.md +++ b/README.md @@ -418,17 +418,50 @@ async_simple::coro::Lazy test_async_client() { ``` ### upload(multipart) file +```cpp +void start_server() { + coro_http_server server(1, 9001); + server.set_http_handler( + "/form_data", + [](coro_http_request &req, + coro_http_response &resp) -> async_simple::coro::Lazy { + assert(req.get_content_type() == content_type::multipart); + auto boundary = req.get_boundary(); + multipart_reader_t multipart(req.get_conn()); + while (true) { + auto part_head = co_await multipart.read_part_head(); + if (part_head.ec) { + co_return; + } + + std::cout << part_head.name << "\n"; + std::cout << part_head.filename << "\n";// if form data, no filename + + auto part_body = co_await multipart.read_part_body(boundary); + if (part_body.ec) { + co_return; + } + + std::cout << part_body.data << "\n"; + + if (part_body.eof) { + break; + } + } + + resp.set_status_and_content(status_type::ok, "multipart finished"); + }); + server.start(); +} +``` ``` async_simple::coro::Lazy test_upload() { - std::string uri = "http://example.com/"; + std::string uri = "http://127.0.0.1:9001/form_data"; coro_http_client client{}; - auto result = co_await client.async_upload(uri, "test", "yourfile.jpg"); - print(result.status); - std::cout << "upload finished\n"; client.add_str_part("hello", "coro_http_client"); client.add_file_part("test", "yourfile.jpg"); - result = co_await client.async_upload(uri); + result = co_await client.async_upload_multipart(uri); print(result.status); std::cout << "upload finished\n"; } diff --git a/example/main.cpp b/example/main.cpp index 7dd4123b..9129d7fd 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -297,6 +297,37 @@ async_simple::coro::Lazy basic_usage() { co_return; }); + server.set_http_handler( + "/form_data", + [](coro_http_request &req, + coro_http_response &resp) -> async_simple::coro::Lazy { + assert(req.get_content_type() == content_type::multipart); + auto boundary = req.get_boundary(); + multipart_reader_t multipart(req.get_conn()); + while (true) { + auto part_head = co_await multipart.read_part_head(); + if (part_head.ec) { + co_return; + } + + std::cout << part_head.name << "\n"; + std::cout << part_head.filename << "\n"; // if form data, no filename + + auto part_body = co_await multipart.read_part_body(boundary); + if (part_body.ec) { + co_return; + } + + std::cout << part_body.data << "\n"; + + if (part_body.eof) { + break; + } + } + + resp.set_status_and_content(status_type::ok, "multipart finished"); + }); + server.set_http_handler( "/in_thread_pool", [](coro_http_request &req, @@ -343,7 +374,7 @@ async_simple::coro::Lazy basic_usage() { person_t person{}; server.set_http_handler("/person", &person_t::foo, person); - server.async_start(); + server.sync_start(); std::this_thread::sleep_for(300ms); // wait for server start coro_http_client client{}; @@ -357,6 +388,13 @@ async_simple::coro::Lazy basic_usage() { result = co_await client.async_get("/coro"); assert(result.status == 200); + client.add_str_part("hello", "form_data"); + client.add_str_part("test", "value"); + result = + co_await client.async_upload_multipart("http://127.0.0.1:9001/form_data"); + assert(result.status == 200); + assert(result.resp_body == "multipart finished"); + result = co_await client.async_get("/in_thread_pool"); assert(result.status == 200); diff --git a/include/cinatra/coro_http_connection.hpp b/include/cinatra/coro_http_connection.hpp index 3fdd794a..356fc456 100644 --- a/include/cinatra/coro_http_connection.hpp +++ b/include/cinatra/coro_http_connection.hpp @@ -288,8 +288,19 @@ class coro_http_connection if (!response_.get_delay()) { if (head_buf_.size()) { - // handle pipeling, only support GET and HEAD method now. - if (parser_.method()[0] != 'G' && parser_.method()[0] != 'H') { + if (type == content_type::multipart) { + response_.set_status_and_content( + status_type::not_implemented, + "mutipart handler not implemented or incorrect implemented"); + co_await reply(); + close(); + CINATRA_LOG_ERROR + << "mutipart handler not implemented or incorrect implemented" + << ec.message(); + break; + } + else if (parser_.method()[0] != 'G' && parser_.method()[0] != 'H') { + // handle pipeling, only support GET and HEAD method now. response_.set_status_and_content(status_type::method_not_allowed, "method not allowed"); co_await reply(); @@ -343,6 +354,7 @@ class coro_http_connection co_return; } } + head_buf_.consume(head_buf_.size()); } else { handle_session_for_response(); diff --git a/lang/english/README.md b/lang/english/README.md index 983becb7..82cf4579 100644 --- a/lang/english/README.md +++ b/lang/english/README.md @@ -376,17 +376,50 @@ async_simple::coro::Lazy test_async_client() { ``` #### upload(multipart) file +```cpp +void start_server() { + coro_http_server server(1, 9001); + server.set_http_handler( + "/form_data", + [](coro_http_request &req, + coro_http_response &resp) -> async_simple::coro::Lazy { + assert(req.get_content_type() == content_type::multipart); + auto boundary = req.get_boundary(); + multipart_reader_t multipart(req.get_conn()); + while (true) { + auto part_head = co_await multipart.read_part_head(); + if (part_head.ec) { + co_return; + } + + std::cout << part_head.name << "\n"; + std::cout << part_head.filename << "\n";// if form data, no filename + + auto part_body = co_await multipart.read_part_body(boundary); + if (part_body.ec) { + co_return; + } + + std::cout << part_body.data << "\n"; + + if (part_body.eof) { + break; + } + } + + resp.set_status_and_content(status_type::ok, "multipart finished"); + }); + server.start(); +} ``` +```cpp async_simple::coro::Lazy test_upload() { - std::string uri = "http://example.com/"; + std::string uri = "http://127.0.0.1:9001/form_data"; coro_http_client client{}; - auto result = co_await client.async_upload(uri, "test", "yourfile.jpg"); - print(result.status); - std::cout << "upload finished\n"; client.add_str_part("hello", "coro_http_client"); client.add_file_part("test", "yourfile.jpg"); - result = co_await client.async_upload(uri); + result = co_await client.async_upload_multipart(uri); print(result.status); std::cout << "upload finished\n"; }