Client: async request handlers are now called multiple times if response content is larger than Config::max_response_streambuf_size. Also improved streambuf to streambuf copy, and streambuf to string copy. Finally, string() functions no longer consume streambuf.

This commit is contained in:
eidheim 2020-01-14 14:32:36 +01:00
commit 3be67623fa
5 changed files with 285 additions and 146 deletions

View file

@ -57,6 +57,7 @@ int main() {
server.resource["^/string$"]["POST"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
auto content = request->content.string();
ASSERT(content == request->content.string());
*response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n"
<< content;
@ -209,6 +210,13 @@ int main() {
*response << "HTTP/1.1 200 OK\nname: value\n\n";
};
std::string long_response;
for(int c = 0; c < 1000; ++c)
long_response += to_string(c);
server.resource["^/long-response$"]["GET"] = [&long_response](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> /*request*/) {
response->write(long_response, {{"name", "value"}});
};
thread server_thread([&server]() {
// Start server
server.start();
@ -241,6 +249,7 @@ int main() {
auto r = client.request("POST", "/string", "A string");
ASSERT(SimpleWeb::status_code(r->status_code) == SimpleWeb::StatusCode::success_ok);
ASSERT(r->content.string() == "A string");
ASSERT(r->content.string() == "A string");
}
{
@ -378,6 +387,81 @@ int main() {
}
}
// Test large responses
{
HttpClient client("localhost:8080");
client.config.max_response_streambuf_size = 400;
{
bool thrown = false;
try {
auto r = client.request("GET", "/long-response");
}
catch(...) {
thrown = true;
}
ASSERT(thrown);
}
{
size_t calls = 0;
bool end = false;
std::string content;
client.request("GET", "/long-response", [&calls, &content, &end](shared_ptr<HttpClient::Response> response, const SimpleWeb::error_code &ec) {
ASSERT(!ec);
content += response->content.string();
calls++;
if(calls == 1)
ASSERT(response->content.end == false);
end = response->content.end;
});
SimpleWeb::restart(*client.io_service);
client.io_service->run();
ASSERT(content == long_response);
ASSERT(calls > 2);
ASSERT(end == true);
}
{
size_t calls = 0;
std::string content;
client.request("GET", "/long-response", [&calls, &content](shared_ptr<HttpClient::Response> 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();
ASSERT(!content.empty());
ASSERT(calls >= 2);
}
}
// Test client timeout
{
HttpClient client("localhost:8080");
client.config.timeout = 2;
{
bool thrown = false;
try {
auto r = client.request("GET", "/work");
}
catch(...) {
thrown = true;
}
ASSERT(thrown);
}
{
bool call = false;
client.request("GET", "/work", [&call](shared_ptr<HttpClient::Response> /*response*/, const SimpleWeb::error_code &ec) {
ASSERT(ec);
call = true;
});
SimpleWeb::restart(*client.io_service);
client.io_service->run();
ASSERT(call);
}
}
// Test asynchronous requests
{
HttpClient client("localhost:8080");