diff --git a/changelog.md b/changelog.md index ee86b79..86a43e8 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 68b320e..54d2723 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 c35bff7..a95b402 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 fcbac10..dadf8a4 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 9f90360..223f72f 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 f689da9..f6cdf0f 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 c0d8f13..7e9f3c0 100644 --- a/websocketpp/connection.hpp +++ b/websocketpp/connection.hpp @@ -533,8 +533,8 @@ public: /// 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 @@ public: /// 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 @@ public: 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 @@ public: */ 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 a1609c8..467f0d8 100644 --- a/websocketpp/endpoint.hpp +++ b/websocketpp/endpoint.hpp @@ -93,6 +93,7 @@ public: , 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 @@ public: 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 @@ private: 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 224367c..929d10b 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 e86be2b..5895199 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;