From 9d237effc7c16e9ab6bf68007597b301a888555b Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Thu, 20 Mar 2014 06:10:24 -0500 Subject: [PATCH 1/6] remove dependency on std::iostream from core It is still required for the iostream transport and the basic (iostream) logging policy. --- changelog.md | 3 +++ websocketpp/endpoint.hpp | 5 ++--- websocketpp/logger/basic.hpp | 16 ++++++++++++++-- websocketpp/logger/levels.hpp | 19 +++++++++++++++++++ websocketpp/logger/stub.hpp | 6 +++--- websocketpp/processors/hybi13.hpp | 4 ++-- 6 files changed, 43 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index dd6e580ff2..4e6c4960c0 100644 --- a/changelog.md +++ b/changelog.md @@ -32,6 +32,9 @@ HEAD about them will remain in the info error channel for debugging purposes. - Improvement: `start_accept` and `listen` errors are now reported to the caller either via an exception or an ec parameter. +- Improvement: Core library no longer has std::iostream as a dependency. + std::iostream is still required for the optional iostream logging policy and + iostream transport. - Bug: Fix some cases of calls to empty lib::function objects. - Bug: Fix memory leak of connection objects due to cached handlers holding on to reference counted pointers. #310 Thank you otaras for reporting. diff --git a/websocketpp/endpoint.hpp b/websocketpp/endpoint.hpp index 6c08b131e8..c20a786303 100644 --- a/websocketpp/endpoint.hpp +++ b/websocketpp/endpoint.hpp @@ -32,7 +32,6 @@ #include #include -#include #include namespace websocketpp { @@ -88,8 +87,8 @@ public: typedef lib::shared_ptr hdl_type; explicit endpoint(bool p_is_server) - : m_alog(config::alog_level, &std::cout) - , m_elog(config::elog_level, &std::cerr) + : m_alog(config::alog_level, log::channel_type_hint::access) + , m_elog(config::elog_level, log::channel_type_hint::error) , m_user_agent(::websocketpp::user_agent) , m_open_handshake_timeout_dur(config::timeout_open_handshake) , m_close_handshake_timeout_dur(config::timeout_close_handshake) diff --git a/websocketpp/logger/basic.hpp b/websocketpp/logger/basic.hpp index 678c724660..fc6b60e68b 100644 --- a/websocketpp/logger/basic.hpp +++ b/websocketpp/logger/basic.hpp @@ -55,12 +55,24 @@ namespace log { template class basic { public: - basic(std::ostream * out = &std::cout) + basic(channel_type_hint::value h = + channel_type_hint::access) + : m_static_channels(0xffffffff) + , m_dynamic_channels(0) + , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {} + + basic(std::ostream * out) : m_static_channels(0xffffffff) , m_dynamic_channels(0) , m_out(out) {} - basic(level c, std::ostream * out = &std::cout) + basic(level c, channel_type_hint::value h = + channel_type_hint::access) + : m_static_channels(c) + , m_dynamic_channels(0) + , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {} + + basic(level c, std::ostream * out) : m_static_channels(c) , m_dynamic_channels(0) , m_out(out) {} diff --git a/websocketpp/logger/levels.hpp b/websocketpp/logger/levels.hpp index 2c0e92c94d..00d3f3fdba 100644 --- a/websocketpp/logger/levels.hpp +++ b/websocketpp/logger/levels.hpp @@ -36,6 +36,25 @@ namespace log { /// Type of a channel package typedef uint32_t level; +/// Package of values for hinting at the nature of a given logger. +/** + * Used by the library to signal to the logging class a hint that it can use to + * set itself up. For example, the `access` hint indicates that it is an access + * log that might be suitable for being printed to an access log file or to cout + * whereas `error` might be suitable for an error log file or cerr. + */ +struct channel_type_hint { + /// Type of a channel type hint value + typedef uint32_t value; + + /// No information + static value const none = 0; + /// Access log + static value const access = 1; + /// Error log + static value const error = 2; +}; + /// Package of log levels for logging errors struct elevel { /// Special aggregate value representing "no levels" diff --git a/websocketpp/logger/stub.hpp b/websocketpp/logger/stub.hpp index 4608d35bfd..9e044e762f 100644 --- a/websocketpp/logger/stub.hpp +++ b/websocketpp/logger/stub.hpp @@ -28,7 +28,7 @@ #ifndef WEBSOCKETPP_LOGGER_STUB_HPP #define WEBSOCKETPP_LOGGER_STUB_HPP -#include +#include #include #include @@ -39,8 +39,8 @@ namespace log { /// Stub logger that ignores all input class stub { public: - explicit stub(std::ostream * out) {} - stub(level c, std::ostream * out) {} + explicit stub(channel_type_hint::value h) {} + stub(level c, channel_type_hint::value h) {} _WEBSOCKETPP_CONSTEXPR_TOKEN_ stub() {} void set_channels(level channels) {} diff --git a/websocketpp/processors/hybi13.hpp b/websocketpp/processors/hybi13.hpp index 92a4e2ea70..69e7b7210a 100644 --- a/websocketpp/processors/hybi13.hpp +++ b/websocketpp/processors/hybi13.hpp @@ -121,8 +121,8 @@ public: // Figure out if this is an error that should halt all // extension negotiations or simply cause negotiation of // this specific extension to fail. - std::cout << "permessage-compress negotiation failed: " - << neg_ret.first.message() << std::endl; + //std::cout << "permessage-compress negotiation failed: " + // << neg_ret.first.message() << std::endl; } else { // Note: this list will need commas if WebSocket++ ever // supports more than one extension From 762c013b939173b5cd3331182a031138fb45bcbb Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Thu, 20 Mar 2014 07:02:40 -0500 Subject: [PATCH 2/6] Adds a stub transport policy This will be used in the minimal config to avoid bringing in iostream dependencies. It will also be used to document the minimal interface for writing a custom transport policy. --- websocketpp/transport/stub/base.hpp | 95 ++++++++ websocketpp/transport/stub/connection.hpp | 264 ++++++++++++++++++++++ websocketpp/transport/stub/endpoint.hpp | 140 ++++++++++++ 3 files changed, 499 insertions(+) create mode 100644 websocketpp/transport/stub/base.hpp create mode 100644 websocketpp/transport/stub/connection.hpp create mode 100644 websocketpp/transport/stub/endpoint.hpp diff --git a/websocketpp/transport/stub/base.hpp b/websocketpp/transport/stub/base.hpp new file mode 100644 index 0000000000..864372a45f --- /dev/null +++ b/websocketpp/transport/stub/base.hpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKETPP_TRANSPORT_STUB_BASE_HPP +#define WEBSOCKETPP_TRANSPORT_STUB_BASE_HPP + +#include +#include + +#include + +namespace websocketpp { +namespace transport { +/// Stub transport policy that has no input or output. +namespace stub { + +/// stub transport errors +namespace error { +enum value { + /// Catch-all error for transport policy errors that don't fit in other + /// categories + general = 1, + + /// not implimented + not_implimented +}; + +/// iostream transport error category +class category : public lib::error_category { + public: + category() {} + + char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { + return "websocketpp.transport.stub"; + } + + std::string message(int value) const { + switch(value) { + case general: + return "Generic stub transport policy error"; + case not_implimented: + return "feature not implimented"; + default: + return "Unknown"; + } + } +}; + +/// Get a reference to a static copy of the stub transport error category +inline lib::error_category const & get_category() { + static category instance; + return instance; +} + +/// Get an error code with the given value and the stub transport category +inline lib::error_code make_error_code(error::value e) { + return lib::error_code(static_cast(e), get_category()); +} + +} // namespace error +} // namespace stub +} // namespace transport +} // namespace websocketpp +_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +template<> struct is_error_code_enum +{ + static bool const value = true; +}; +_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ + +#endif // WEBSOCKETPP_TRANSPORT_STUB_BASE_HPP diff --git a/websocketpp/transport/stub/connection.hpp b/websocketpp/transport/stub/connection.hpp new file mode 100644 index 0000000000..ce3bdccd66 --- /dev/null +++ b/websocketpp/transport/stub/connection.hpp @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2014, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKETPP_TRANSPORT_STUB_CON_HPP +#define WEBSOCKETPP_TRANSPORT_STUB_CON_HPP + +#include +#include +#include +#include + +#include +#include + +namespace websocketpp { +namespace transport { +namespace stub { + +/// Empty timer class to stub out for timer functionality that stub +/// transport doesn't support +struct timer { + void cancel() {} +}; + +template +class connection : public lib::enable_shared_from_this< connection > { +public: + /// Type of this connection transport component + typedef connection type; + /// Type of a shared pointer to this connection transport component + typedef lib::shared_ptr ptr; + + /// transport concurrency policy + typedef typename config::concurrency_type concurrency_type; + /// Type of this transport's access logging policy + typedef typename config::alog_type alog_type; + /// Type of this transport's error logging policy + typedef typename config::elog_type elog_type; + + // Concurrency policy types + typedef typename concurrency_type::scoped_lock_type scoped_lock_type; + typedef typename concurrency_type::mutex_type mutex_type; + + typedef lib::shared_ptr timer_ptr; + + explicit connection(bool is_server, alog_type & alog, elog_type & elog) + { + m_alog.write(log::alevel::devel,"stub con transport constructor"); + } + + /// Get a shared pointer to this component + ptr get_shared() { + return type::shared_from_this(); + } + + /// Set whether or not this connection is secure + /** + * Todo: docs + * + * @since 0.3.0-alpha4 + * + * @param value Whether or not this connection is secure. + */ + void set_secure(bool value) {} + + /// Tests whether or not the underlying transport is secure + /** + * TODO: docs + * + * @return Whether or not the underlying transport is secure + */ + bool is_secure() const { + return false; + } + + /// Set human readable remote endpoint address + /** + * Sets the remote endpoint address returned by `get_remote_endpoint`. This + * value should be a human readable string that describes the remote + * endpoint. Typically an IP address or hostname, perhaps with a port. But + * may be something else depending on the nature of the underlying + * transport. + * + * If none is set a default is returned. + * + * @since 0.3.0-alpha4 + * + * @param value The remote endpoint address to set. + */ + void set_remote_endpoint(std::string value) {} + + /// Get human readable remote endpoint address + /** + * TODO: docs + * + * This value is used in access and error logs and is available to the end + * application for including in user facing interfaces and messages. + * + * @return A string identifying the address of the remote endpoint + */ + std::string get_remote_endpoint() const { + return "unknown (stub transport)"; + } + + /// Get the connection handle + /** + * @return The handle for this connection. + */ + connection_hdl get_handle() const { + return connection_hdl(); + } + + /// Call back a function after a period of time. + /** + * Timers are not implemented in this transport. The timer pointer will + * always be empty. The handler will never be called. + * + * @param duration Length of time to wait in milliseconds + * @param callback The function to call back when the timer has expired + * @return A handle that can be used to cancel the timer if it is no longer + * needed. + */ + timer_ptr set_timer(long duration, timer_handler handler) { + return timer_ptr(); + } +protected: + /// Initialize the connection transport + /** + * Initialize the connection's transport component. + * + * @param handler The `init_handler` to call when initialization is done + */ + void init(init_handler handler) { + m_alog.write(log::alevel::devel,"stub connection init"); + handler(make_error_code(error::not_implimented)); + } + + /// Initiate an async_read for at least num_bytes bytes into buf + /** + * Initiates an async_read request for at least num_bytes bytes. The input + * will be read into buf. A maximum of len bytes will be input. When the + * operation is complete, handler will be called with the status and number + * of bytes read. + * + * This method may or may not call handler from within the initial call. The + * application should be prepared to accept either. + * + * The application should never call this method a second time before it has + * been called back for the first read. If this is done, the second read + * will be called back immediately with a double_read error. + * + * If num_bytes or len are zero handler will be called back immediately + * indicating success. + * + * @param num_bytes Don't call handler until at least this many bytes have + * been read. + * @param buf The buffer to read bytes into + * @param len The size of buf. At maximum, this many bytes will be read. + * @param handler The callback to invoke when the operation is complete or + * ends in an error + */ + void async_read_at_least(size_t num_bytes, char *buf, size_t len, + read_handler handler) + { + m_alog.write(log::alevel::devel, "stub_con async_read_at_least"); + handler(make_error_code(error::not_implimented)); + } + + /// Asyncronous Transport Write + /** + * Write len bytes in buf to the output stream. Call handler to report + * success or failure. handler may or may not be called during async_write, + * but it must be safe for this to happen. + * + * Will return 0 on success. + * + * @param buf buffer to read bytes from + * @param len number of bytes to write + * @param handler Callback to invoke with operation status. + */ + void async_write(char const * buf, size_t len, write_handler handler) { + m_alog.write(log::alevel::devel,"stub_con async_write"); + handler(make_error_code(error::not_implimented)); + } + + /// Asyncronous Transport Write (scatter-gather) + /** + * Write a sequence of buffers to the output stream. Call handler to report + * success or failure. handler may or may not be called during async_write, + * but it must be safe for this to happen. + * + * Will return 0 on success. + * + * @param bufs vector of buffers to write + * @param handler Callback to invoke with operation status. + */ + void async_write(std::vector const & bufs, write_handler handler) { + m_alog.write(log::alevel::devel,"stub_con async_write buffer list"); + handler(make_error_code(error::not_implimented)); + } + + /// Set Connection Handle + /** + * @param hdl The new handle + */ + void set_handle(connection_hdl hdl) {} + + /// Call given handler back within the transport's event system (if present) + /** + * Invoke a callback within the transport's event system if it has one. If + * it doesn't, the handler will be invoked immediately before this function + * returns. + * + * @param handler The callback to invoke + * + * @return Whether or not the transport was able to register the handler for + * callback. + */ + lib::error_code dispatch(dispatch_handler handler) { + handler(); + return lib::error_code(); + } + + /// Perform cleanup on socket shutdown_handler + /** + * @param h The `shutdown_handler` to call back when complete + */ + void async_shutdown(shutdown_handler handler) { + handler(lib::error_code()); + } +private: + // member variables! +}; + + +} // namespace stub +} // namespace transport +} // namespace websocketpp + +#endif // WEBSOCKETPP_TRANSPORT_STUB_CON_HPP diff --git a/websocketpp/transport/stub/endpoint.hpp b/websocketpp/transport/stub/endpoint.hpp new file mode 100644 index 0000000000..7be76d7f88 --- /dev/null +++ b/websocketpp/transport/stub/endpoint.hpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2014, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKETPP_TRANSPORT_STUB_HPP +#define WEBSOCKETPP_TRANSPORT_STUB_HPP + +#include +#include + +#include +#include + +namespace websocketpp { +namespace transport { +namespace stub { + +template +class endpoint { +public: + /// Type of this endpoint transport component + typedef endpoint type; + /// Type of a pointer to this endpoint transport component + typedef lib::shared_ptr ptr; + + /// Type of this endpoint's concurrency policy + typedef typename config::concurrency_type concurrency_type; + /// Type of this endpoint's error logging policy + typedef typename config::elog_type elog_type; + /// Type of this endpoint's access logging policy + typedef typename config::alog_type alog_type; + + /// Type of this endpoint transport component's associated connection + /// transport component. + typedef iostream::connection transport_con_type; + /// Type of a shared pointer to this endpoint transport component's + /// associated connection transport component + typedef typename transport_con_type::ptr transport_con_ptr; + + // generate and manage our own io_service + explicit endpoint() + { + //std::cout << "transport::iostream::endpoint constructor" << std::endl; + } + + /// Set whether or not endpoint can create secure connections + /** + * TODO: docs + * + * Setting this value only indicates whether or not the endpoint is capable + * of producing and managing secure connections. Connections produced by + * this endpoint must also be individually flagged as secure if they are. + * + * @since 0.3.0-alpha4 + * + * @param value Whether or not the endpoint can create secure connections. + */ + void set_secure(bool value) {} + + /// Tests whether or not the underlying transport is secure + /** + * TODO: docs + * + * @return Whether or not the underlying transport is secure + */ + bool is_secure() const { + return false; + } +protected: + /// Initialize logging + /** + * The loggers are located in the main endpoint class. As such, the + * transport doesn't have direct access to them. This method is called + * by the endpoint constructor to allow shared logging from the transport + * component. These are raw pointers to member variables of the endpoint. + * In particular, they cannot be used in the transport constructor as they + * haven't been constructed yet, and cannot be used in the transport + * destructor as they will have been destroyed by then. + * + * @param a A pointer to the access logger to use. + * @param e A pointer to the error logger to use. + */ + void init_logging(alog_type * a, elog_type * e) {} + + /// Initiate a new connection + /** + * @param tcon A pointer to the transport connection component of the + * connection to connect. + * @param u A URI pointer to the URI to connect to. + * @param cb The function to call back with the results when complete. + */ + void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb) { + cb(make_error_code(error::not_implimented)); + } + + /// Initialize a connection + /** + * Init is called by an endpoint once for each newly created connection. + * It's purpose is to give the transport policy the chance to perform any + * transport specific initialization that couldn't be done via the default + * constructor. + * + * @param tcon A pointer to the transport portion of the connection. + * @return A status code indicating the success or failure of the operation + */ + lib::error_code init(transport_con_ptr tcon) { + cb(make_error_code(error::not_implimented)); + } +private: + +}; + +} // namespace stub +} // namespace transport +} // namespace websocketpp + +#endif // WEBSOCKETPP_TRANSPORT_STUB_HPP From 0bfb67ef11e0ae6d630b3490f6629f05ed513070 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Thu, 20 Mar 2014 07:03:31 -0500 Subject: [PATCH 3/6] Add minimal_client and minimal_server configs references #338 --- changelog.md | 4 + websocketpp/config/boost_config.hpp | 9 +- websocketpp/config/minimal_client.hpp | 72 ++++++ websocketpp/config/minimal_server.hpp | 302 ++++++++++++++++++++++++++ 4 files changed, 383 insertions(+), 4 deletions(-) create mode 100644 websocketpp/config/minimal_client.hpp create mode 100644 websocketpp/config/minimal_server.hpp diff --git a/changelog.md b/changelog.md index 4e6c4960c0..7e6f3a6c83 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,10 @@ HEAD - Feature: Adds the ability to specify a maximum message size. - Feature: Adds `close::status::get_string(...)` method to look up a human readable string given a close code value. +- Feature: Adds incomplete `minimal_server` and `minimal_client` configs that + can be used to build custom configs without pulling in the dependencies of + `core` or `core_client`. These configs will offer a stable base config to + future-proof custom configs. - Improvement: Open, close, and pong timeouts can be disabled entirely by setting their duration to 0. - Improvement: Numerous performance improvements. Including: tuned default diff --git a/websocketpp/config/boost_config.hpp b/websocketpp/config/boost_config.hpp index 19c890538a..0a0d2c9b6f 100644 --- a/websocketpp/config/boost_config.hpp +++ b/websocketpp/config/boost_config.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Peter Thorson. All rights reserved. + * Copyright (c) 2014, Peter Thorson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,9 +25,9 @@ * */ - // This header defines WebSocket++ macros for C++11 compatibility based on the Boost.Config library. - // This will correctly configure most target platforms simply by including this header before - // any other WebSocket++ header. + // This header defines WebSocket++ macros for C++11 compatibility based on the + // Boost.Config library. This will correctly configure most target platforms + // simply by including this header before any other WebSocket++ header. #ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP #define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP @@ -67,5 +67,6 @@ #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR +// TODO: nullptr support #endif // WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP diff --git a/websocketpp/config/minimal_client.hpp b/websocketpp/config/minimal_client.hpp new file mode 100644 index 0000000000..de8da74171 --- /dev/null +++ b/websocketpp/config/minimal_client.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP +#define WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP + +#include + +namespace websocketpp { +namespace config { + +/// Client config with minimal dependencies +/** + * This config strips out as many dependencies as possible. It is suitable for + * use as a base class for custom configs that want to implement or choose their + * own policies for components that even the core config includes. + * + * NOTE: this config stubs out enough that it cannot be used directly. You must + * supply at least a transport policy and a cryptographically secure random + * number generation policy for a config based on `minimal_client` to do + * anything useful. + * + * Present dependency list for minimal_server config: + * + * C++98 STL: + * + * + * + * + * + * + * C++11 STL or Boost + * + * + * + * + * Operating System: + * or + * or (for ntohl.. could potentially bundle this) + * + * @since 0.4.0-alpha1 + */ +typedef minimal_server minimal_client; + +} // namespace config +} // namespace websocketpp + +#endif // WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP diff --git a/websocketpp/config/minimal_server.hpp b/websocketpp/config/minimal_server.hpp new file mode 100644 index 0000000000..31aceaca4d --- /dev/null +++ b/websocketpp/config/minimal_server.hpp @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2014, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKETPP_CONFIG_MINIMAL_HPP +#define WEBSOCKETPP_CONFIG_MINIMAL_HPP + +// Non-Policy common stuff +#include +#include +#include + +// Concurrency +#include + +// Transport +#include + +// HTTP +#include +#include + +// Messages +#include +#include + +// Loggers +#include + +// RNG +#include + +// User stub base classes +#include +#include + +// Extensions +#include + +namespace websocketpp { +namespace config { + +/// Server config with minimal dependencies +/** + * This config strips out as many dependencies as possible. It is suitable for + * use as a base class for custom configs that want to implement or choose their + * own policies for components that even the core config includes. + * + * NOTE: this config stubs out enough that it cannot be used directly. You must + * supply at least a transport policy for a config based on `minimal_server` to + * do anything useful. + * + * Present dependency list for minimal_server config: + * + * C++98 STL: + * + * + * + * + * + * + * C++11 STL or Boost + * + * + * + * + * Operating System: + * or + * or (for ntohl.. could potentially bundle this) + * + * @since 0.4.0-alpha1 + */ +struct minimal_server { + typedef minimal_server type; + + // Concurrency policy + typedef websocketpp::concurrency::none concurrency_type; + + // HTTP Parser Policies + typedef http::parser::request request_type; + typedef http::parser::response response_type; + + // Message Policies + typedef message_buffer::message + message_type; + typedef message_buffer::alloc::con_msg_manager + con_msg_manager_type; + typedef message_buffer::alloc::endpoint_msg_manager + endpoint_msg_manager_type; + + /// Logging policies + typedef websocketpp::log::stub elog_type; + typedef websocketpp::log::stub alog_type; + + /// RNG policies + typedef websocketpp::random::none::int_generator rng_type; + + /// Controls compile time enabling/disabling of thread syncronization + /// code Disabling can provide a minor performance improvement to single + /// threaded applications + static bool const enable_multithreading = true; + + struct transport_config { + typedef type::concurrency_type concurrency_type; + typedef type::elog_type elog_type; + typedef type::alog_type alog_type; + typedef type::request_type request_type; + typedef type::response_type response_type; + + /// Controls compile time enabling/disabling of thread syncronization + /// code Disabling can provide a minor performance improvement to single + /// threaded applications + static bool const enable_multithreading = true; + + /// Default timer values (in ms) + + /// Length of time to wait for socket pre-initialization + /** + * Exactly what this includes depends on the socket policy in use + */ + static const long timeout_socket_pre_init = 5000; + + /// Length of time to wait before a proxy handshake is aborted + static const long timeout_proxy = 5000; + + /// Length of time to wait for socket post-initialization + /** + * Exactly what this includes depends on the socket policy in use. + * Often this means the TLS handshake + */ + static const long timeout_socket_post_init = 5000; + + /// Length of time to wait for dns resolution + static const long timeout_dns_resolve = 5000; + + /// Length of time to wait for TCP connect + static const long timeout_connect = 5000; + + /// Length of time to wait for socket shutdown + static const long timeout_socket_shutdown = 5000; + }; + + /// Transport Endpoint Component + typedef websocketpp::transport::stub::endpoint + transport_type; + + /// User overridable Endpoint base class + typedef websocketpp::endpoint_base endpoint_base; + /// User overridable Connection base class + typedef websocketpp::connection_base connection_base; + + /// Default timer values (in ms) + + /// Length of time before an opening handshake is aborted + static const long timeout_open_handshake = 5000; + /// Length of time before a closing handshake is aborted + static const long timeout_close_handshake = 5000; + /// Length of time to wait for a pong after a ping + static const long timeout_pong = 5000; + + /// WebSocket Protocol version to use as a client + /** + * What version of the WebSocket Protocol to use for outgoing client + * connections. Setting this to a value other than 13 (RFC6455) is not + * recommended. + */ + static const int client_version = 13; // RFC6455 + + /// Default static error logging channels + /** + * Which error logging channels to enable at compile time. Channels not + * enabled here will be unable to be selected by programs using the library. + * This option gives an optimizing compiler the ability to remove entirely + * code to test whether or not to print out log messages on a certain + * channel + * + * Default is all except for development/debug level errors + */ + static const websocketpp::log::level elog_level = + websocketpp::log::elevel::none; + + /// Default static access logging channels + /** + * Which access logging channels to enable at compile time. Channels not + * enabled here will be unable to be selected by programs using the library. + * This option gives an optimizing compiler the ability to remove entirely + * code to test whether or not to print out log messages on a certain + * channel + * + * Default is all except for development/debug level access messages + */ + static const websocketpp::log::level alog_level = + websocketpp::log::alevel::none; + + /// + static const size_t connection_read_buffer_size = 16384; + + /// Drop connections immediately on protocol error. + /** + * Drop connections on protocol error rather than sending a close frame. + * Off by default. This may result in legit messages near the error being + * dropped as well. It may free up resources otherwise spent dealing with + * misbehaving clients. + */ + static const bool drop_on_protocol_error = false; + + /// Suppresses the return of detailed connection close information + /** + * Silence close suppresses the return of detailed connection close + * information during the closing handshake. This information is useful + * for debugging and presenting useful errors to end users but may be + * undesirable for security reasons in some production environments. + * Close reasons could be used by an attacker to confirm that the endpoint + * is out of resources or be used to identify the WebSocket implementation + * in use. + * + * Note: this will suppress *all* close codes, including those explicitly + * sent by local applications. + */ + static const bool silent_close = false; + + /// Default maximum message size + /** + * Default value for the processor's maximum message size. Maximum message size + * determines the point at which the library will fail a connection with the + * message_too_big protocol error. + * + * The default is 32MB + * + * @since 0.4.0-alpha1 + */ + static const size_t max_message_size = 32000000; + + /// Global flag for enabling/disabling extensions + static const bool enable_extensions = true; + + /// Extension specific settings: + + /// permessage_compress extension + struct permessage_deflate_config { + typedef core::request_type request_type; + + /// If the remote endpoint requests that we reset the compression + /// context after each message should we honor the request? + static const bool allow_disabling_context_takeover = true; + + /// If the remote endpoint requests that we reduce the size of the + /// LZ77 sliding window size this is the lowest value that will be + /// allowed. Values range from 8 to 15. A value of 8 means we will + /// allow any possible window size. A value of 15 means do not allow + /// negotiation of the window size (ie require the default). + static const uint8_t minimum_outgoing_window_bits = 8; + }; + + typedef websocketpp::extensions::permessage_deflate::disabled + permessage_deflate_type; + + /// Autonegotiate permessage-deflate + /** + * Automatically enables the permessage-deflate extension. + * + * For clients this results in a permessage-deflate extension request being + * sent with every request rather than requiring it to be requested manually + * + * For servers this results in accepting the first set of extension settings + * requested by the client that we understand being used. The alternative is + * requiring the extension to be manually negotiated in `validate`. With + * auto-negotiate on, you may still override the auto-negotiate manually if + * needed. + */ + //static const bool autonegotiate_compression = false; +}; + +} // namespace config +} // namespace websocketpp + +#endif // WEBSOCKETPP_CONFIG_MINIMAL_HPP From 497bc574da281d8627144b482e68821611f80c44 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Thu, 20 Mar 2014 07:15:02 -0500 Subject: [PATCH 4/6] remove references to unused iostream header from asio transport --- websocketpp/transport/asio/connection.hpp | 2 +- websocketpp/transport/asio/endpoint.hpp | 4 +--- websocketpp/transport/asio/security/base.hpp | 3 +-- websocketpp/transport/asio/security/none.hpp | 3 +-- websocketpp/transport/asio/security/tls.hpp | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp index cd78fd2444..8019147399 100644 --- a/websocketpp/transport/asio/connection.hpp +++ b/websocketpp/transport/asio/connection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Peter Thorson. All rights reserved. + * Copyright (c) 2014, Peter Thorson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp index a7bf8a36f9..43b03d3a8f 100644 --- a/websocketpp/transport/asio/endpoint.hpp +++ b/websocketpp/transport/asio/endpoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Peter Thorson. All rights reserved. + * Copyright (c) 2014, Peter Thorson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -38,8 +38,6 @@ #include #include -#include - namespace websocketpp { namespace transport { namespace asio { diff --git a/websocketpp/transport/asio/security/base.hpp b/websocketpp/transport/asio/security/base.hpp index 7003452bde..0b49417041 100644 --- a/websocketpp/transport/asio/security/base.hpp +++ b/websocketpp/transport/asio/security/base.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Peter Thorson. All rights reserved. + * Copyright (c) 2014, Peter Thorson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -36,7 +36,6 @@ #include -#include #include // Interface that sockets/security policies must implement diff --git a/websocketpp/transport/asio/security/none.hpp b/websocketpp/transport/asio/security/none.hpp index 96bf868589..c84bc07d1f 100644 --- a/websocketpp/transport/asio/security/none.hpp +++ b/websocketpp/transport/asio/security/none.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Peter Thorson. All rights reserved. + * Copyright (c) 2014, Peter Thorson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,6 @@ #include -#include #include namespace websocketpp { diff --git a/websocketpp/transport/asio/security/tls.hpp b/websocketpp/transport/asio/security/tls.hpp index 9b884ceef7..ab7bd6f331 100644 --- a/websocketpp/transport/asio/security/tls.hpp +++ b/websocketpp/transport/asio/security/tls.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Peter Thorson. All rights reserved. + * Copyright (c) 2014, Peter Thorson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,7 +37,6 @@ #include #include -#include #include namespace websocketpp { From 7a46203beba7ebce2d805f0f1043ae2048268d9c Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Thu, 20 Mar 2014 07:18:59 -0500 Subject: [PATCH 5/6] added a note about breaking changes in the logging policy API --- changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/changelog.md b/changelog.md index 7e6f3a6c83..490e687272 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,9 @@ HEAD +- API BREAKING CHANGE: Custom logging policies have some new required + constructors that take generic config settings rather than pointers to + std::ostreams. This allows writing logging policies that do not involve the + use of std::ostream. This does not affect anyone using the built in logging + policies. - Feature: Adds `start_perpetual` and `stop_perpetual` methods to asio transport These may be used to replace manually managed `asio::io_service::work` objects - Feature: Allow setting pong and handshake timeouts at runtime. From fe0310b283788bc4dcc626ebbc16791a02e290ab Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Sat, 9 Aug 2014 16:13:19 -0500 Subject: [PATCH 6/6] make version introduced notes less specific --- websocketpp/config/minimal_client.hpp | 2 +- websocketpp/config/minimal_server.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/websocketpp/config/minimal_client.hpp b/websocketpp/config/minimal_client.hpp index de8da74171..72528cdeec 100644 --- a/websocketpp/config/minimal_client.hpp +++ b/websocketpp/config/minimal_client.hpp @@ -62,7 +62,7 @@ namespace config { * or * or (for ntohl.. could potentially bundle this) * - * @since 0.4.0-alpha1 + * @since 0.4.0-dev */ typedef minimal_server minimal_client; diff --git a/websocketpp/config/minimal_server.hpp b/websocketpp/config/minimal_server.hpp index 31aceaca4d..f689da9e6e 100644 --- a/websocketpp/config/minimal_server.hpp +++ b/websocketpp/config/minimal_server.hpp @@ -91,7 +91,7 @@ namespace config { * or * or (for ntohl.. could potentially bundle this) * - * @since 0.4.0-alpha1 + * @since 0.4.0-dev */ struct minimal_server { typedef minimal_server type;