From eef8a108499ba6f27fd578d2cde9d587937fc6b7 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 19 Dec 2016 08:39:34 +0100 Subject: [PATCH] Added error reporting through on_error std::function --- server_http.hpp | 47 +++++++++++++++++++++++++++----------------- server_https.hpp | 6 +++++- tests/parse_test.cpp | 4 +++- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/server_http.hpp b/server_http.hpp index 237ce41..e041dad 100644 --- a/server_http.hpp +++ b/server_http.hpp @@ -21,6 +21,9 @@ #endif namespace SimpleWeb { + template + class Server; + template class ServerBase { public: @@ -59,6 +62,7 @@ namespace SimpleWeb { class Request { friend class ServerBase; + friend class Server; //Based on http://www.boost.org/doc/libs/1_60_0/doc/html/unordered/hash_equality.html class iequal_to { @@ -89,7 +93,13 @@ namespace SimpleWeb { unsigned short remote_endpoint_port; private: - Request(): content(streambuf) {} + Request(const socket_type &socket): content(streambuf) { + try { + remote_endpoint_address=socket.lowest_layer().remote_endpoint().address().to_string(); + remote_endpoint_port=socket.lowest_layer().remote_endpoint().port(); + } + catch(...) {} + } boost::asio::streambuf streambuf; }; @@ -116,7 +126,7 @@ namespace SimpleWeb { std::unordered_map::Response>, std::shared_ptr::Request>)> > default_resource; - std::function exception_handler; + std::function::Request>, const boost::system::error_code&)> on_error; private: std::vector(*io_service); timer->expires_from_now(boost::posix_time::seconds(seconds)); - timer->async_wait([socket](const boost::system::error_code& ec){ + timer->async_wait([this, socket](const boost::system::error_code& ec){ if(!ec) { boost::system::error_code ec; socket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); @@ -231,15 +241,7 @@ namespace SimpleWeb { void read_request_and_content(const std::shared_ptr &socket) { //Create new streambuf (Request::streambuf) for async_read_until() //shared_ptr is used to pass temporary objects to the asynchronous functions - std::shared_ptr request(new Request()); - try { - request->remote_endpoint_address=socket->lowest_layer().remote_endpoint().address().to_string(); - request->remote_endpoint_port=socket->lowest_layer().remote_endpoint().port(); - } - catch(const std::exception &e) { - if(exception_handler) - exception_handler(e); - } + std::shared_ptr request(new Request(*socket)); //Set timeout on the following boost::asio::async-read or write function auto timer=this->get_timeout_timer(socket, timeout_request); @@ -266,8 +268,8 @@ namespace SimpleWeb { content_length=stoull(it->second); } catch(const std::exception &e) { - if(exception_handler) - exception_handler(e); + if(on_error) + on_error(request, boost::system::error_code(boost::system::errc::protocol_error, boost::system::generic_category())); return; } if(content_length>num_additional_bytes) { @@ -281,6 +283,8 @@ namespace SimpleWeb { timer->cancel(); if(!ec) this->find_resource(socket, request); + else if(on_error) + on_error(request, ec); }); } else @@ -289,6 +293,8 @@ namespace SimpleWeb { else this->find_resource(socket, request); } + else if(on_error) + on_error(request, ec); }); } @@ -370,8 +376,8 @@ namespace SimpleWeb { http_version=stof(request->http_version); } catch(const std::exception &e){ - if(exception_handler) - exception_handler(e); + if(on_error) + on_error(request, boost::system::error_code(boost::system::errc::protocol_error, boost::system::generic_category())); return; } @@ -383,6 +389,8 @@ namespace SimpleWeb { if(http_version>1.05) this->read_request_and_content(response->socket); } + else if(on_error) + on_error(request, ec); }); }); @@ -390,8 +398,8 @@ namespace SimpleWeb { resource_function(response, request); } catch(const std::exception &e) { - if(exception_handler) - exception_handler(e); + if(on_error) + on_error(request, boost::system::error_code(boost::system::errc::operation_canceled, boost::system::generic_category())); return; } } @@ -425,6 +433,9 @@ namespace SimpleWeb { this->read_request_and_content(socket); } + else if(on_error) { + on_error(std::shared_ptr(new Request(*socket)), ec); + } }); } }; diff --git a/server_https.hpp b/server_https.hpp index 85fda94..8e381f1 100644 --- a/server_https.hpp +++ b/server_https.hpp @@ -61,14 +61,18 @@ namespace SimpleWeb { //Set timeout on the following boost::asio::ssl::stream::async_handshake auto timer=get_timeout_timer(socket, timeout_request); - (*socket).async_handshake(boost::asio::ssl::stream_base::server, [this, socket, timer] + socket->async_handshake(boost::asio::ssl::stream_base::server, [this, socket, timer] (const boost::system::error_code& ec) { if(timer) timer->cancel(); if(!ec) read_request_and_content(socket); + else if(on_error) + on_error(std::shared_ptr(new Request(*socket)), ec); }); } + else if(on_error) + on_error(std::shared_ptr(new Request(*socket)), ec); }); } }; diff --git a/tests/parse_test.cpp b/tests/parse_test.cpp index 3eff774..f417da5 100644 --- a/tests/parse_test.cpp +++ b/tests/parse_test.cpp @@ -13,7 +13,8 @@ public: void accept() {} bool parse_request_test() { - std::shared_ptr request(new Request()); + HTTP socket(*io_service); + std::shared_ptr request(new Request(socket)); std::ostream stream(&request->content.streambuf); stream << "GET /test/ HTTP/1.1\r\n"; @@ -100,6 +101,7 @@ public: int main() { ServerTest serverTest; + serverTest.io_service=std::make_shared(); if(!serverTest.parse_request_test()) { cerr << "FAIL Server::parse_request" << endl;