Added SimpleWeb::error, and simplified request size checks on server
This commit is contained in:
parent
1a56f4810e
commit
31e6819b42
6 changed files with 39 additions and 38 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#include <asio.hpp>
|
||||
#include <asio/steady_timer.hpp>
|
||||
namespace SimpleWeb {
|
||||
namespace error = asio::error;
|
||||
using error_code = std::error_code;
|
||||
using errc = std::errc;
|
||||
using system_error = std::system_error;
|
||||
|
|
@ -17,6 +18,7 @@ namespace SimpleWeb {
|
|||
#include <boost/asio/steady_timer.hpp>
|
||||
namespace SimpleWeb {
|
||||
namespace asio = boost::asio;
|
||||
namespace error = asio::error;
|
||||
using error_code = boost::system::error_code;
|
||||
namespace errc = boost::system::errc;
|
||||
using system_error = boost::system::system_error;
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ namespace SimpleWeb {
|
|||
/// Convenience function to perform synchronous request. The io_service is run within this function.
|
||||
/// If reusing the io_service for other tasks, use the asynchronous request functions instead.
|
||||
/// Do not use concurrently with the asynchronous request functions.
|
||||
/// When requesting Server-Sent Events: will throw on asio::error::eof, please use asynchronous request functions instead.
|
||||
/// When requesting Server-Sent Events: will throw on error::eof, please use asynchronous request functions instead.
|
||||
std::shared_ptr<Response> request(const std::string &method, const std::string &path = {"/"}, string_view content = {}, const CaseInsensitiveMultimap &header = {}) {
|
||||
std::shared_ptr<Response> response;
|
||||
error_code ec;
|
||||
|
|
@ -179,7 +179,7 @@ namespace SimpleWeb {
|
|||
/// Convenience function to perform synchronous request. The io_service is run within this function.
|
||||
/// If reusing the io_service for other tasks, use the asynchronous request functions instead.
|
||||
/// Do not use concurrently with the asynchronous request functions.
|
||||
/// When requesting Server-Sent Events: will throw on asio::error::eof, please use asynchronous request functions instead.
|
||||
/// When requesting Server-Sent Events: will throw on error::eof, please use asynchronous request functions instead.
|
||||
std::shared_ptr<Response> request(const std::string &method, const std::string &path, std::istream &content, const CaseInsensitiveMultimap &header = {}) {
|
||||
std::shared_ptr<Response> response;
|
||||
error_code ec;
|
||||
|
|
@ -208,7 +208,7 @@ namespace SimpleWeb {
|
|||
|
||||
/// Asynchronous request where setting and/or running Client's io_service is required.
|
||||
/// Do not use concurrently with the synchronous request functions.
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = asio::error::eof on last call
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = error::eof on last call
|
||||
void request(const std::string &method, const std::string &path, string_view content, const CaseInsensitiveMultimap &header,
|
||||
std::function<void(std::shared_ptr<Response>, const error_code &)> &&request_callback_) {
|
||||
auto session = std::make_shared<Session>(config.max_response_streambuf_size, get_connection(), create_request_header(method, path, header));
|
||||
|
|
@ -260,7 +260,7 @@ namespace SimpleWeb {
|
|||
|
||||
/// Asynchronous request where setting and/or running Client's io_service is required.
|
||||
/// Do not use concurrently with the synchronous request functions.
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = asio::error::eof on last call
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = error::eof on last call
|
||||
void request(const std::string &method, const std::string &path, string_view content,
|
||||
std::function<void(std::shared_ptr<Response>, const error_code &)> &&request_callback_) {
|
||||
request(method, path, content, CaseInsensitiveMultimap(), std::move(request_callback_));
|
||||
|
|
@ -268,7 +268,7 @@ namespace SimpleWeb {
|
|||
|
||||
/// Asynchronous request where setting and/or running Client's io_service is required.
|
||||
/// Do not use concurrently with the synchronous request functions.
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = asio::error::eof on last call
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = error::eof on last call
|
||||
void request(const std::string &method, const std::string &path,
|
||||
std::function<void(std::shared_ptr<Response>, const error_code &)> &&request_callback_) {
|
||||
request(method, path, std::string(), CaseInsensitiveMultimap(), std::move(request_callback_));
|
||||
|
|
@ -276,14 +276,14 @@ namespace SimpleWeb {
|
|||
|
||||
/// Asynchronous request where setting and/or running Client's io_service is required.
|
||||
/// Do not use concurrently with the synchronous request functions.
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = asio::error::eof on last call
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = error::eof on last call
|
||||
void request(const std::string &method, std::function<void(std::shared_ptr<Response>, const error_code &)> &&request_callback_) {
|
||||
request(method, std::string("/"), std::string(), CaseInsensitiveMultimap(), std::move(request_callback_));
|
||||
}
|
||||
|
||||
/// Asynchronous request where setting and/or running Client's io_service is required.
|
||||
/// Do not use concurrently with the synchronous request functions.
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = asio::error::eof on last call
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = error::eof on last call
|
||||
void request(const std::string &method, const std::string &path, std::istream &content, const CaseInsensitiveMultimap &header,
|
||||
std::function<void(std::shared_ptr<Response>, const error_code &)> &&request_callback_) {
|
||||
auto session = std::make_shared<Session>(config.max_response_streambuf_size, get_connection(), create_request_header(method, path, header));
|
||||
|
|
@ -339,7 +339,7 @@ namespace SimpleWeb {
|
|||
|
||||
/// Asynchronous request where setting and/or running Client's io_service is required.
|
||||
/// Do not use concurrently with the synchronous request functions.
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = asio::error::eof on last call
|
||||
/// When requesting Server-Sent Events: request_callback might be called more than twice, first call with empty contents on open, and with ec = error::eof on last call
|
||||
void request(const std::string &method, const std::string &path, std::istream &content,
|
||||
std::function<void(std::shared_ptr<Response>, const error_code &)> &&request_callback_) {
|
||||
request(method, path, content, CaseInsensitiveMultimap(), std::move(request_callback_));
|
||||
|
|
@ -543,7 +543,7 @@ namespace SimpleWeb {
|
|||
session->callback(ec);
|
||||
}
|
||||
else
|
||||
session->callback(ec == asio::error::eof ? error_code() : ec);
|
||||
session->callback(ec == error::eof ? error_code() : ec);
|
||||
});
|
||||
}
|
||||
else if(((header_it = session->response->header.find("Content-Type")) != session->response->header.end() && header_it->second == "text/event-stream")) {
|
||||
|
|
@ -566,7 +566,7 @@ namespace SimpleWeb {
|
|||
session->callback(ec);
|
||||
}
|
||||
else {
|
||||
if(session->connection->attempt_reconnect && ec != asio::error::operation_aborted) {
|
||||
if(session->connection->attempt_reconnect && ec != error::operation_aborted) {
|
||||
std::unique_lock<std::mutex> lock(connections_mutex);
|
||||
auto it = connections.find(session->connection);
|
||||
if(it != connections.end()) {
|
||||
|
|
|
|||
|
|
@ -83,10 +83,11 @@ namespace SimpleWeb {
|
|||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
if((!ec || ec == asio::error::not_found) && response->streambuf.size() == response->streambuf.max_size()) {
|
||||
if(response->streambuf.size() == response->streambuf.max_size()) {
|
||||
session->callback(make_error_code::make_error_code(errc::message_size));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ec) {
|
||||
if(!ResponseMessage::parse(response->content, response->http_version, response->status_code, response->header))
|
||||
session->callback(make_error_code::make_error_code(errc::protocol_error));
|
||||
|
|
|
|||
|
|
@ -511,13 +511,14 @@ namespace SimpleWeb {
|
|||
if(!lock)
|
||||
return;
|
||||
session->request->header_read_time = std::chrono::system_clock::now();
|
||||
if((!ec || ec == asio::error::not_found) && session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
if(session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
auto response = std::shared_ptr<Response>(new Response(session, this->config.timeout_content));
|
||||
response->write(StatusCode::client_error_payload_too_large);
|
||||
if(this->on_error)
|
||||
this->on_error(session->request, make_error_code::make_error_code(errc::message_size));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ec) {
|
||||
// request->streambuf.size() is not necessarily the same as bytes_transferred, from Boost-docs:
|
||||
// "After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter"
|
||||
|
|
@ -551,16 +552,16 @@ namespace SimpleWeb {
|
|||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
if(!ec) {
|
||||
if(session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
auto response = std::shared_ptr<Response>(new Response(session, this->config.timeout_content));
|
||||
response->write(StatusCode::client_error_payload_too_large);
|
||||
if(this->on_error)
|
||||
this->on_error(session->request, make_error_code::make_error_code(errc::message_size));
|
||||
return;
|
||||
}
|
||||
this->find_resource(session);
|
||||
if(session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
auto response = std::shared_ptr<Response>(new Response(session, this->config.timeout_content));
|
||||
response->write(StatusCode::client_error_payload_too_large);
|
||||
if(this->on_error)
|
||||
this->on_error(session->request, make_error_code::make_error_code(errc::message_size));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ec)
|
||||
this->find_resource(session);
|
||||
else if(this->on_error)
|
||||
this->on_error(session->request, ec);
|
||||
});
|
||||
|
|
@ -587,13 +588,14 @@ namespace SimpleWeb {
|
|||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
if((!ec || ec == asio::error::not_found) && session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
if(session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
auto response = std::shared_ptr<Response>(new Response(session, this->config.timeout_content));
|
||||
response->write(StatusCode::client_error_payload_too_large);
|
||||
if(this->on_error)
|
||||
this->on_error(session->request, make_error_code::make_error_code(errc::message_size));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ec) {
|
||||
std::string line;
|
||||
getline(session->request->content, line);
|
||||
|
|
@ -618,16 +620,16 @@ namespace SimpleWeb {
|
|||
auto lock = session->connection->handler_runner->continue_lock();
|
||||
if(!lock)
|
||||
return;
|
||||
if(!ec) {
|
||||
if(session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
auto response = std::shared_ptr<Response>(new Response(session, this->config.timeout_content));
|
||||
response->write(StatusCode::client_error_payload_too_large);
|
||||
if(this->on_error)
|
||||
this->on_error(session->request, make_error_code::make_error_code(errc::message_size));
|
||||
return;
|
||||
}
|
||||
this->read_chunked_transfer_encoded_chunk(session, chunks_streambuf, length);
|
||||
if(session->request->streambuf.size() == session->request->streambuf.max_size()) {
|
||||
auto response = std::shared_ptr<Response>(new Response(session, this->config.timeout_content));
|
||||
response->write(StatusCode::client_error_payload_too_large);
|
||||
if(this->on_error)
|
||||
this->on_error(session->request, make_error_code::make_error_code(errc::message_size));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ec)
|
||||
this->read_chunked_transfer_encoded_chunk(session, chunks_streambuf, length);
|
||||
else if(this->on_error)
|
||||
this->on_error(session->request, ec);
|
||||
});
|
||||
|
|
@ -766,7 +768,7 @@ namespace SimpleWeb {
|
|||
return;
|
||||
|
||||
// Immediately start accepting a new connection (unless io_service has been stopped)
|
||||
if(ec != asio::error::operation_aborted)
|
||||
if(ec != error::operation_aborted)
|
||||
this->accept();
|
||||
|
||||
auto session = std::make_shared<Session>(config.max_request_streambuf_size, connection);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ namespace SimpleWeb {
|
|||
if(!lock)
|
||||
return;
|
||||
|
||||
if(ec != asio::error::operation_aborted)
|
||||
if(ec != error::operation_aborted)
|
||||
this->accept();
|
||||
|
||||
auto session = std::make_shared<Session>(config.max_request_streambuf_size, connection);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@
|
|||
#include "server_http.hpp"
|
||||
#include <future>
|
||||
|
||||
#ifndef USE_STANDALONE_ASIO
|
||||
namespace asio = boost::asio;
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
|
||||
|
|
@ -363,7 +359,7 @@ int main() {
|
|||
}
|
||||
else if(call_num == 3) {
|
||||
ASSERT(response->content.string().empty());
|
||||
ASSERT(ec == asio::error::eof);
|
||||
ASSERT(ec == SimpleWeb::error::eof);
|
||||
}
|
||||
++call_num;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue