diff --git a/client_http.hpp b/client_http.hpp index 7c0b18c..9946dfb 100644 --- a/client_http.hpp +++ b/client_http.hpp @@ -216,6 +216,7 @@ namespace SimpleWeb { /// If you reuse the io_service for other tasks, use the asynchronous request functions instead. /// When requesting Server-Sent Events: will throw on error::eof, please use asynchronous request functions instead. std::shared_ptr request(const std::string &method, const std::string &path = {"/"}, string_view content = {}, const CaseInsensitiveMultimap &header = CaseInsensitiveMultimap()) { + start_internal_io_service_handler_thread(); std::promise> response_promise; std::future> response_future = response_promise.get_future(); std::shared_ptr response; @@ -251,6 +252,7 @@ namespace SimpleWeb { /// If you reuse the io_service for other tasks, use the asynchronous request functions instead. /// When requesting Server-Sent Events: will throw on error::eof, please use asynchronous request functions instead. std::shared_ptr request(const std::string &method, const std::string &path, std::istream &content, const CaseInsensitiveMultimap &header = CaseInsensitiveMultimap()) { + start_internal_io_service_handler_thread(); std::promise> response_promise; std::future> response_future = response_promise.get_future(); std::shared_ptr response; @@ -465,8 +467,7 @@ namespace SimpleWeb { port = parsed_host_port.second; } - std::shared_ptr get_connection() noexcept { - std::shared_ptr connection; + void start_internal_io_service_handler_thread() noexcept { LockGuard lock(connections_mutex); if(!io_service) { @@ -477,6 +478,15 @@ namespace SimpleWeb { io_service->run(); })); } + } + + std::shared_ptr get_connection() noexcept { + std::shared_ptr connection; + LockGuard lock(connections_mutex); + + if(!io_service) { + io_service = std::make_shared(); + } for(auto it = connections.begin(); it != connections.end(); ++it) { if(!(*it)->in_use) { diff --git a/tests/io_test.cpp b/tests/io_test.cpp index 9a96315..d8492dd 100644 --- a/tests/io_test.cpp +++ b/tests/io_test.cpp @@ -389,12 +389,16 @@ int main() { // Test large responses { - HttpClient client("localhost:8080"); - client.config.max_response_streambuf_size = 400; + // Don't mix synchronous and asynchronous on the same client + HttpClient sync_request_client("localhost:8080"); + HttpClient async_request_client("localhost:8080"); + sync_request_client.config.max_response_streambuf_size = 400; + async_request_client.config.max_response_streambuf_size = 400; + async_request_client.io_service = std::make_shared(); { bool thrown = false; try { - auto r = client.request("GET", "/long-response"); + auto r = sync_request_client.request("GET", "/long-response"); } catch(...) { thrown = true; @@ -405,7 +409,7 @@ int main() { size_t calls = 0; bool end = false; std::string content; - client.request("GET", "/long-response", [&calls, &content, &end](shared_ptr response, const SimpleWeb::error_code &ec) { + async_request_client.request("GET", "/long-response", [&calls, &content, &end](shared_ptr response, const SimpleWeb::error_code &ec) { ASSERT(!ec); content += response->content.string(); calls++; @@ -413,8 +417,8 @@ int main() { ASSERT(response->content.end == false); end = response->content.end; }); - SimpleWeb::restart(*client.io_service); - client.io_service->run(); + SimpleWeb::restart(*async_request_client.io_service); + async_request_client.io_service->run(); ASSERT(content == long_response); ASSERT(calls > 2); ASSERT(end == true); @@ -422,15 +426,15 @@ int main() { { size_t calls = 0; std::string content; - client.request("GET", "/long-response", [&calls, &content](shared_ptr response, const SimpleWeb::error_code &ec) { + async_request_client.request("GET", "/long-response", [&calls, &content](shared_ptr response, const SimpleWeb::error_code &ec) { if(calls == 0) ASSERT(!ec); content += response->content.string(); calls++; response->close(); }); - SimpleWeb::restart(*client.io_service); - client.io_service->run(); + SimpleWeb::restart(*async_request_client.io_service); + async_request_client.io_service->run(); ASSERT(!content.empty()); ASSERT(calls >= 2); } @@ -438,12 +442,15 @@ int main() { // Test client timeout { - HttpClient client("localhost:8080"); - client.config.timeout = 2; + // Don't mix synchronous and asynchronous on the same client + HttpClient sync_request_client("localhost:8080"); + HttpClient async_request_client("localhost:8080"); + sync_request_client.config.timeout = 2; + async_request_client.config.timeout = 2; { bool thrown = false; try { - auto r = client.request("GET", "/work"); + auto r = sync_request_client.request("GET", "/work"); } catch(...) { thrown = true; @@ -452,12 +459,12 @@ int main() { } { bool call = false; - client.request("GET", "/work", [&call](shared_ptr /*response*/, const SimpleWeb::error_code &ec) { + async_request_client.request("GET", "/work", [&call](shared_ptr /*response*/, const SimpleWeb::error_code &ec) { ASSERT(ec); call = true; }); - SimpleWeb::restart(*client.io_service); - client.io_service->run(); + SimpleWeb::restart(*async_request_client.io_service); + async_request_client.io_service->run(); ASSERT(call); } }