From f6c6552622dc324a596dc74dd1868dc985cd0d19 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Tue, 18 Nov 2014 22:05:46 -0500 Subject: [PATCH] Access to HTTP request bodies references #181 Use connection::get_request_body() to access. Use endpoint::set_max_http_body_size(size_t value) to control maximum upload size. Initial support is for single chunk bodies that define a content-length . Transfer-Encoding: chunked is not currently supported --- changelog.md | 2 + examples/debug_server/debug_server.cpp | 13 +++++++ websocketpp/config/core.hpp | 12 ++++++ websocketpp/config/core_client.hpp | 12 ++++++ websocketpp/config/debug.hpp | 12 ++++++ websocketpp/config/minimal_server.hpp | 12 ++++++ websocketpp/connection.hpp | 53 +++++++++++++++++++++++--- websocketpp/endpoint.hpp | 36 +++++++++++++++++ websocketpp/impl/connection_impl.hpp | 6 +++ websocketpp/impl/endpoint_impl.hpp | 1 + 10 files changed, 154 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index ee86b79162b..86a43e80933 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,8 @@ HEAD `http::response::parse_complete`, and `http::request::parse_complete` have been removed. - Security: Disabled SSLv3 in example servers. +- Feature: Adds basic support for accessing HTTP request bodies in the http + handler. #181 - Improvement: Message payload logging now prints text for text messages rather than binary. - Documentation: Add Sending & Receiving Messages step to chapter one of the diff --git a/examples/debug_server/debug_server.cpp b/examples/debug_server/debug_server.cpp index 68b320e58d2..54d27236f67 100644 --- a/examples/debug_server/debug_server.cpp +++ b/examples/debug_server/debug_server.cpp @@ -44,6 +44,17 @@ using websocketpp::lib::bind; // pull out the type of messages sent by our config typedef server::message_ptr message_ptr; +void on_http(server* s, websocketpp::connection_hdl hdl) { + server::connection_ptr con = s->get_con_from_hdl(hdl); + + std::string res = con->get_request_body(); + + std::cout << "got HTTP request with " << res.size() << " bytes of body data." << std::endl; + + con->set_body(res); + con->set_status(websocketpp::http::status_code::ok); +} + // Define a callback to handle incoming messages void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) { std::cout << "on_message called with hdl: " << hdl.lock().get() @@ -73,6 +84,8 @@ int main() { // Register our message handler echo_server.set_message_handler(bind(&on_message,&echo_server,::_1,::_2)); + + echo_server.set_http_handler(bind(&on_http,&echo_server,::_1)); // Listen on port 9012 echo_server.listen(9012); diff --git a/websocketpp/config/core.hpp b/websocketpp/config/core.hpp index c35bff762b4..a95b4021dfd 100644 --- a/websocketpp/config/core.hpp +++ b/websocketpp/config/core.hpp @@ -226,6 +226,18 @@ struct core { * @since 0.3.0 */ static const size_t max_message_size = 32000000; + + /// Default maximum http body size + /** + * Default value for the http parser's maximum body size. Maximum body size + * determines the point at which the library will abort reading an HTTP + * connection with the 413/request entity too large error. + * + * The default is 32MB + * + * @since 0.5.0 + */ + static const size_t max_http_body_size = 32000000; /// Global flag for enabling/disabling extensions static const bool enable_extensions = true; diff --git a/websocketpp/config/core_client.hpp b/websocketpp/config/core_client.hpp index fcbac10acbd..dadf8a4e706 100644 --- a/websocketpp/config/core_client.hpp +++ b/websocketpp/config/core_client.hpp @@ -236,6 +236,18 @@ struct core_client { */ static const size_t max_message_size = 32000000; + /// Default maximum http body size + /** + * Default value for the http parser's maximum body size. Maximum body size + * determines the point at which the library will abort reading an HTTP + * connection with the 413/request entity too large error. + * + * The default is 32MB + * + * @since 0.5.0 + */ + static const size_t max_http_body_size = 32000000; + /// Global flag for enabling/disabling extensions static const bool enable_extensions = true; diff --git a/websocketpp/config/debug.hpp b/websocketpp/config/debug.hpp index 9f90360ae22..223f72fbb7c 100644 --- a/websocketpp/config/debug.hpp +++ b/websocketpp/config/debug.hpp @@ -228,6 +228,18 @@ struct debug_core { */ static const size_t max_message_size = 32000000; + /// Default maximum http body size + /** + * Default value for the http parser's maximum body size. Maximum body size + * determines the point at which the library will abort reading an HTTP + * connection with the 413/request entity too large error. + * + * The default is 32MB + * + * @since 0.5.0 + */ + static const size_t max_http_body_size = 32000000; + /// Global flag for enabling/disabling extensions static const bool enable_extensions = true; diff --git a/websocketpp/config/minimal_server.hpp b/websocketpp/config/minimal_server.hpp index f689da9e6e0..f6cdf0f3961 100644 --- a/websocketpp/config/minimal_server.hpp +++ b/websocketpp/config/minimal_server.hpp @@ -256,6 +256,18 @@ struct minimal_server { */ static const size_t max_message_size = 32000000; + /// Default maximum http body size + /** + * Default value for the http parser's maximum body size. Maximum body size + * determines the point at which the library will abort reading an HTTP + * connection with the 413/request entity too large error. + * + * The default is 32MB + * + * @since 0.5.0 + */ + static const size_t max_http_body_size = 32000000; + /// Global flag for enabling/disabling extensions static const bool enable_extensions = true; diff --git a/websocketpp/connection.hpp b/websocketpp/connection.hpp index c0d8f130ad4..7e9f3c041d8 100644 --- a/websocketpp/connection.hpp +++ b/websocketpp/connection.hpp @@ -533,8 +533,8 @@ class connection /// Get maximum message size /** - * Get maximum message size. Maximum message size determines the point at which the - * connection will fail a connection with the message_too_big protocol error. + * Get maximum message size. Maximum message size determines the point at + * which the connection will fail with the message_too_big protocol error. * * The default is set by the endpoint that creates the connection. * @@ -546,9 +546,9 @@ class connection /// Set maximum message size /** - * Set maximum message size. Maximum message size determines the point at which the - * connection will fail a connection with the message_too_big protocol error. This - * value may be changed during the connection. + * Set maximum message size. Maximum message size determines the point at + * which the connection will fail with the message_too_big protocol error. + * This value may be changed during the connection. * * The default is set by the endpoint that creates the connection. * @@ -562,6 +562,38 @@ class connection m_processor->set_max_message_size(new_value); } } + + /// Get maximum HTTP message body size + /** + * Get maximum HTTP message body size. Maximum message body size determines + * the point at which the connection will stop reading an HTTP request whose + * body is too large. + * + * The default is set by the endpoint that creates the connection. + * + * @since 0.5.0 + * + * @return The maximum HTTP message body size + */ + size_t get_max_http_body_size() const { + return m_request.get_max_body_size(); + } + + /// Set maximum HTTP message body size + /** + * Set maximum HTTP message body size. Maximum message body size determines + * the point at which the connection will stop reading an HTTP request whose + * body is too large. + * + * The default is set by the endpoint that creates the connection. + * + * @since 0.5.0 + * + * @param new_value The value to set as the maximum message size. + */ + void set_max_http_body_size(size_t new_value) { + m_request.set_max_body_size(new_value); + } ////////////////////////////////// // Uncategorized public methods // @@ -901,6 +933,17 @@ class connection */ std::string const & get_request_header(std::string const & key) const; + /// Retrieve a request body + /** + * Retrieve the value of the request body. This value is typically used with + * PUT and POST requests to upload files or other data. Only HTTP + * connections will ever have bodies. WebSocket connection's will always + * have blank bodies. + * + * @return The value of the request body. + */ + std::string const & get_request_body() const; + /// Retrieve a response header /** * Retrieve the value of a header from the handshake HTTP request. diff --git a/websocketpp/endpoint.hpp b/websocketpp/endpoint.hpp index a1609c8135c..467f0d82280 100644 --- a/websocketpp/endpoint.hpp +++ b/websocketpp/endpoint.hpp @@ -93,6 +93,7 @@ class endpoint : public config::transport_type, public config::endpoint_base { , m_close_handshake_timeout_dur(config::timeout_close_handshake) , m_pong_timeout_dur(config::timeout_pong) , m_max_message_size(config::max_message_size) + , m_max_http_body_size(config::max_http_body_size) , m_is_server(p_is_server) { m_alog.set_channels(config::alog_level); @@ -379,6 +380,40 @@ class endpoint : public config::transport_type, public config::endpoint_base { m_max_message_size = new_value; } + /// Get maximum HTTP message body size + /** + * Get maximum HTTP message body size. Maximum message body size determines + * the point at which the connection will stop reading an HTTP request whose + * body is too large. + * + * The default is set by the max_http_body_size value from the template + * config + * + * @since 0.5.0 + * + * @return The maximum HTTP message body size + */ + size_t get_max_http_body_size() const { + return m_max_http_body_size; + } + + /// Set maximum HTTP message body size + /** + * Set maximum HTTP message body size. Maximum message body size determines + * the point at which the connection will stop reading an HTTP request whose + * body is too large. + * + * The default is set by the max_http_body_size value from the template + * config + * + * @since 0.5.0 + * + * @param new_value The value to set as the maximum message size. + */ + void get_max_http_body_size(size_t new_value) { + m_max_http_body_size = new_value; + } + /*************************************/ /* Connection pass through functions */ /*************************************/ @@ -566,6 +601,7 @@ class endpoint : public config::transport_type, public config::endpoint_base { long m_close_handshake_timeout_dur; long m_pong_timeout_dur; size_t m_max_message_size; + size_t m_max_http_body_size; rng_type m_rng; diff --git a/websocketpp/impl/connection_impl.hpp b/websocketpp/impl/connection_impl.hpp index 224367c2591..929d10b66a2 100644 --- a/websocketpp/impl/connection_impl.hpp +++ b/websocketpp/impl/connection_impl.hpp @@ -511,6 +511,12 @@ connection::get_request_header(std::string const & key) const { return m_request.get_header(key); } +template +std::string const & +connection::get_request_body() const { + return m_request.get_body(); +} + template std::string const & connection::get_response_header(std::string const & key) const { diff --git a/websocketpp/impl/endpoint_impl.hpp b/websocketpp/impl/endpoint_impl.hpp index e86be2b038c..5895199a016 100644 --- a/websocketpp/impl/endpoint_impl.hpp +++ b/websocketpp/impl/endpoint_impl.hpp @@ -79,6 +79,7 @@ endpoint::create_connection() { if (m_max_message_size != config::max_message_size) { con->set_max_message_size(m_max_message_size); } + con->set_max_http_body_size(m_max_http_body_size); lib::error_code ec;