diff --git a/websocketpp/common.hpp b/websocketpp/common.hpp index 1199f6255d..31d2bf11c5 100644 --- a/websocketpp/common.hpp +++ b/websocketpp/common.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -71,8 +71,8 @@ //#define _WEBSOCKETPP_CPP11_ALIAS_TEMPLATES_ #ifdef _WEBSOCKETPP_CPP11_ - #define _WEBSOCKETPP_DELETED_FUNCTIONS_ - #define _WEBSOCKETPP_RVALUE_REFERENCES_ + #define _WEBSOCKETPP_DELETED_FUNCTIONS_ + #define _WEBSOCKETPP_RVALUE_REFERENCES_ #endif #include diff --git a/websocketpp/common/chrono.hpp b/websocketpp/common/chrono.hpp index dbd1d4ed25..e7e8e5f0bb 100644 --- a/websocketpp/common/chrono.hpp +++ b/websocketpp/common/chrono.hpp @@ -29,24 +29,24 @@ #define WEBSOCKETPP_COMMON_CHRONO_HPP #if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_ - #ifndef _WEBSOCKETPP_CPP11_CHRONO_ - #define _WEBSOCKETPP_CPP11_CHRONO_ - #endif + #ifndef _WEBSOCKETPP_CPP11_CHRONO_ + #define _WEBSOCKETPP_CPP11_CHRONO_ + #endif #endif #ifdef _WEBSOCKETPP_CPP11_CHRONO_ - #include + #include #else - #include + #include #endif namespace websocketpp { namespace lib { #ifdef _WEBSOCKETPP_CPP11_CHRONO_ - using std::chrono::system_clock; + using std::chrono::system_clock; #else - using boost::chrono::system_clock; + using boost::chrono::system_clock; #endif } // namespace lib diff --git a/websocketpp/common/cpp11.hpp b/websocketpp/common/cpp11.hpp index d96d7647ed..aecd2e305e 100644 --- a/websocketpp/common/cpp11.hpp +++ b/websocketpp/common/cpp11.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -42,44 +42,44 @@ #ifdef _WEBSOCKETPP_CPP11_STL_ - // This flag indicates that all of the C++11 language features are available - // to us. - #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept - #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr - #define _WEBSOCKETPP_INITIALIZER_LISTS_ + // This flag indicates that all of the C++11 language features are available + // to us. + #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept + #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr + #define _WEBSOCKETPP_INITIALIZER_LISTS_ #else - // Test for noexcept - #ifdef _WEBSOCKETPP_NOEXCEPT_ - // build system says we have noexcept - #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept - #else - #if __has_feature(cxx_noexcept) - // clang feature detect says we have noexcept - #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept - #else - // assume we don't have noexcept - #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ - #endif - #endif - - // Test for constexpr - #ifdef _WEBSOCKETPP_CONSTEXPR_ - // build system says we have constexpr - #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr - #else - #if __has_feature(cxx_constexpr) - // clang feature detect says we have constexpr - #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr - #else - // assume we don't have constexpr - #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ - #endif - #endif - - // Enable initializer lists on clang when available. - #if __has_feature(cxx_generalized_initializers) - #define _WEBSOCKETPP_INITIALIZER_LISTS_ - #endif + // Test for noexcept + #ifdef _WEBSOCKETPP_NOEXCEPT_ + // build system says we have noexcept + #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept + #else + #if __has_feature(cxx_noexcept) + // clang feature detect says we have noexcept + #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept + #else + // assume we don't have noexcept + #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ + #endif + #endif + + // Test for constexpr + #ifdef _WEBSOCKETPP_CONSTEXPR_ + // build system says we have constexpr + #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr + #else + #if __has_feature(cxx_constexpr) + // clang feature detect says we have constexpr + #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr + #else + // assume we don't have constexpr + #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ + #endif + #endif + + // Enable initializer lists on clang when available. + #if __has_feature(cxx_generalized_initializers) + #define _WEBSOCKETPP_INITIALIZER_LISTS_ + #endif #endif #endif // WEBSOCKETPP_COMMON_CPP11_HPP diff --git a/websocketpp/common/functional.hpp b/websocketpp/common/functional.hpp index 71fa632d89..1261ad685d 100644 --- a/websocketpp/common/functional.hpp +++ b/websocketpp/common/functional.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -29,35 +29,35 @@ #define WEBSOCKETPP_COMMON_FUNCTIONAL_HPP #if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_ - #ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_ - #define _WEBSOCKETPP_CPP11_FUNCTIONAL_ - #endif + #ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_ + #define _WEBSOCKETPP_CPP11_FUNCTIONAL_ + #endif #endif #ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_ - #include + #include #else - #include - #include + #include + #include #endif namespace websocketpp { namespace lib { #ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_ - using std::function; - using std::bind; - using std::ref; - namespace placeholders = std::placeholders; + using std::function; + using std::bind; + using std::ref; + namespace placeholders = std::placeholders; #else - using boost::function; - using boost::bind; - using boost::ref; - namespace placeholders { - // TODO: there has got to be a better way than this - using ::_1; - using ::_2; - } + using boost::function; + using boost::bind; + using boost::ref; + namespace placeholders { + // TODO: there has got to be a better way than this + using ::_1; + using ::_2; + } #endif } // namespace lib diff --git a/websocketpp/common/memory.hpp b/websocketpp/common/memory.hpp index 97c0a07151..5378b44c5a 100644 --- a/websocketpp/common/memory.hpp +++ b/websocketpp/common/memory.hpp @@ -29,34 +29,34 @@ #define WEBSOCKETPP_COMMON_MEMORY_HPP #if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_ - #ifndef _WEBSOCKETPP_CPP11_MEMORY_ - #define _WEBSOCKETPP_CPP11_MEMORY_ - #endif + #ifndef _WEBSOCKETPP_CPP11_MEMORY_ + #define _WEBSOCKETPP_CPP11_MEMORY_ + #endif #endif #ifdef _WEBSOCKETPP_CPP11_MEMORY_ - #include + #include #else - #include - #include - #include - #include + #include + #include + #include + #include #endif namespace websocketpp { namespace lib { #ifdef _WEBSOCKETPP_CPP11_MEMORY_ - using std::shared_ptr; - using std::weak_ptr; - using std::enable_shared_from_this; + using std::shared_ptr; + using std::weak_ptr; + using std::enable_shared_from_this; using std::static_pointer_cast; typedef std::unique_ptr unique_ptr_uchar_array; #else - using boost::shared_ptr; - using boost::weak_ptr; - using boost::enable_shared_from_this; + using boost::shared_ptr; + using boost::weak_ptr; + using boost::enable_shared_from_this; using boost::static_pointer_cast; typedef boost::scoped_array unique_ptr_uchar_array; diff --git a/websocketpp/common/network.hpp b/websocketpp/common/network.hpp index fcbb6a214f..eb3d44f5b2 100644 --- a/websocketpp/common/network.hpp +++ b/websocketpp/common/network.hpp @@ -30,10 +30,10 @@ // For ntohs and htons #if defined(WIN32) - #include + #include #else - //#include - #include + //#include + #include #endif namespace websocketpp { @@ -41,7 +41,7 @@ namespace lib { namespace net { inline bool is_little_endian() { - short int val = 0x1; + short int val = 0x1; char *ptr = (char*)&val; return (ptr[0] == 1); } diff --git a/websocketpp/common/random.hpp b/websocketpp/common/random.hpp index b3162f37fe..9ee2b611e3 100644 --- a/websocketpp/common/random.hpp +++ b/websocketpp/common/random.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -29,24 +29,24 @@ #define WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP #if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_RANDOM_DEVICE_ - #ifndef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ - #define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ - #endif + #ifndef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ + #define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ + #endif #endif #ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ - #include + #include #else - #include - - #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 46 - #include - #include - #elif (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) >= 43 - #include - #else - // TODO: static_assert(false, "Could not find a suitable random_device") - #endif + #include + + #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 46 + #include + #include + #elif (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) >= 43 + #include + #else + // TODO: static_assert(false, "Could not find a suitable random_device") + #endif #endif namespace websocketpp { diff --git a/websocketpp/common/regex.hpp b/websocketpp/common/regex.hpp index ddc5e582c3..7a285e1b40 100644 --- a/websocketpp/common/regex.hpp +++ b/websocketpp/common/regex.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -29,15 +29,15 @@ #define WEBSOCKETPP_COMMON_REGEX_HPP #if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_REGEX_ - #ifndef _WEBSOCKETPP_CPP11_REGEX_ - #define _WEBSOCKETPP_CPP11_REGEX_ - #endif + #ifndef _WEBSOCKETPP_CPP11_REGEX_ + #define _WEBSOCKETPP_CPP11_REGEX_ + #endif #endif #ifdef _WEBSOCKETPP_CPP11_REGEX_ - #include + #include #else - #include + #include #endif namespace websocketpp { diff --git a/websocketpp/common/stdint.hpp b/websocketpp/common/stdint.hpp index 3e89407ea7..d272b39cf7 100644 --- a/websocketpp/common/stdint.hpp +++ b/websocketpp/common/stdint.hpp @@ -29,7 +29,7 @@ #define WEBSOCKETPP_COMMON_STDINT_HPP #ifndef __STDC_LIMIT_MACROS - #define __STDC_LIMIT_MACROS 1 + #define __STDC_LIMIT_MACROS 1 #endif #if WIN32 && (_MSC_VER < 1600) diff --git a/websocketpp/common/system_error.hpp b/websocketpp/common/system_error.hpp index f206318f5e..58a4c25602 100644 --- a/websocketpp/common/system_error.hpp +++ b/websocketpp/common/system_error.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -29,16 +29,16 @@ #define WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP #if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_ - #ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ - #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ - #endif + #ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ + #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ + #endif #endif #ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ - #include + #include #else - #include - #include + #include + #include #endif namespace websocketpp { diff --git a/websocketpp/common/thread.hpp b/websocketpp/common/thread.hpp index 411cd7daf8..2aac62de20 100644 --- a/websocketpp/common/thread.hpp +++ b/websocketpp/common/thread.hpp @@ -29,31 +29,31 @@ #define WEBSOCKETPP_COMMON_THREAD_HPP #if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_THREAD_ - #ifndef _WEBSOCKETPP_CPP11_THREAD_ - #define _WEBSOCKETPP_CPP11_THREAD_ - #endif + #ifndef _WEBSOCKETPP_CPP11_THREAD_ + #define _WEBSOCKETPP_CPP11_THREAD_ + #endif #endif #ifdef _WEBSOCKETPP_CPP11_THREAD_ - #include - #include + #include + #include #else - #include - #include - #include + #include + #include + #include #endif namespace websocketpp { namespace lib { #ifdef _WEBSOCKETPP_CPP11_THREAD_ - using std::mutex; - using std::lock_guard; - using std::thread; + using std::mutex; + using std::lock_guard; + using std::thread; #else - using boost::mutex; - using boost::lock_guard; - using boost::thread; + using boost::mutex; + using boost::lock_guard; + using boost::thread; #endif } // namespace lib diff --git a/websocketpp/concurrency/basic.hpp b/websocketpp/concurrency/basic.hpp index 9b34cc7b84..e9a2aa6ee7 100644 --- a/websocketpp/concurrency/basic.hpp +++ b/websocketpp/concurrency/basic.hpp @@ -35,8 +35,8 @@ namespace concurrency { class basic { public: - typedef lib::mutex mutex_type; - typedef lib::lock_guard scoped_lock_type; + typedef lib::mutex mutex_type; + typedef lib::lock_guard scoped_lock_type; }; } // namespace concurrency diff --git a/websocketpp/concurrency/none.hpp b/websocketpp/concurrency/none.hpp index 70a945d12a..1826b17e20 100644 --- a/websocketpp/concurrency/none.hpp +++ b/websocketpp/concurrency/none.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -47,11 +47,11 @@ public: class fake_lock_guard { public: - explicit fake_lock_guard(fake_mutex foo) { - //std::cout << "fake_lock_guard constructor: " << this << " mutex: " << &foo << std::endl; - } - - ~fake_lock_guard() { + explicit fake_lock_guard(fake_mutex foo) { + //std::cout << "fake_lock_guard constructor: " << this << " mutex: " << &foo << std::endl; + } + + ~fake_lock_guard() { //std::cout << "fake_lock_guard destructor: " << this << std::endl; } }; @@ -60,8 +60,8 @@ public: class none { public: - typedef none_impl::fake_mutex mutex_type; - typedef none_impl::fake_lock_guard scoped_lock_type; + typedef none_impl::fake_mutex mutex_type; + typedef none_impl::fake_lock_guard scoped_lock_type; }; } // namespace concurrency diff --git a/websocketpp/config/asio.hpp b/websocketpp/config/asio.hpp index adb6b1efc8..e764faf93a 100644 --- a/websocketpp/config/asio.hpp +++ b/websocketpp/config/asio.hpp @@ -42,19 +42,19 @@ namespace config { struct asio_tls : public core { typedef asio_tls type; - typedef core::concurrency_type concurrency_type; - - typedef core::request_type request_type; - typedef core::response_type response_type; + typedef core::concurrency_type concurrency_type; + + typedef core::request_type request_type; + typedef core::response_type response_type; - typedef core::message_type message_type; - typedef core::con_msg_manager_type con_msg_manager_type; - typedef core::endpoint_msg_manager_type endpoint_msg_manager_type; - - typedef core::alog_type alog_type; - typedef core::elog_type elog_type; - - typedef core::rng_type rng_type; + typedef core::message_type message_type; + typedef core::con_msg_manager_type con_msg_manager_type; + typedef core::endpoint_msg_manager_type endpoint_msg_manager_type; + + typedef core::alog_type alog_type; + typedef core::elog_type elog_type; + + typedef core::rng_type rng_type; struct transport_config { typedef type::concurrency_type concurrency_type; diff --git a/websocketpp/config/asio_client.hpp b/websocketpp/config/asio_client.hpp index ecb4fbcb45..e169537a38 100644 --- a/websocketpp/config/asio_client.hpp +++ b/websocketpp/config/asio_client.hpp @@ -42,19 +42,19 @@ namespace config { struct asio_tls_client : public core_client { typedef asio_tls_client type; - typedef core_client::concurrency_type concurrency_type; - - typedef core_client::request_type request_type; - typedef core_client::response_type response_type; + typedef core_client::concurrency_type concurrency_type; + + typedef core_client::request_type request_type; + typedef core_client::response_type response_type; - typedef core_client::message_type message_type; - typedef core_client::con_msg_manager_type con_msg_manager_type; - typedef core_client::endpoint_msg_manager_type endpoint_msg_manager_type; - - typedef core_client::alog_type alog_type; - typedef core_client::elog_type elog_type; - - typedef core_client::rng_type rng_type; + typedef core_client::message_type message_type; + typedef core_client::con_msg_manager_type con_msg_manager_type; + typedef core_client::endpoint_msg_manager_type endpoint_msg_manager_type; + + typedef core_client::alog_type alog_type; + typedef core_client::elog_type elog_type; + + typedef core_client::rng_type rng_type; struct transport_config { typedef type::concurrency_type concurrency_type; diff --git a/websocketpp/config/asio_no_tls.hpp b/websocketpp/config/asio_no_tls.hpp index 86a2cf2a4c..f4c1d9ea15 100644 --- a/websocketpp/config/asio_no_tls.hpp +++ b/websocketpp/config/asio_no_tls.hpp @@ -35,19 +35,19 @@ namespace websocketpp { namespace config { struct asio : public core { - typedef asio type; - - typedef core::concurrency_type concurrency_type; - - typedef core::request_type request_type; - typedef core::response_type response_type; + typedef asio type; + + typedef core::concurrency_type concurrency_type; + + typedef core::request_type request_type; + typedef core::response_type response_type; - typedef core::message_type message_type; - typedef core::con_msg_manager_type con_msg_manager_type; - typedef core::endpoint_msg_manager_type endpoint_msg_manager_type; - - typedef core::alog_type alog_type; - typedef core::elog_type elog_type; + typedef core::message_type message_type; + typedef core::con_msg_manager_type con_msg_manager_type; + typedef core::endpoint_msg_manager_type endpoint_msg_manager_type; + + typedef core::alog_type alog_type; + typedef core::elog_type elog_type; typedef core::rng_type rng_type; diff --git a/websocketpp/config/asio_no_tls_client.hpp b/websocketpp/config/asio_no_tls_client.hpp index 5a18d0c769..7c6f1a87da 100644 --- a/websocketpp/config/asio_no_tls_client.hpp +++ b/websocketpp/config/asio_no_tls_client.hpp @@ -37,17 +37,17 @@ namespace config { struct asio_client : public core_client { typedef asio_client type; - typedef core_client::concurrency_type concurrency_type; - - typedef core_client::request_type request_type; - typedef core_client::response_type response_type; + typedef core_client::concurrency_type concurrency_type; + + typedef core_client::request_type request_type; + typedef core_client::response_type response_type; - typedef core_client::message_type message_type; - typedef core_client::con_msg_manager_type con_msg_manager_type; - typedef core_client::endpoint_msg_manager_type endpoint_msg_manager_type; - - typedef core_client::alog_type alog_type; - typedef core_client::elog_type elog_type; + typedef core_client::message_type message_type; + typedef core_client::con_msg_manager_type con_msg_manager_type; + typedef core_client::endpoint_msg_manager_type endpoint_msg_manager_type; + + typedef core_client::alog_type alog_type; + typedef core_client::elog_type elog_type; typedef core_client::rng_type rng_type; diff --git a/websocketpp/config/core.hpp b/websocketpp/config/core.hpp index dc5d684671..eacee08f8a 100644 --- a/websocketpp/config/core.hpp +++ b/websocketpp/config/core.hpp @@ -69,28 +69,28 @@ struct core { // Concurrency policy typedef websocketpp::concurrency::basic 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; + message_type; typedef message_buffer::alloc::con_msg_manager - con_msg_manager_type; + con_msg_manager_type; typedef message_buffer::alloc::endpoint_msg_manager - endpoint_msg_manager_type; - - /// Logging policies - typedef websocketpp::log::basic elog_type; - typedef websocketpp::log::basic alog_type; - - /// RNG policies - typedef websocketpp::random::none::int_generator rng_type; - + endpoint_msg_manager_type; + + /// Logging policies + typedef websocketpp::log::basic elog_type; + typedef websocketpp::log::basic alog_type; + + /// RNG policies + typedef websocketpp::random::none::int_generator rng_type; + struct transport_config { typedef type::concurrency_type concurrency_type; typedef type::elog_type elog_type; @@ -143,7 +143,7 @@ struct core { websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel; /// - static const size_t connection_read_buffer_size = 512; + static const size_t connection_read_buffer_size = 512; /// Drop connections immediately on protocol error. /** diff --git a/websocketpp/config/core_client.hpp b/websocketpp/config/core_client.hpp index a7896af39b..653167bb02 100644 --- a/websocketpp/config/core_client.hpp +++ b/websocketpp/config/core_client.hpp @@ -67,29 +67,29 @@ struct core_client { // Concurrency policy typedef websocketpp::concurrency::basic 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; + message_type; typedef message_buffer::alloc::con_msg_manager - con_msg_manager_type; + con_msg_manager_type; typedef message_buffer::alloc::endpoint_msg_manager - endpoint_msg_manager_type; - - /// Logging policies - typedef websocketpp::log::basic elog_type; - typedef websocketpp::log::basic alog_type; - - /// RNG policies - typedef websocketpp::random::random_device::int_generator rng_type; - + endpoint_msg_manager_type; + + /// Logging policies + typedef websocketpp::log::basic elog_type; + typedef websocketpp::log::basic alog_type; + + /// RNG policies + typedef websocketpp::random::random_device::int_generator rng_type; + struct transport_config { typedef type::concurrency_type concurrency_type; typedef type::elog_type elog_type; @@ -142,7 +142,7 @@ struct core_client { websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel; /// - static const size_t connection_read_buffer_size = 512; + static const size_t connection_read_buffer_size = 512; /// Drop connections immediately on protocol error. /** diff --git a/websocketpp/config/debug.hpp b/websocketpp/config/debug.hpp index 3a8ad772e9..51b2ecbd85 100644 --- a/websocketpp/config/debug.hpp +++ b/websocketpp/config/debug.hpp @@ -69,28 +69,28 @@ struct debug_core { // Concurrency policy typedef websocketpp::concurrency::basic 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; + message_type; typedef message_buffer::alloc::con_msg_manager - con_msg_manager_type; + con_msg_manager_type; typedef message_buffer::alloc::endpoint_msg_manager - endpoint_msg_manager_type; - - /// Logging policies - typedef websocketpp::log::basic elog_type; - typedef websocketpp::log::basic alog_type; - - /// RNG policies - typedef websocketpp::random::none::int_generator rng_type; - + endpoint_msg_manager_type; + + /// Logging policies + typedef websocketpp::log::basic elog_type; + typedef websocketpp::log::basic alog_type; + + /// RNG policies + typedef websocketpp::random::none::int_generator rng_type; + struct transport_config { typedef type::concurrency_type concurrency_type; typedef type::elog_type elog_type; @@ -143,7 +143,7 @@ struct debug_core { websocketpp::log::alevel::all; /// - static const size_t connection_read_buffer_size = 512; + static const size_t connection_read_buffer_size = 512; /// Drop connections immediately on protocol error. /** diff --git a/websocketpp/config/debug_asio.hpp b/websocketpp/config/debug_asio.hpp index 010fb5d143..37f6c98503 100644 --- a/websocketpp/config/debug_asio.hpp +++ b/websocketpp/config/debug_asio.hpp @@ -41,21 +41,21 @@ namespace config { struct debug_asio_tls : public debug_core { typedef debug_asio_tls type; - typedef debug_core base; - - typedef base::concurrency_type concurrency_type; - - typedef base::request_type request_type; - typedef base::response_type response_type; + typedef debug_core base; + + typedef base::concurrency_type concurrency_type; + + typedef base::request_type request_type; + typedef base::response_type response_type; - typedef base::message_type message_type; - typedef base::con_msg_manager_type con_msg_manager_type; - typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; - - typedef base::alog_type alog_type; - typedef base::elog_type elog_type; - - typedef base::rng_type rng_type; + typedef base::message_type message_type; + typedef base::con_msg_manager_type con_msg_manager_type; + typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; + + typedef base::alog_type alog_type; + typedef base::elog_type elog_type; + + typedef base::rng_type rng_type; struct transport_config { typedef type::concurrency_type concurrency_type; diff --git a/websocketpp/config/debug_asio_no_tls.hpp b/websocketpp/config/debug_asio_no_tls.hpp index 7645a05335..6942190153 100644 --- a/websocketpp/config/debug_asio_no_tls.hpp +++ b/websocketpp/config/debug_asio_no_tls.hpp @@ -38,17 +38,17 @@ struct debug_asio : public debug_core { typedef debug_asio type; typedef debug_core base; - typedef base::concurrency_type concurrency_type; - - typedef base::request_type request_type; - typedef base::response_type response_type; + typedef base::concurrency_type concurrency_type; + + typedef base::request_type request_type; + typedef base::response_type response_type; - typedef base::message_type message_type; - typedef base::con_msg_manager_type con_msg_manager_type; - typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; - - typedef base::alog_type alog_type; - typedef base::elog_type elog_type; + typedef base::message_type message_type; + typedef base::con_msg_manager_type con_msg_manager_type; + typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; + + typedef base::alog_type alog_type; + typedef base::elog_type elog_type; typedef base::rng_type rng_type; diff --git a/websocketpp/connection.hpp b/websocketpp/connection.hpp index 11d05588df..e54209de40 100644 --- a/websocketpp/connection.hpp +++ b/websocketpp/connection.hpp @@ -72,7 +72,7 @@ typedef lib::function http_handler; namespace session { namespace state { - // externally visible session state (states based on the RFC) + // externally visible session state (states based on the RFC) enum value { connecting = 0, open = 1, @@ -96,20 +96,20 @@ namespace status { } // namespace fail namespace internal_state { - // More granular internal states. These are used for multi-threaded - // connection syncronization and preventing values that are not yet or no - // longer avaliable from being used. - - enum value { - USER_INIT = 0, - TRANSPORT_INIT = 1, - READ_HTTP_REQUEST = 2, - WRITE_HTTP_REQUEST = 3, - READ_HTTP_RESPONSE = 4, - WRITE_HTTP_RESPONSE = 5, - PROCESS_HTTP_REQUEST = 6, - PROCESS_CONNECTION = 7 - }; + // More granular internal states. These are used for multi-threaded + // connection syncronization and preventing values that are not yet or no + // longer avaliable from being used. + + enum value { + USER_INIT = 0, + TRANSPORT_INIT = 1, + READ_HTTP_REQUEST = 2, + WRITE_HTTP_REQUEST = 3, + READ_HTTP_RESPONSE = 4, + WRITE_HTTP_RESPONSE = 5, + PROCESS_HTTP_REQUEST = 6, + PROCESS_CONNECTION = 7 + }; } // namespace internal_state } // namespace session @@ -149,10 +149,10 @@ public: typedef typename config::request_type request_type; typedef typename config::response_type response_type; - typedef typename config::message_type message_type; - typedef typename message_type::ptr message_ptr; - - typedef typename config::con_msg_manager_type con_msg_manager_type; + typedef typename config::message_type message_type; + typedef typename message_type::ptr message_ptr; + + typedef typename config::con_msg_manager_type con_msg_manager_type; typedef typename con_msg_manager_type::ptr con_msg_manager_ptr; /// Type of RNG @@ -174,14 +174,14 @@ public: , m_state(session::state::connecting) , m_internal_state(session::internal_state::USER_INIT) , m_msg_manager(new con_msg_manager_type()) - , m_send_buffer_size(0) - , m_write_flag(false) - , m_is_server(is_server) - , m_alog(alog) - , m_elog(elog) - , m_rng(rng) - , m_local_close_code(close::status::abnormal_close) - , m_remote_close_code(close::status::abnormal_close) + , m_send_buffer_size(0) + , m_write_flag(false) + , m_is_server(is_server) + , m_alog(alog) + , m_elog(elog) + , m_rng(rng) + , m_local_close_code(close::status::abnormal_close) + , m_remote_close_code(close::status::abnormal_close) { m_alog.write(log::alevel::devel,"connection constructor"); } @@ -322,21 +322,21 @@ public: // Uncategorized public methods // ////////////////////////////////// - /// Get the size of the outgoing write buffer (in payload bytes) - /** - * Retrieves the number of bytes in the outgoing write buffer that have not + /// Get the size of the outgoing write buffer (in payload bytes) + /** + * Retrieves the number of bytes in the outgoing write buffer that have not * already been dispatched to the transport layer. This represents the bytes * that are presently cancelable without uncleanly ending the websocket * connection * * This method invokes the m_write_lock mutex - * - * @return The current number of bytes in the outgoing send buffer. - */ - size_t get_buffered_amount() const; + * + * @return The current number of bytes in the outgoing send buffer. + */ + size_t get_buffered_amount() const; - /// DEPRECATED: use get_buffered_amount instead - size_t buffered_amount() const {return get_buffered_amount();} + /// DEPRECATED: use get_buffered_amount instead + size_t buffered_amount() const {return get_buffered_amount();} //////////////////// // Action Methods // @@ -355,9 +355,9 @@ public: * frame::opcode::text */ lib::error_code send(const std::string& payload, frame::opcode::value op = - frame::opcode::TEXT); - - /// Send a message (raw array overload) + frame::opcode::TEXT); + + /// Send a message (raw array overload) /** * Convenience method to send a message given a raw array and optionally an * opcode. Default opcode is binary. @@ -781,7 +781,7 @@ public: void handle_write(const lib::error_code& ec); void handle_handshake_read(const lib::error_code& ec, - size_t bytes_transferred); + size_t bytes_transferred); void handle_read_http_response(const lib::error_code& ec, size_t bytes_transferred); @@ -977,8 +977,8 @@ private: void log_close_result(); // static settings - const std::string m_user_agent; - + const std::string m_user_agent; + /// Pointer to the connection handle connection_hdl m_connection_hdl; @@ -1040,13 +1040,13 @@ private: /** * Lock: m_write_lock */ - std::queue m_send_queue; + std::queue m_send_queue; /// Size in bytes of the outstanding payloads in the write queue /** * Lock: m_write_lock */ - size_t m_send_buffer_size; + size_t m_send_buffer_size; /// buffer holding the various parts of the current message being writen /** @@ -1074,7 +1074,7 @@ private: // of the whole connection. std::vector m_requested_subprotocols; - const bool m_is_server; + const bool m_is_server; alog_type& m_alog; elog_type& m_elog; diff --git a/websocketpp/endpoint.hpp b/websocketpp/endpoint.hpp index 2c59a3f614..7c38557774 100644 --- a/websocketpp/endpoint.hpp +++ b/websocketpp/endpoint.hpp @@ -42,21 +42,21 @@ static const char user_agent[] = "WebSocket++/0.3.0dev"; template class endpoint : public config::transport_type, public config::endpoint_base { public: - // Import appropriate types from our helper class - // See endpoint_types for more details. - typedef endpoint type; - + // Import appropriate types from our helper class + // See endpoint_types for more details. + typedef endpoint type; + /// Type of the transport component of this endpoint typedef typename config::transport_type transport_type; /// Type of the concurrency component of this endpoint - typedef typename config::concurrency_type concurrency_type; + typedef typename config::concurrency_type concurrency_type; /// Type of the connections that this endpoint creates - typedef connection connection_type; + typedef connection connection_type; /// Shared pointer to connection_type - typedef typename connection_type::ptr connection_ptr; + typedef typename connection_type::ptr connection_ptr; /// Weak pointer to connection type - typedef typename connection_type::weak_ptr connection_weak_ptr; + typedef typename connection_type::weak_ptr connection_weak_ptr; /// Type of the transport component of the connections that this endpoint /// creates @@ -64,7 +64,7 @@ public: /// Type of a shared pointer to the transport component of the connections /// that this endpoint creates. typedef typename transport_con_type::ptr transport_con_ptr; - + /// Type of message_handler typedef typename connection_type::message_handler message_handler; /// Type of message pointers that this endpoint uses @@ -73,70 +73,70 @@ public: /// Type of error logger typedef typename config::elog_type elog_type; /// Type of access logger - typedef typename config::alog_type alog_type; + typedef typename config::alog_type alog_type; /// Type of our concurrency policy's scoped lock object - typedef typename concurrency_type::scoped_lock_type scoped_lock_type; - /// Type of our concurrency policy's mutex object - typedef typename concurrency_type::mutex_type mutex_type; + typedef typename concurrency_type::scoped_lock_type scoped_lock_type; + /// Type of our concurrency policy's mutex object + typedef typename concurrency_type::mutex_type mutex_type; /// Type of RNG typedef typename config::rng_type rng_type; // TODO: organize these - typedef typename connection_type::termination_handler termination_handler; - + typedef typename connection_type::termination_handler termination_handler; + typedef lib::shared_ptr hdl_type; - explicit endpoint(bool is_server) - : m_alog(config::alog_level,&std::cout) - , m_elog(config::elog_level,&std::cerr) - , m_user_agent(::websocketpp::user_agent) - , m_is_server(is_server) - { - m_alog.set_channels(config::alog_level); - m_elog.set_channels(config::elog_level); - - m_alog.write(log::alevel::devel,"endpoint constructor"); + explicit endpoint(bool is_server) + : m_alog(config::alog_level,&std::cout) + , m_elog(config::elog_level,&std::cerr) + , m_user_agent(::websocketpp::user_agent) + , m_is_server(is_server) + { + m_alog.set_channels(config::alog_level); + m_elog.set_channels(config::elog_level); + + m_alog.write(log::alevel::devel,"endpoint constructor"); transport_type::init_logging(&m_elog,&m_alog); - } - - /// Returns the user agent string that this endpoint will use - /** - * Returns the user agent string that this endpoint will use when creating - * new connections. - * - * The default value for this version is WebSocket++/0.3.0dev - * - * @return The user agent string. - */ - std::string get_user_agent() const { + } + + /// Returns the user agent string that this endpoint will use + /** + * Returns the user agent string that this endpoint will use when creating + * new connections. + * + * The default value for this version is WebSocket++/0.3.0dev + * + * @return The user agent string. + */ + std::string get_user_agent() const { scoped_lock_type guard(m_mutex); - return m_user_agent; - } - - /// Sets the user agent string that this endpoint will use - /** - * Sets the user agent string that this endpoint will use when creating - * new connections. Changing this value will only affect future connections. - * - * For best results set this before accepting or opening connections. - * - * The default value for this version is WebSocket++/0.3.0dev - * - * @param ua The string to set the user agent to. - */ - void set_user_agent(const std::string& ua) { + return m_user_agent; + } + + /// Sets the user agent string that this endpoint will use + /** + * Sets the user agent string that this endpoint will use when creating + * new connections. Changing this value will only affect future connections. + * + * For best results set this before accepting or opening connections. + * + * The default value for this version is WebSocket++/0.3.0dev + * + * @param ua The string to set the user agent to. + */ + void set_user_agent(const std::string& ua) { scoped_lock_type guard(m_mutex); - m_user_agent = ua; - } - + m_user_agent = ua; + } + /// Returns whether or not this endpoint is a server. /** * @return Whether or not this endpoint is a server */ - bool is_server() const { + bool is_server() const { return m_is_server; } @@ -323,15 +323,15 @@ public: return con; } protected: - connection_ptr create_connection(); - void remove_connection(connection_ptr con); + connection_ptr create_connection(); + void remove_connection(connection_ptr con); alog_type m_alog; elog_type m_elog; private: - // dynamic settings - std::string m_user_agent; - + // dynamic settings + std::string m_user_agent; + open_handler m_open_handler; close_handler m_close_handler; fail_handler m_fail_handler; @@ -345,14 +345,14 @@ private: rng_type m_rng; - // endpoint resources - std::set m_connections; - - // static settings - const bool m_is_server; - - // endpoint state - mutex_type m_mutex; + // endpoint resources + std::set m_connections; + + // static settings + const bool m_is_server; + + // endpoint state + mutex_type m_mutex; }; } // namespace websocketpp diff --git a/websocketpp/error.hpp b/websocketpp/error.hpp index 9c34a62189..e094b867f2 100644 --- a/websocketpp/error.hpp +++ b/websocketpp/error.hpp @@ -105,67 +105,67 @@ enum value { class category : public lib::error_category { public: - category() {} + category() {} - const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { - return "websocketpp"; - } - - std::string message(int value) const { - switch(value) { - case error::general: - return "Generic error"; - case error::send_queue_full: - return "send queue full"; - case error::payload_violation: - return "payload violation"; - case error::endpoint_not_secure: - return "endpoint not secure"; - case error::endpoint_unavailable: - return "endpoint not available"; - case error::invalid_uri: - return "invalid uri"; - case error::no_outgoing_buffers: - return "no outgoing message buffers"; - case error::no_incoming_buffers: - return "no incoming message buffers"; - case error::invalid_state: - return "invalid state"; - case error::bad_close_code: - return "Unable to extract close code"; - case error::invalid_close_code: - return "Extracted close code is in an invalid range"; - case error::reserved_close_code: - return "Extracted close code is in a reserved range"; - case error::invalid_utf8: - return "Invalid UTF-8"; - case error::invalid_subprotocol: - return "Invalid subprotocol"; - case error::bad_connection: - return "Bad Connection"; - case error::test: - return "Test Error"; - case error::con_creation_failed: - return "Connection creation attempt failed"; - case error::unrequested_subprotocol: - return "Selected subprotocol was not requested by the client"; - case error::client_only: - return "Feature not available on server endpoints"; - case error::server_only: - return "Feature not available on client endpoints"; - default: - return "Unknown"; - } - } + const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { + return "websocketpp"; + } + + std::string message(int value) const { + switch(value) { + case error::general: + return "Generic error"; + case error::send_queue_full: + return "send queue full"; + case error::payload_violation: + return "payload violation"; + case error::endpoint_not_secure: + return "endpoint not secure"; + case error::endpoint_unavailable: + return "endpoint not available"; + case error::invalid_uri: + return "invalid uri"; + case error::no_outgoing_buffers: + return "no outgoing message buffers"; + case error::no_incoming_buffers: + return "no incoming message buffers"; + case error::invalid_state: + return "invalid state"; + case error::bad_close_code: + return "Unable to extract close code"; + case error::invalid_close_code: + return "Extracted close code is in an invalid range"; + case error::reserved_close_code: + return "Extracted close code is in a reserved range"; + case error::invalid_utf8: + return "Invalid UTF-8"; + case error::invalid_subprotocol: + return "Invalid subprotocol"; + case error::bad_connection: + return "Bad Connection"; + case error::test: + return "Test Error"; + case error::con_creation_failed: + return "Connection creation attempt failed"; + case error::unrequested_subprotocol: + return "Selected subprotocol was not requested by the client"; + case error::client_only: + return "Feature not available on server endpoints"; + case error::server_only: + return "Feature not available on client endpoints"; + default: + return "Unknown"; + } + } }; inline const lib::error_category& get_category() { - static category instance; - return instance; + static category instance; + return instance; } inline lib::error_code make_error_code(error::value e) { - return lib::error_code(static_cast(e), get_category()); + return lib::error_code(static_cast(e), get_category()); } } // namespace error diff --git a/websocketpp/frame.hpp b/websocketpp/frame.hpp index 8bad56f5c4..b6ffdef683 100644 --- a/websocketpp/frame.hpp +++ b/websocketpp/frame.hpp @@ -47,18 +47,18 @@ static const unsigned int MAX_HEADER_LENGTH = 14; static const unsigned int MAX_EXTENDED_HEADER_LENGTH = 12; union uint16_converter { - uint16_t i; - uint8_t c[2]; + uint16_t i; + uint8_t c[2]; }; union uint32_converter { - uint32_t i; - uint8_t c[4]; + uint32_t i; + uint8_t c[4]; }; union uint64_converter { - uint64_t i; - uint8_t c[8]; + uint64_t i; + uint8_t c[8]; }; // WebSocket Opcodes are 4 bits. See spec section 5.2 @@ -115,7 +115,7 @@ namespace opcode { namespace limits { /// Maximum size of a basic WebSocket payload - static const uint8_t payload_size_basic = 125; + static const uint8_t payload_size_basic = 125; /// Maximum size of an extended WebSocket payload (basic payload = 126) static const uint16_t payload_size_extended = 0xFFFF; // 2^16, 65535 /// Maximum size of a jumbo WebSocket payload (basic payload = 127) @@ -123,7 +123,7 @@ namespace limits { /// Maximum size of close frame reason /// This is payload_size_basic - 2 bytes (as first two bytes are used for //// the close code - static const uint8_t close_reason_size = 123; + static const uint8_t close_reason_size = 123; } @@ -136,97 +136,97 @@ static const uint8_t BHB0_FIN = 0x80; static const uint8_t BHB1_PAYLOAD = 0x7F; static const uint8_t BHB1_MASK = 0x80; - + static const uint8_t payload_size_code_16bit = 0x7E; // 126 static const uint8_t payload_size_code_64bit = 0x7F; // 127 typedef uint32_converter masking_key_type; struct basic_header { - basic_header() : b0(0x00),b1(0x00) {} - - basic_header(uint8_t p0, uint8_t p1) : b0(p0), b1(p1) {} - - basic_header(opcode::value op, uint64_t size, bool fin, bool mask, - bool rsv1 = false, bool rsv2 = false, bool rsv3 = false) : b0(0x00), - b1(0x00) - { - if (fin) { - b0 |= BHB0_FIN; - } - if (rsv1) { - b0 |= BHB0_RSV1; - } - if (rsv2) { - b0 |= BHB0_RSV2; - } - if (rsv3) { - b0 |= BHB0_RSV3; - } - b0 |= (op & BHB0_OPCODE); - - if (mask) { - b1 |= BHB1_MASK; - } - - uint8_t basic_value; - - if (size <= limits::payload_size_basic) { - basic_value = static_cast(size); - } else if (size <= limits::payload_size_extended) { - basic_value = payload_size_code_16bit; - } else { - basic_value = payload_size_code_64bit; - } - - - b1 |= basic_value; - } - - uint8_t b0; - uint8_t b1; + basic_header() : b0(0x00),b1(0x00) {} + + basic_header(uint8_t p0, uint8_t p1) : b0(p0), b1(p1) {} + + basic_header(opcode::value op, uint64_t size, bool fin, bool mask, + bool rsv1 = false, bool rsv2 = false, bool rsv3 = false) : b0(0x00), + b1(0x00) + { + if (fin) { + b0 |= BHB0_FIN; + } + if (rsv1) { + b0 |= BHB0_RSV1; + } + if (rsv2) { + b0 |= BHB0_RSV2; + } + if (rsv3) { + b0 |= BHB0_RSV3; + } + b0 |= (op & BHB0_OPCODE); + + if (mask) { + b1 |= BHB1_MASK; + } + + uint8_t basic_value; + + if (size <= limits::payload_size_basic) { + basic_value = static_cast(size); + } else if (size <= limits::payload_size_extended) { + basic_value = payload_size_code_16bit; + } else { + basic_value = payload_size_code_64bit; + } + + + b1 |= basic_value; + } + + uint8_t b0; + uint8_t b1; }; struct extended_header { - extended_header() { - std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); - } - - extended_header(uint64_t payload_size) { - std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); - - copy_payload(payload_size); - } - - extended_header(uint64_t payload_size, uint32_t masking_key) { - std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); - - // Copy payload size - int offset = copy_payload(payload_size); - - // Copy Masking Key - uint32_converter temp32; - temp32.i = masking_key; - std::copy(temp32.c,temp32.c+4,bytes+offset); - } + extended_header() { + std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); + } + + extended_header(uint64_t payload_size) { + std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); + + copy_payload(payload_size); + } + + extended_header(uint64_t payload_size, uint32_t masking_key) { + std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); + + // Copy payload size + int offset = copy_payload(payload_size); + + // Copy Masking Key + uint32_converter temp32; + temp32.i = masking_key; + std::copy(temp32.c,temp32.c+4,bytes+offset); + } - uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH]; + uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH]; private: - int copy_payload(uint64_t payload_size) { - int payload_offset = 0; - - if (payload_size <= limits::payload_size_basic) { - payload_offset = 8; - } else if (payload_size <= limits::payload_size_extended) { - payload_offset = 6; - } - - uint64_converter temp64; - temp64.i = lib::net::htonll(payload_size); - std::copy(temp64.c+payload_offset,temp64.c+8,bytes); - - return 8-payload_offset; - } + int copy_payload(uint64_t payload_size) { + int payload_offset = 0; + + if (payload_size <= limits::payload_size_basic) { + payload_offset = 8; + } else if (payload_size <= limits::payload_size_extended) { + payload_offset = 6; + } + + uint64_converter temp64; + temp64.i = lib::net::htonll(payload_size); + std::copy(temp64.c+payload_offset,temp64.c+8,bytes); + + return 8-payload_offset; + } }; // Forward function declarations @@ -256,12 +256,12 @@ void byte_mask(iter_type b, iter_type e, iter_type o, const masking_key_type& key, size_t key_offset = 0); template void byte_mask(iter_type b, iter_type e, const masking_key_type& key, - size_t key_offset = 0); + size_t key_offset = 0); void word_mask_exact(uint8_t* input, uint8_t* output, size_t length, - const masking_key_type& key); + const masking_key_type& key); void word_mask_exact(uint8_t* data, size_t length, const masking_key_type& key); size_t word_mask_circ(uint8_t* input, uint8_t* output, size_t length, - size_t prepared_key); + size_t prepared_key); size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key); @@ -272,7 +272,7 @@ size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key); * @return True if the header's fin bit is set. */ inline bool get_fin(const basic_header &h) { - return ((h.b0 & BHB0_FIN) == BHB0_FIN); + return ((h.b0 & BHB0_FIN) == BHB0_FIN); } /// Set the frame's FIN bit @@ -282,7 +282,7 @@ inline bool get_fin(const basic_header &h) { * @param value Value to set it to */ inline void set_fin(basic_header &h, bool value) { - h.b0 = (value ? h.b0 | BHB0_FIN : h.b0 & ~BHB0_FIN); + h.b0 = (value ? h.b0 | BHB0_FIN : h.b0 & ~BHB0_FIN); } /// check whether the frame's RSV1 bit is set @@ -290,7 +290,7 @@ inline void set_fin(basic_header &h, bool value) { * @return True if the header's RSV1 bit is set. */ inline bool get_rsv1(const basic_header &h) { - return ((h.b0 & BHB0_RSV1) == BHB0_RSV1); + return ((h.b0 & BHB0_RSV1) == BHB0_RSV1); } /// Set the frame's RSV1 bit @@ -300,7 +300,7 @@ inline bool get_rsv1(const basic_header &h) { * @param value Value to set it to */ inline void set_rsv1(basic_header &h, bool value) { - h.b0 = (value ? h.b0 | BHB0_RSV1 : h.b0 & ~BHB0_RSV1); + h.b0 = (value ? h.b0 | BHB0_RSV1 : h.b0 & ~BHB0_RSV1); } /// check whether the frame's RSV2 bit is set @@ -308,7 +308,7 @@ inline void set_rsv1(basic_header &h, bool value) { * @return True if the header's RSV2 bit is set. */ inline bool get_rsv2(const basic_header &h) { - return ((h.b0 & BHB0_RSV2) == BHB0_RSV2); + return ((h.b0 & BHB0_RSV2) == BHB0_RSV2); } /// Set the frame's RSV2 bit @@ -318,7 +318,7 @@ inline bool get_rsv2(const basic_header &h) { * @param value Value to set it to */ inline void set_rsv2(basic_header &h, bool value) { - h.b0 = (value ? h.b0 | BHB0_RSV2 : h.b0 & ~BHB0_RSV2); + h.b0 = (value ? h.b0 | BHB0_RSV2 : h.b0 & ~BHB0_RSV2); } /// check whether the frame's RSV3 bit is set @@ -326,7 +326,7 @@ inline void set_rsv2(basic_header &h, bool value) { * @return True if the header's RSV3 bit is set. */ inline bool get_rsv3(const basic_header &h) { - return ((h.b0 & BHB0_RSV3) == BHB0_RSV3); + return ((h.b0 & BHB0_RSV3) == BHB0_RSV3); } /// Set the frame's RSV3 bit @@ -336,12 +336,12 @@ inline bool get_rsv3(const basic_header &h) { * @param value Value to set it to */ inline void set_rsv3(basic_header &h, bool value) { - h.b0 = (value ? h.b0 | BHB0_RSV3 : h.b0 & ~BHB0_RSV3); + h.b0 = (value ? h.b0 | BHB0_RSV3 : h.b0 & ~BHB0_RSV3); } /// Extract opcode from basic header inline opcode::value get_opcode(const basic_header &h) { - return opcode::value(h.b0 & BHB0_OPCODE); + return opcode::value(h.b0 & BHB0_OPCODE); } /// check whether the frame is masked @@ -349,7 +349,7 @@ inline opcode::value get_opcode(const basic_header &h) { * @return True if the header mask bit is set. */ inline bool get_masked(const basic_header &h) { - return ((h.b1 & BHB1_MASK) == BHB1_MASK); + return ((h.b1 & BHB1_MASK) == BHB1_MASK); } /// Set the frame's MASK bit @@ -359,7 +359,7 @@ inline bool get_masked(const basic_header &h) { * @param value Value to set it to */ inline void set_masked(basic_header &h, bool value) { - h.b1 = (value ? h.b1 | BHB1_MASK : h.b1 & ~BHB1_MASK); + h.b1 = (value ? h.b1 | BHB1_MASK : h.b1 & ~BHB1_MASK); } /// Extracts the raw payload length specified in the basic header @@ -380,7 +380,7 @@ inline void set_masked(basic_header &h, bool value) { * @return the exact size encoded in h */ inline uint8_t get_basic_size(const basic_header &h) { - return h.b1 & BHB1_PAYLOAD; + return h.b1 & BHB1_PAYLOAD; } /// Set the frame's MASK bit @@ -392,23 +392,23 @@ inline uint8_t get_basic_size(const basic_header &h) { inline lib::error_code set_size(basic_header &h, extended_header &eh, uint64_t size) { - // make sure value isn't too big - uint8_t basic_value; - - if (size <= limits::payload_size_basic) { - basic_value = static_cast(size); - } else if (size <= limits::payload_size_extended) { - basic_value = payload_size_code_16bit; - } else if (size <= limits::payload_size_jumbo) { - basic_value = payload_size_code_64bit; - } else { - // error - return lib::error_code(); - } - - h.b1 = (basic_value & BHB1_PAYLOAD) | (h.b1 & BHB1_MASK); - - return lib::error_code(); + // make sure value isn't too big + uint8_t basic_value; + + if (size <= limits::payload_size_basic) { + basic_value = static_cast(size); + } else if (size <= limits::payload_size_extended) { + basic_value = payload_size_code_16bit; + } else if (size <= limits::payload_size_jumbo) { + basic_value = payload_size_code_64bit; + } else { + // error + return lib::error_code(); + } + + h.b1 = (basic_value & BHB1_PAYLOAD) | (h.b1 & BHB1_MASK); + + return lib::error_code(); } /// Calculates the full length of the header based on the first bytes. @@ -423,18 +423,18 @@ inline lib::error_code set_size(basic_header &h, extended_header &eh, uint64_t * @return Full length of the extended header. */ inline size_t get_header_len(const basic_header &h) { - // TODO: check extensions? - - // masking key offset represents the space used for the extended length - // fields - size_t size = BASIC_HEADER_LENGTH + get_masking_key_offset(h); - - // If the header is masked there is a 4 byte masking key - if (get_masked(h)) { - size += 4; - } - - return size; + // TODO: check extensions? + + // masking key offset represents the space used for the extended length + // fields + size_t size = BASIC_HEADER_LENGTH + get_masking_key_offset(h); + + // If the header is masked there is a 4 byte masking key + if (get_masked(h)) { + size += 4; + } + + return size; } /// Calculate the offset location of the masking key within the extended header @@ -447,13 +447,13 @@ inline size_t get_header_len(const basic_header &h) { * @return byte offset of the first byte of the masking key */ inline unsigned int get_masking_key_offset(const basic_header &h) { - if (get_basic_size(h) == payload_size_code_16bit) { - return 2; - } else if (get_basic_size(h) == payload_size_code_64bit) { - return 8; - } else { - return 0; - } + if (get_basic_size(h) == payload_size_code_16bit) { + return 2; + } else if (get_basic_size(h) == payload_size_code_64bit) { + return 8; + } else { + return 0; + } } /// Generate a properly sized contiguous string that encodes a full frame header @@ -469,16 +469,16 @@ inline unsigned int get_masking_key_offset(const basic_header &h) { inline std::string prepare_header(const basic_header &h, const extended_header &e) { - std::string ret; - - ret.push_back(char(h.b0)); - ret.push_back(char(h.b1)); - ret.append( - reinterpret_cast(e.bytes), - get_header_len(h)-BASIC_HEADER_LENGTH - ); - - return ret; + std::string ret; + + ret.push_back(char(h.b0)); + ret.push_back(char(h.b1)); + ret.append( + reinterpret_cast(e.bytes), + get_header_len(h)-BASIC_HEADER_LENGTH + ); + + return ret; } /// Extract the masking key from a frame header @@ -496,16 +496,16 @@ inline std::string prepare_header(const basic_header &h, const inline masking_key_type get_masking_key(const basic_header &h, const extended_header &e) { - masking_key_type temp32; + masking_key_type temp32; - if (!get_masked(h)) { - temp32.i = 0; - } else { - unsigned int offset = get_masking_key_offset(h); - std::copy(e.bytes+offset,e.bytes+offset+4,temp32.c); - } + if (!get_masked(h)) { + temp32.i = 0; + } else { + unsigned int offset = get_masking_key_offset(h); + std::copy(e.bytes+offset,e.bytes+offset+4,temp32.c); + } - return temp32; + return temp32; } /// Extract the extended size field from an extended header @@ -518,9 +518,9 @@ inline masking_key_type get_masking_key(const basic_header &h, const * @return The size encoded in the extended header in host byte order */ inline uint16_t get_extended_size(const extended_header &e) { - uint16_converter temp16; - std::copy(e.bytes,e.bytes+2,temp16.c); - return ntohs(temp16.i); + uint16_converter temp16; + std::copy(e.bytes,e.bytes+2,temp16.c); + return ntohs(temp16.i); } /// Extract the jumbo size field from an extended header @@ -533,9 +533,9 @@ inline uint16_t get_extended_size(const extended_header &e) { * @return The size encoded in the extended header in host byte order */ inline uint64_t get_jumbo_size(const extended_header &e) { - uint64_converter temp64; - std::copy(e.bytes,e.bytes+8,temp64.c); - return lib::net::ntohll(temp64.i); + uint64_converter temp64; + std::copy(e.bytes,e.bytes+8,temp64.c); + return lib::net::ntohll(temp64.i); } /// Extract the full payload size field from a WebSocket header @@ -553,15 +553,15 @@ inline uint64_t get_jumbo_size(const extended_header &e) { inline uint64_t get_payload_size(const basic_header &h, const extended_header &e) { - uint8_t val = get_basic_size(h); + uint8_t val = get_basic_size(h); - if (val <= limits::payload_size_basic) { - return val; - } else if (val == payload_size_code_16bit) { - return get_extended_size(e); - } else { - return get_jumbo_size(e); - } + if (val <= limits::payload_size_basic) { + return val; + } else if (val == payload_size_code_16bit) { + return get_extended_size(e); + } else { + return get_jumbo_size(e); + } } /// Extract a masking key into a value the size of a machine word. @@ -573,14 +573,14 @@ inline uint64_t get_payload_size(const basic_header &h, const * @return prepared key as a machine word */ inline size_t prepare_masking_key(const masking_key_type& key) { - size_t low_bits = static_cast(key.i); - - if (sizeof(size_t) == 8) { - uint64_t high_bits = static_cast(key.i); - return static_cast((high_bits << 32) | low_bits); - } else { - return low_bits; - } + size_t low_bits = static_cast(key.i); + + if (sizeof(size_t) == 8) { + uint64_t high_bits = static_cast(key.i); + return static_cast((high_bits << 32) | low_bits); + } else { + return low_bits; + } } /// circularly shifts the supplied prepared masking key by offset bytes @@ -648,7 +648,7 @@ void byte_mask(iter_type b, iter_type e, iter_type o, const masking_key_type& */ template void byte_mask(iter_type b, iter_type e, const masking_key_type& key, - size_t key_offset) + size_t key_offset) { byte_mask(b,e,b,key,key_offset); } @@ -675,7 +675,7 @@ void byte_mask(iter_type b, iter_type e, const masking_key_type& key, * @param key Masking key to use */ inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length, - const masking_key_type& key) + const masking_key_type& key) { size_t prepared_key = prepare_masking_key(key); size_t n = length/sizeof(size_t); @@ -741,26 +741,26 @@ inline void word_mask_exact(uint8_t* data, size_t length, const * @return the prepared_key shifted to account for the input length */ inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length, - size_t prepared_key) + size_t prepared_key) { size_t n = length / sizeof(size_t); // whole words - size_t l = length - (n * sizeof(size_t)); // remaining bytes + size_t l = length - (n * sizeof(size_t)); // remaining bytes size_t * input_word = reinterpret_cast(input); size_t * output_word = reinterpret_cast(output); - // mask word by word + // mask word by word for (size_t i = 0; i < n; i++) { output_word[i] = input_word[i] ^ prepared_key; } - - // mask partial word at the end + + // mask partial word at the end size_t start = length - l; uint8_t * byte_key = reinterpret_cast(&prepared_key); for (size_t i = 0; i < l; ++i) { output[start+i] = input[start+i] ^ byte_key[i]; } - - return circshift_prepared_key(prepared_key,l); + + return circshift_prepared_key(prepared_key,l); } /// Circular word aligned mask/unmask (in place) @@ -778,7 +778,7 @@ inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length, * @return the prepared_key shifted to account for the input length */ inline size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key){ - return word_mask_circ(data,data,length,prepared_key); + return word_mask_circ(data,data,length,prepared_key); } } // namespace frame diff --git a/websocketpp/http/constants.hpp b/websocketpp/http/constants.hpp index dfdf1dabed..c4a8dee817 100644 --- a/websocketpp/http/constants.hpp +++ b/websocketpp/http/constants.hpp @@ -46,39 +46,39 @@ namespace http { // 0x00 - 0x32, 0x7f-0xff // ( ) < > @ , ; : \ " / [ ] ? = { } static const char header_token[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f - 0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f - 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f - 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f - 1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f + 0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f + 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f + 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f + 1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff }; inline bool is_token_char(unsigned char c) { - return (header_token[c] == 1); + return (header_token[c] == 1); } inline bool is_not_token_char(unsigned char c) { - return !header_token[c]; + return !header_token[c]; } // Space (32) or horizontal tab (9) inline bool is_whitespace_char(unsigned char c) { - return (c == 9 || c == 32); + return (c == 9 || c == 32); } inline bool is_not_whitespace_char(unsigned char c) { - return (c != 9 && c != 32); + return (c != 9 && c != 32); } namespace status_code { @@ -142,7 +142,7 @@ namespace http { inline std::string get_string(value c) { switch (c) { case uninitialized: - return "Uninitialized"; + return "Uninitialized"; case continue_code: return "Continue"; case switching_protocols: @@ -180,7 +180,7 @@ namespace http { case unauthorized: return "Unauthorized"; case payment_required: - return "Payment Required"; + return "Payment Required"; case forbidden: return "Forbidden"; case not_found: diff --git a/websocketpp/http/impl/parser.hpp b/websocketpp/http/impl/parser.hpp index 75931d9c03..ad9c3aba56 100644 --- a/websocketpp/http/impl/parser.hpp +++ b/websocketpp/http/impl/parser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -109,16 +109,16 @@ inline void parser::remove_header(const std::string &key) { } inline void parser::set_body(const std::string& value) { - if (value.size() == 0) { - remove_header("Content-Length"); - m_body = ""; - return; - } - - std::stringstream foo; - foo << value.size(); - replace_header("Content-Length", foo.str()); - m_body = value; + if (value.size() == 0) { + remove_header("Content-Length"); + m_body = ""; + return; + } + + std::stringstream foo; + foo << value.size(); + replace_header("Content-Length", foo.str()); + m_body = value; } inline bool parser::parse_headers(std::istream& s) { diff --git a/websocketpp/http/impl/request.hpp b/websocketpp/http/impl/request.hpp index f1a6fd0239..4032ed304a 100644 --- a/websocketpp/http/impl/request.hpp +++ b/websocketpp/http/impl/request.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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,143 +38,143 @@ namespace http { namespace parser { inline bool request::parse_complete(std::istream& s) { - std::string request; - - // get status line - std::getline(s, request); - - if (request[request.size()-1] == '\r') { - request.erase(request.end()-1); - - std::stringstream ss(request); - std::string val; - - ss >> val; - set_method(val); - - ss >> val; - set_uri(val); - - ss >> val; - set_version(val); - } else { - return false; - } - - return parse_headers(s); + std::string request; + + // get status line + std::getline(s, request); + + if (request[request.size()-1] == '\r') { + request.erase(request.end()-1); + + std::stringstream ss(request); + std::string val; + + ss >> val; + set_method(val); + + ss >> val; + set_uri(val); + + ss >> val; + set_version(val); + } else { + return false; + } + + return parse_headers(s); } inline size_t request::consume(const char *buf, size_t len) { - if (m_ready) {return 0;} - - if (m_buf->size() + len > max_header_size) { - // exceeded max header size - throw exception("Maximum header size exceeded.", - status_code::request_header_fields_too_large); - } - - // copy new header bytes into buffer - m_buf->append(buf,len); - - // Search for delimiter in buf. If found read until then. If not read all - std::string::iterator begin = m_buf->begin(); - std::string::iterator end; - - for (;;) { - // search for line delimiter - end = std::search( - begin, - m_buf->end(), - header_delimiter, - header_delimiter+sizeof(header_delimiter)-1 - ); - - //std::cout << "mark5: " << end-begin << std::endl; - //std::cout << "mark6: " << sizeof(header_delimiter) << std::endl; + if (m_ready) {return 0;} + + if (m_buf->size() + len > max_header_size) { + // exceeded max header size + throw exception("Maximum header size exceeded.", + status_code::request_header_fields_too_large); + } + + // copy new header bytes into buffer + m_buf->append(buf,len); + + // Search for delimiter in buf. If found read until then. If not read all + std::string::iterator begin = m_buf->begin(); + std::string::iterator end; + + for (;;) { + // search for line delimiter + end = std::search( + begin, + m_buf->end(), + header_delimiter, + header_delimiter+sizeof(header_delimiter)-1 + ); + + //std::cout << "mark5: " << end-begin << std::endl; + //std::cout << "mark6: " << sizeof(header_delimiter) << std::endl; - if (end == m_buf->end()) { - // we are out of bytes. Discard the processed bytes and copy the - // remaining unprecessed bytes to the beginning of the buffer - std::copy(begin,end,m_buf->begin()); - m_buf->resize(static_cast(end-begin)); - - return len; - } - - //the range [begin,end) now represents a line to be processed. - if (end-begin == 0) { - // we got a blank line - if (m_method.empty() || get_header("Host") == "") { - throw exception("Incomplete Request",status_code::bad_request); - } - m_ready = true; - - size_t bytes_processed = ( - len - static_cast(m_buf->end()-end) - + sizeof(header_delimiter) - 1 - ); - - // frees memory used temporarily during request parsing - m_buf.reset(); - - // return number of bytes processed (starting bytes - bytes left) - return bytes_processed; - } else { - if (m_method.empty()) { - this->process(begin,end); - } else { - this->process_header(begin,end); - } - } - - begin = end+sizeof(header_delimiter)-1; - } + if (end == m_buf->end()) { + // we are out of bytes. Discard the processed bytes and copy the + // remaining unprecessed bytes to the beginning of the buffer + std::copy(begin,end,m_buf->begin()); + m_buf->resize(static_cast(end-begin)); + + return len; + } + + //the range [begin,end) now represents a line to be processed. + if (end-begin == 0) { + // we got a blank line + if (m_method.empty() || get_header("Host") == "") { + throw exception("Incomplete Request",status_code::bad_request); + } + m_ready = true; + + size_t bytes_processed = ( + len - static_cast(m_buf->end()-end) + + sizeof(header_delimiter) - 1 + ); + + // frees memory used temporarily during request parsing + m_buf.reset(); + + // return number of bytes processed (starting bytes - bytes left) + return bytes_processed; + } else { + if (m_method.empty()) { + this->process(begin,end); + } else { + this->process_header(begin,end); + } + } + + begin = end+sizeof(header_delimiter)-1; + } } inline std::string request::raw() { - // TODO: validation. Make sure all required fields have been set? - std::stringstream raw; - - raw << m_method << " " << m_uri << " " << get_version() << "\r\n"; - raw << raw_headers() << "\r\n" << m_body; - - return raw.str(); + // TODO: validation. Make sure all required fields have been set? + std::stringstream raw; + + raw << m_method << " " << m_uri << " " << get_version() << "\r\n"; + raw << raw_headers() << "\r\n" << m_body; + + return raw.str(); } inline void request::set_method(const std::string& method) { - if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) { - throw exception("Invalid method token.",status_code::bad_request); - } + if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) { + throw exception("Invalid method token.",status_code::bad_request); + } - m_method = method; + m_method = method; } inline void request::set_uri(const std::string& uri) { - // TODO: validation? - m_uri = uri; + // TODO: validation? + m_uri = uri; } inline void request::process(std::string::iterator begin, std::string::iterator end) { - std::string::iterator cursor_start = begin; - std::string::iterator cursor_end = std::find(begin,end,' '); - - if (cursor_end == end) { - throw exception("Invalid request line1",status_code::bad_request); - } - - set_method(std::string(cursor_start,cursor_end)); - - cursor_start = cursor_end+1; - cursor_end = std::find(cursor_start,end,' '); - - if (cursor_end == end) { - throw exception("Invalid request line2",status_code::bad_request); - } - - set_uri(std::string(cursor_start,cursor_end)); - set_version(std::string(cursor_end+1,end)); + std::string::iterator cursor_start = begin; + std::string::iterator cursor_end = std::find(begin,end,' '); + + if (cursor_end == end) { + throw exception("Invalid request line1",status_code::bad_request); + } + + set_method(std::string(cursor_start,cursor_end)); + + cursor_start = cursor_end+1; + cursor_end = std::find(cursor_start,end,' '); + + if (cursor_end == end) { + throw exception("Invalid request line2",status_code::bad_request); + } + + set_uri(std::string(cursor_start,cursor_end)); + set_version(std::string(cursor_end+1,end)); } } // namespace parser diff --git a/websocketpp/http/impl/response.hpp b/websocketpp/http/impl/response.hpp index 2eaf047b70..74516ed2ea 100644 --- a/websocketpp/http/impl/response.hpp +++ b/websocketpp/http/impl/response.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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,97 +38,97 @@ namespace http { namespace parser { inline size_t response::consume(const char *buf, size_t len) { - if (m_state == DONE) {return 0;} - - if (m_state == BODY) { - return this->process_body(buf,len); - } - - if (m_read + len > max_header_size) { - // exceeded max header size - throw exception("Maximum header size exceeded.", - status_code::request_header_fields_too_large); - } - - // copy new header bytes into buffer - m_buf->append(buf,len); - - // Search for delimiter in buf. If found read until then. If not read all - std::string::iterator begin = m_buf->begin(); - std::string::iterator end = begin; - - - for (;;) { - // search for delimiter - end = std::search( - begin, - m_buf->end(), - header_delimiter, - header_delimiter + sizeof(header_delimiter) - 1 - ); - - if (end == m_buf->end()) { - // we are out of bytes. Discard the processed bytes and copy the - // remaining unprecessed bytes to the beginning of the buffer - std::copy(begin,end,m_buf->begin()); - m_buf->resize(static_cast(end-begin)); - - m_read +=len; - - return len; - } - - //the range [begin,end) now represents a line to be processed. - - if (end-begin == 0) { - // we got a blank line - if (m_state == RESPONSE_LINE) { - throw exception("Incomplete Request",status_code::bad_request); - } - - // TODO: grab content-length - std::string length = get_header("Content-Length"); - - if (length == "") { - // no content length found, read indefinitely - m_read = 0; - } else { - std::istringstream ss(length); - - if ((ss >> m_read).fail()) { - throw exception("Unable to parse Content-Length header", - status_code::bad_request); - } - } - - m_state = BODY; - - // calc header bytes processed (starting bytes - bytes left) - size_t read = ( - len - static_cast(m_buf->end() - end) - + sizeof(header_delimiter) - 1 - ); - - // if there were bytes left process them as body bytes - if (read < len) { - read += this->process_body(buf+read,(len-read)); - } - - // frees memory used temporarily during header parsing - m_buf.reset(); - - return read; - } else { - if (m_state == RESPONSE_LINE) { - this->process(begin,end); - m_state = HEADERS; - } else { - this->process_header(begin,end); - } - } - - begin = end+sizeof(header_delimiter) - 1; - } + if (m_state == DONE) {return 0;} + + if (m_state == BODY) { + return this->process_body(buf,len); + } + + if (m_read + len > max_header_size) { + // exceeded max header size + throw exception("Maximum header size exceeded.", + status_code::request_header_fields_too_large); + } + + // copy new header bytes into buffer + m_buf->append(buf,len); + + // Search for delimiter in buf. If found read until then. If not read all + std::string::iterator begin = m_buf->begin(); + std::string::iterator end = begin; + + + for (;;) { + // search for delimiter + end = std::search( + begin, + m_buf->end(), + header_delimiter, + header_delimiter + sizeof(header_delimiter) - 1 + ); + + if (end == m_buf->end()) { + // we are out of bytes. Discard the processed bytes and copy the + // remaining unprecessed bytes to the beginning of the buffer + std::copy(begin,end,m_buf->begin()); + m_buf->resize(static_cast(end-begin)); + + m_read +=len; + + return len; + } + + //the range [begin,end) now represents a line to be processed. + + if (end-begin == 0) { + // we got a blank line + if (m_state == RESPONSE_LINE) { + throw exception("Incomplete Request",status_code::bad_request); + } + + // TODO: grab content-length + std::string length = get_header("Content-Length"); + + if (length == "") { + // no content length found, read indefinitely + m_read = 0; + } else { + std::istringstream ss(length); + + if ((ss >> m_read).fail()) { + throw exception("Unable to parse Content-Length header", + status_code::bad_request); + } + } + + m_state = BODY; + + // calc header bytes processed (starting bytes - bytes left) + size_t read = ( + len - static_cast(m_buf->end() - end) + + sizeof(header_delimiter) - 1 + ); + + // if there were bytes left process them as body bytes + if (read < len) { + read += this->process_body(buf+read,(len-read)); + } + + // frees memory used temporarily during header parsing + m_buf.reset(); + + return read; + } else { + if (m_state == RESPONSE_LINE) { + this->process(begin,end); + m_state = HEADERS; + } else { + this->process_header(begin,end); + } + } + + begin = end+sizeof(header_delimiter) - 1; + } } inline size_t response::consume(std::istream & s) { @@ -171,115 +171,115 @@ inline size_t response::consume(std::istream & s) { } inline bool response::parse_complete(std::istream& s) { - // parse a complete header (ie \r\n\r\n MUST be in the input stream) - std::string response; - - // get status line - std::getline(s, response); - - if (response[response.size()-1] == '\r') { - response.erase(response.end()-1); - - std::stringstream ss(response); - std::string str_val; - int int_val; - char char_val[256]; - - ss >> str_val; - set_version(str_val); - - ss >> int_val; - ss.getline(char_val,256); - set_status(status_code::value(int_val),std::string(char_val)); - } else { - return false; - } - - return parse_headers(s); + // parse a complete header (ie \r\n\r\n MUST be in the input stream) + std::string response; + + // get status line + std::getline(s, response); + + if (response[response.size()-1] == '\r') { + response.erase(response.end()-1); + + std::stringstream ss(response); + std::string str_val; + int int_val; + char char_val[256]; + + ss >> str_val; + set_version(str_val); + + ss >> int_val; + ss.getline(char_val,256); + set_status(status_code::value(int_val),std::string(char_val)); + } else { + return false; + } + + return parse_headers(s); } inline std::string response::raw() const { - // TODO: validation. Make sure all required fields have been set? - - std::stringstream raw; - - raw << get_version() << " " << m_status_code << " " << m_status_msg; - raw << "\r\n" << raw_headers() << "\r\n"; - - raw << m_body; - - return raw.str(); + // TODO: validation. Make sure all required fields have been set? + + std::stringstream raw; + + raw << get_version() << " " << m_status_code << " " << m_status_msg; + raw << "\r\n" << raw_headers() << "\r\n"; + + raw << m_body; + + return raw.str(); } inline void response::set_status(status_code::value code) { - // TODO: validation? - m_status_code = code; - m_status_msg = get_string(code); + // TODO: validation? + m_status_code = code; + m_status_msg = get_string(code); } inline void response::set_status(status_code::value code, const std::string& msg) { - // TODO: validation? - m_status_code = code; - m_status_msg = msg; + // TODO: validation? + m_status_code = code; + m_status_msg = msg; } inline void response::process(std::string::iterator begin, std::string::iterator end) { - std::string::iterator cursor_start = begin; - std::string::iterator cursor_end = std::find(begin,end,' '); - - if (cursor_end == end) { - throw exception("Invalid response line",status_code::bad_request); - } - - set_version(std::string(cursor_start,cursor_end)); - - cursor_start = cursor_end+1; - cursor_end = std::find(cursor_start,end,' '); - - if (cursor_end == end) { - throw exception("Invalid request line",status_code::bad_request); - } - - int code; - - std::istringstream ss(std::string(cursor_start,cursor_end)); - - if ((ss >> code).fail()) { - throw exception("Unable to parse response code",status_code::bad_request); - } - - set_status(status_code::value(code),std::string(cursor_end+1,end)); + std::string::iterator cursor_start = begin; + std::string::iterator cursor_end = std::find(begin,end,' '); + + if (cursor_end == end) { + throw exception("Invalid response line",status_code::bad_request); + } + + set_version(std::string(cursor_start,cursor_end)); + + cursor_start = cursor_end+1; + cursor_end = std::find(cursor_start,end,' '); + + if (cursor_end == end) { + throw exception("Invalid request line",status_code::bad_request); + } + + int code; + + std::istringstream ss(std::string(cursor_start,cursor_end)); + + if ((ss >> code).fail()) { + throw exception("Unable to parse response code",status_code::bad_request); + } + + set_status(status_code::value(code),std::string(cursor_end+1,end)); } inline size_t response::process_body(const char *buf, size_t len) { - // If no content length was set then we read forever and never set m_ready - if (m_read == 0) { - //m_body.append(buf,len); - //return len; - m_state = DONE; - return 0; - } - - // Otherwise m_read is the number of bytes left. - size_t to_read; - - if (len >= m_read) { - // if we have more bytes than we need read, read only the amount needed - // then set done state - to_read = m_read; - m_state = DONE; - } else { - // we need more bytes than are avaliable, read them all - to_read = len; - } - - m_body.append(buf,to_read); - m_read -= to_read; - return to_read; + // If no content length was set then we read forever and never set m_ready + if (m_read == 0) { + //m_body.append(buf,len); + //return len; + m_state = DONE; + return 0; + } + + // Otherwise m_read is the number of bytes left. + size_t to_read; + + if (len >= m_read) { + // if we have more bytes than we need read, read only the amount needed + // then set done state + to_read = m_read; + m_state = DONE; + } else { + // we need more bytes than are avaliable, read them all + to_read = len; + } + + m_body.append(buf,to_read); + m_read -= to_read; + return to_read; } } // namespace parser diff --git a/websocketpp/http/parser.hpp b/websocketpp/http/parser.hpp index 0f2ae321d9..845bbb218b 100644 --- a/websocketpp/http/parser.hpp +++ b/websocketpp/http/parser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -39,12 +39,12 @@ namespace http { namespace parser { namespace state { - enum value { - method, - resource, - version, - headers - }; + enum value { + method, + resource, + version, + headers + }; } typedef std::map header_list; @@ -142,7 +142,7 @@ struct attribute { typedef std::vector attribute_list; struct parameter { - parameter(std::string n) : name(n) {} + parameter(std::string n) : name(n) {} void add_attribute(const attribute& p) { attributes.push_back(p); @@ -353,7 +353,7 @@ public: /// Get the HTTP version string const std::string& get_version() const { - return m_version; + return m_version; } /// Get the HTTP header with name `key` @@ -365,7 +365,7 @@ public: /// Get the body string const std::string& get_body() const { - return m_body; + return m_body; } /// Get the HTTP header with name `key` @@ -417,7 +417,7 @@ public: */ void set_body(const std::string& value); protected: - /// DEPRECATED Read headers out of an istream + /// DEPRECATED Read headers out of an istream bool parse_headers(std::istream& s); /// Helper function for consume. Process header line diff --git a/websocketpp/http/request.hpp b/websocketpp/http/request.hpp index 47c05034cb..b3e0953f89 100644 --- a/websocketpp/http/request.hpp +++ b/websocketpp/http/request.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -84,7 +84,7 @@ public: /// Returns whether or not the request is ready for reading. bool ready() const { - return m_ready; + return m_ready; } /// Returns the full raw request @@ -95,7 +95,7 @@ public: /// Return the request method const std::string& get_method() const { - return m_method; + return m_method; } /// Set the HTTP uri. Must be a valid HTTP uri @@ -103,17 +103,17 @@ public: /// Return the requested URI const std::string& get_uri() const { - return m_uri; + return m_uri; } private: - /// Helper function for message::consume. Process request line - void process(std::string::iterator begin, std::string::iterator end); - - lib::shared_ptr m_buf; - std::string m_method; - std::string m_uri; - bool m_ready; + /// Helper function for message::consume. Process request line + void process(std::string::iterator begin, std::string::iterator end); + + lib::shared_ptr m_buf; + std::string m_method; + std::string m_uri; + bool m_ready; }; } // namespace parser diff --git a/websocketpp/http/response.hpp b/websocketpp/http/response.hpp index eea7f7d639..0cab36d867 100644 --- a/websocketpp/http/response.hpp +++ b/websocketpp/http/response.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -53,16 +53,16 @@ namespace parser { */ class response : public parser { public: - typedef response type; + typedef response type; typedef lib::shared_ptr ptr; - - response() + + response() : m_read(0) , m_buf(new std::string()) , m_status_code(status_code::uninitialized) , m_state(RESPONSE_LINE) {} - - /// Process bytes in the input buffer + + /// Process bytes in the input buffer /** * Process up to len bytes from input buffer buf. Returns the number of * bytes processed. Bytes left unprocessed means bytes left over after the @@ -91,12 +91,12 @@ public: * @note will never return true if the content length header is not present */ bool ready() const { - return m_state == DONE; + return m_state == DONE; } /// Returns true if the response headers are fully parsed. bool headers_ready() const { - return (m_state == BODY || m_state == DONE); + return (m_state == BODY || m_state == DONE); } /// DEPRECATED parse a complete response from a pre-delimited istream @@ -130,32 +130,32 @@ public: /// Return the response status code status_code::value get_status_code() const { - return m_status_code; + return m_status_code; } /// Return the response status message const std::string& get_status_msg() const { - return m_status_msg; + return m_status_msg; } private: - /// Helper function for consume. Process response line - void process(std::string::iterator begin, std::string::iterator end); - - /// Helper function for processing body bytes - size_t process_body(const char *buf, size_t len); - - enum state { - RESPONSE_LINE = 0, - HEADERS = 1, - BODY = 2, - DONE = 3 - }; - - std::string m_status_msg; - size_t m_read; - lib::shared_ptr m_buf; - status_code::value m_status_code; - state m_state; + /// Helper function for consume. Process response line + void process(std::string::iterator begin, std::string::iterator end); + + /// Helper function for processing body bytes + size_t process_body(const char *buf, size_t len); + + enum state { + RESPONSE_LINE = 0, + HEADERS = 1, + BODY = 2, + DONE = 3 + }; + + std::string m_status_msg; + size_t m_read; + lib::shared_ptr m_buf; + status_code::value m_status_code; + state m_state; }; diff --git a/websocketpp/impl/connection_impl.hpp b/websocketpp/impl/connection_impl.hpp index 2076aec1c1..b4df39b064 100644 --- a/websocketpp/impl/connection_impl.hpp +++ b/websocketpp/impl/connection_impl.hpp @@ -75,28 +75,28 @@ template lib::error_code connection::send(const std::string& payload, frame::opcode::value op) { - message_ptr msg = m_msg_manager->get_message(op,payload.size()); - msg->append_payload(payload); - - return send(msg); + message_ptr msg = m_msg_manager->get_message(op,payload.size()); + msg->append_payload(payload); + + return send(msg); } template lib::error_code connection::send(const void* payload, size_t len, frame::opcode::value op) { - message_ptr msg = m_msg_manager->get_message(op,len); - msg->append_payload(payload,len); - - return send(msg); + message_ptr msg = m_msg_manager->get_message(op,len); + msg->append_payload(payload,len); + + return send(msg); } template lib::error_code connection::send(typename config::message_type::ptr msg) { m_alog.write(log::alevel::devel,"connection send"); - // TODO: - + // TODO: + if (m_state != session::state::open) { return error::make_error_code(error::invalid_state); } @@ -111,29 +111,29 @@ lib::error_code connection::send(typename config::message_type::ptr msg) write_push(outgoing_msg); needs_writing = !m_write_flag && !m_send_queue.empty(); } else { - outgoing_msg = m_msg_manager->get_message(); - - if (!outgoing_msg) { - return error::make_error_code(error::no_outgoing_buffers); - } - - scoped_lock_type lock(m_write_lock); - lib::error_code ec = m_processor->prepare_data_frame(msg,outgoing_msg); - - if (ec) { - return ec; - } - + outgoing_msg = m_msg_manager->get_message(); + + if (!outgoing_msg) { + return error::make_error_code(error::no_outgoing_buffers); + } + + scoped_lock_type lock(m_write_lock); + lib::error_code ec = m_processor->prepare_data_frame(msg,outgoing_msg); + + if (ec) { + return ec; + } + write_push(outgoing_msg); needs_writing = !m_write_flag && !m_send_queue.empty(); } - if (needs_writing) { - transport_con_type::dispatch(lib::bind( - &type::write_frame, - type::shared_from_this() - )); - } + if (needs_writing) { + transport_con_type::dispatch(lib::bind( + &type::write_frame, + type::shared_from_this() + )); + } return lib::error_code(); } @@ -164,10 +164,10 @@ void connection::ping(const std::string& payload) { } if (needs_writing) { - transport_con_type::dispatch(lib::bind( - &type::write_frame, - type::shared_from_this() - )); + transport_con_type::dispatch(lib::bind( + &type::write_frame, + type::shared_from_this() + )); } } @@ -199,10 +199,10 @@ void connection::pong(const std::string& payload, lib::error_code& ec) { } if (needs_writing) { - transport_con_type::dispatch(lib::bind( - &type::write_frame, - type::shared_from_this() - )); + transport_con_type::dispatch(lib::bind( + &type::write_frame, + type::shared_from_this() + )); } ec = lib::error_code(); @@ -549,7 +549,7 @@ void connection::handle_transport_init(const lib::error_code& ec) { if (ec) { std::stringstream s; - s << "handle_transport_init recieved error: "<< ec.message(); + s << "handle_transport_init recieved error: "<< ec.message(); m_elog.write(log::elevel::fatal,s.str()); this->terminate(); @@ -595,7 +595,7 @@ void connection::read(size_t num_bytes) { // a new read request with this function as the handler. template void connection::handle_handshake_read(const lib::error_code& ec, - size_t bytes_transferred) + size_t bytes_transferred) { m_alog.write(log::alevel::devel,"connection handle_handshake_read"); @@ -606,7 +606,7 @@ void connection::handle_handshake_read(const lib::error_code& ec, if (ec) { std::stringstream s; - s << "error in handle_read_handshake: "<< ec.message(); + s << "error in handle_read_handshake: "<< ec.message(); m_elog.write(log::elevel::fatal,s.str()); this->terminate(); return; @@ -727,7 +727,7 @@ void connection::send_http_response_error() { // a new read request with this function as the handler. template void connection::handle_read_frame(const lib::error_code& ec, - size_t bytes_transferred) + size_t bytes_transferred) { //m_alog.write(log::alevel::devel,"connection handle_read_frame"); @@ -746,7 +746,7 @@ void connection::handle_read_frame(const lib::error_code& ec, } std::stringstream s; - s << "error in handle_read_frame: " << ec.message() << " (" << ec << ")"; + s << "error in handle_read_frame: " << ec.message() << " (" << ec << ")"; m_elog.write(log::elevel::fatal,s.str()); this->terminate(); return; @@ -762,32 +762,32 @@ void connection::handle_read_frame(const lib::error_code& ec, size_t p = 0; if (m_alog.static_test(log::alevel::devel)) { - std::stringstream s; - s << "p = " << p << " bytes transferred = " << bytes_transferred; - m_alog.write(log::alevel::devel,s.str()); + std::stringstream s; + s << "p = " << p << " bytes transferred = " << bytes_transferred; + m_alog.write(log::alevel::devel,s.str()); } while (p < bytes_transferred) { if (m_alog.static_test(log::alevel::devel)) { - std::stringstream s; - s << "calling consume with " << bytes_transferred-p << " bytes"; - m_alog.write(log::alevel::devel,s.str()); + std::stringstream s; + s << "calling consume with " << bytes_transferred-p << " bytes"; + m_alog.write(log::alevel::devel,s.str()); } lib::error_code ec; - p += m_processor->consume( - reinterpret_cast(m_buf)+p, - bytes_transferred-p, + p += m_processor->consume( + reinterpret_cast(m_buf)+p, + bytes_transferred-p, ec - ); - - if (m_alog.static_test(log::alevel::devel)) { - std::stringstream s; - s << "bytes left after consume: " << bytes_transferred-p; - m_alog.write(log::alevel::devel,s.str()); - } - if (ec) { + ); + + if (m_alog.static_test(log::alevel::devel)) { + std::stringstream s; + s << "bytes left after consume: " << bytes_transferred-p; + m_alog.write(log::alevel::devel,s.str()); + } + if (ec) { m_elog.write(log::elevel::rerror,"consume error: "+ec.message()); if (config::drop_on_protocol_error) { @@ -806,11 +806,11 @@ void connection::handle_read_frame(const lib::error_code& ec, } } return; - } + } - if (m_processor->ready()) { + if (m_processor->ready()) { //m_alog.write(log::alevel::devel,"consume ended in ready"); - + message_ptr msg = m_processor->get_message(); if (!msg) { @@ -824,7 +824,7 @@ void connection::handle_read_frame(const lib::error_code& ec, } else { process_control_frame(msg); } - } + } } transport_con_type::async_read_at_least( @@ -934,8 +934,8 @@ bool connection::process_handshake_request() { // we don't send an empty extensions header because it breaks many // clients. if (neg_results.second.size() > 0) { - m_response.replace_header("Sec-WebSocket-Extensions", - neg_results.second); + m_response.replace_header("Sec-WebSocket-Extensions", + neg_results.second); } } @@ -993,7 +993,7 @@ bool connection::process_handshake_request() { // TODO: does this function still need to be here? template void connection::handle_read(const lib::error_code& ec, - size_t bytes_transferred) + size_t bytes_transferred) { if (ec) { m_elog.write(log::elevel::rerror,"error in handle_read"+ec.message()); @@ -1382,8 +1382,8 @@ void connection::write_frame() { m_send_buffer.push_back(transport::buffer(header.c_str(),header.size())); m_send_buffer.push_back(transport::buffer(payload.c_str(),payload.size())); - - + + if (m_alog.static_test(log::alevel::frame_header)) { if (m_alog.dynamic_test(log::alevel::frame_header)) { std::stringstream s; @@ -1415,10 +1415,10 @@ template void connection::handle_write_frame(bool terminate, const lib::error_code& ec) { - m_send_buffer.clear(); - m_current_msg.reset(); - - if (ec) { + m_send_buffer.clear(); + m_current_msg.reset(); + + if (ec) { m_elog.write(log::elevel::fatal,"error in handle_write_frame: "+ec.message()); this->terminate(); return; @@ -1442,10 +1442,10 @@ void connection::handle_write_frame(bool terminate, } if (needs_writing) { - transport_con_type::dispatch(lib::bind( - &type::write_frame, - type::shared_from_this() - )); + transport_con_type::dispatch(lib::bind( + &type::write_frame, + type::shared_from_this() + )); } } @@ -1672,10 +1672,10 @@ lib::error_code connection::send_close_frame(close::status::value code, } if (needs_writing) { - transport_con_type::dispatch(lib::bind( - &type::write_frame, - type::shared_from_this() - )); + transport_con_type::dispatch(lib::bind( + &type::write_frame, + type::shared_from_this() + )); } return lib::error_code(); diff --git a/websocketpp/impl/endpoint_impl.hpp b/websocketpp/impl/endpoint_impl.hpp index 29223e7908..55a521713e 100644 --- a/websocketpp/impl/endpoint_impl.hpp +++ b/websocketpp/impl/endpoint_impl.hpp @@ -35,11 +35,11 @@ typename endpoint::connection_ptr endpoint::create_connection() { m_alog.write(log::alevel::devel,"create_connection"); //scoped_lock_type lock(m_state_lock); - - /*if (m_state == STOPPING || m_state == STOPPED) { - return connection_ptr(); - }*/ - + + /*if (m_state == STOPPING || m_state == STOPPED) { + return connection_ptr(); + }*/ + // Create a connection on the heap and manage it using a shared pointer connection_ptr con(new connection_type(m_is_server,m_user_agent,m_alog, m_elog, m_rng)); @@ -54,7 +54,7 @@ endpoint::create_connection() { // con->set_handle(w); - + // Copy default handlers from the endpoint con->set_open_handler(m_open_handler); con->set_close_handler(m_close_handler); @@ -66,27 +66,27 @@ endpoint::create_connection() { con->set_http_handler(m_http_handler); con->set_validate_handler(m_validate_handler); con->set_message_handler(m_message_handler); - + con->set_termination_handler( - lib::bind( - &type::remove_connection, - this, - lib::placeholders::_1 - ) - ); - - lib::error_code ec; - - ec = transport_type::init(con); + lib::bind( + &type::remove_connection, + this, + lib::placeholders::_1 + ) + ); + + lib::error_code ec; + + ec = transport_type::init(con); if (ec) { m_elog.write(log::elevel::fatal,ec.message()); return connection_ptr(); } scoped_lock_type lock(m_mutex); - m_connections.insert(con); - - return con; + m_connections.insert(con); + + return con; } template @@ -182,16 +182,16 @@ void endpoint::close(connection_hdl hdl, template void endpoint::remove_connection(connection_ptr con) { - std::stringstream s; - s << "remove_connection. New count: " << m_connections.size()-1; - m_alog.write(log::alevel::devel,s.str()); - + std::stringstream s; + s << "remove_connection. New count: " << m_connections.size()-1; + m_alog.write(log::alevel::devel,s.str()); + scoped_lock_type lock(m_mutex); - - // unregister the termination handler - con->set_termination_handler(termination_handler()); - - m_connections.erase(con); + + // unregister the termination handler + con->set_termination_handler(termination_handler()); + + m_connections.erase(con); } } // namespace websocketpp diff --git a/websocketpp/impl/utilities_impl.hpp b/websocketpp/impl/utilities_impl.hpp index b3ff1a0858..72f4a1b015 100644 --- a/websocketpp/impl/utilities_impl.hpp +++ b/websocketpp/impl/utilities_impl.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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/logger/basic.hpp b/websocketpp/logger/basic.hpp index adf329d874..893cf323ea 100644 --- a/websocketpp/logger/basic.hpp +++ b/websocketpp/logger/basic.hpp @@ -68,8 +68,8 @@ public: void set_channels(level channels) { if (channels == names::none) { - clear_channels(names::all); - return; + clear_channels(names::all); + return; } scoped_lock_type lock(m_lock); @@ -104,20 +104,20 @@ public: } bool dynamic_test(level channel) { - return ((channel & m_dynamic_channels) != 0); - } + return ((channel & m_dynamic_channels) != 0); + } private: typedef typename concurrency::scoped_lock_type scoped_lock_type; - typedef typename concurrency::mutex_type mutex_type; - + typedef typename concurrency::mutex_type mutex_type; + const char* get_timestamp() { std::time_t t = std::time(NULL); std::strftime(buffer,39,"%Y-%m-%d %H:%M:%S%z",std::localtime(&t)); return buffer; } - mutex_type m_lock; - + mutex_type m_lock; + char buffer[40]; const level m_static_channels; level m_dynamic_channels; diff --git a/websocketpp/logger/levels.hpp b/websocketpp/logger/levels.hpp index ecbfc2d58d..02b342a121 100644 --- a/websocketpp/logger/levels.hpp +++ b/websocketpp/logger/levels.hpp @@ -46,23 +46,23 @@ struct elevel { static const level all = 0xffffffff; static const char* channel_name(level channel) { - switch(channel) { - case devel: - return "devel"; - case library: - return "library"; - case info: - return "info"; - case warn: - return "warning"; - case rerror: - return "error"; - case fatal: - return "fatal"; - default: - return "unknown"; - } - } + switch(channel) { + case devel: + return "devel"; + case library: + return "library"; + case info: + return "info"; + case warn: + return "warning"; + case rerror: + return "error"; + case fatal: + return "fatal"; + default: + return "unknown"; + } + } }; struct alevel { @@ -82,35 +82,35 @@ struct alevel { static const level all = 0xffffffff; static const char* channel_name(level channel) { - switch(channel) { - case connect: - return "connect"; - case disconnect: - return "disconnect"; - case control: - return "control"; - case frame_header: - return "frame_header"; - case frame_payload: - return "frame_payload"; - case message_header: - return "message_header"; - case message_payload: - return "message_payload"; - case endpoint: - return "endpoint"; - case debug_handshake: - return "debug_handshake"; - case debug_close: - return "debug_close"; - case devel: - return "devel"; - case app: - return "application"; - default: - return "unknown"; - } - } + switch(channel) { + case connect: + return "connect"; + case disconnect: + return "disconnect"; + case control: + return "control"; + case frame_header: + return "frame_header"; + case frame_payload: + return "frame_payload"; + case message_header: + return "message_header"; + case message_payload: + return "message_payload"; + case endpoint: + return "endpoint"; + case debug_handshake: + return "debug_handshake"; + case debug_close: + return "debug_close"; + case devel: + return "devel"; + case app: + return "application"; + default: + return "unknown"; + } + } }; } // logger diff --git a/websocketpp/message_buffer/alloc.hpp b/websocketpp/message_buffer/alloc.hpp index ec528ebcf7..1b38baa4f3 100644 --- a/websocketpp/message_buffer/alloc.hpp +++ b/websocketpp/message_buffer/alloc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -42,12 +42,12 @@ class con_msg_manager : public lib::enable_shared_from_this > { public: - typedef con_msg_manager type; - typedef lib::shared_ptr ptr; - typedef lib::weak_ptr weak_ptr; + typedef con_msg_manager type; + typedef lib::shared_ptr ptr; + typedef lib::weak_ptr weak_ptr; - typedef typename message::ptr message_ptr; - + typedef typename message::ptr message_ptr; + /// Get an empty message buffer /** * @return A shared pointer to an empty new message @@ -56,30 +56,30 @@ public: return message_ptr(new message(type::shared_from_this())); } - /// Get a message buffer with specified size and opcode - /** + /// Get a message buffer with specified size and opcode + /** * @param op The opcode to use - * @param size Minimum size in bytes to request for the message payload. - * - * @return A shared pointer to a new message with specified size. - */ - message_ptr get_message(frame::opcode::value op,size_t size) { - return message_ptr(new message(type::shared_from_this(),op,size)); - } + * @param size Minimum size in bytes to request for the message payload. + * + * @return A shared pointer to a new message with specified size. + */ + message_ptr get_message(frame::opcode::value op,size_t size) { + return message_ptr(new message(type::shared_from_this(),op,size)); + } - /// Recycle a message - /** - * This method shouldn't be called. If it is, return false to indicate an - * error. The rest of the method recycle chain should notice this and free - * the memory. - * - * @param msg The message to be recycled. - * - * @return true if the message was successfully recycled, false otherwse. - */ - bool recycle(message * msg) { - return false; - } + /// Recycle a message + /** + * This method shouldn't be called. If it is, return false to indicate an + * error. The rest of the method recycle chain should notice this and free + * the memory. + * + * @param msg The message to be recycled. + * + * @return true if the message was successfully recycled, false otherwse. + */ + bool recycle(message * msg) { + return false; + } }; /// An endpoint message manager that allocates a new manager for each @@ -87,15 +87,15 @@ public: template class endpoint_msg_manager { public: - typedef typename con_msg_manager::ptr con_msg_man_ptr; - - /// Get a pointer to a connection message manager - /** - * @return A pointer to the requested connection message manager. - */ - con_msg_man_ptr get_manager() const { - return con_msg_man_ptr(new con_msg_manager()); - } + typedef typename con_msg_manager::ptr con_msg_man_ptr; + + /// Get a pointer to a connection message manager + /** + * @return A pointer to the requested connection message manager. + */ + con_msg_man_ptr get_manager() const { + return con_msg_man_ptr(new con_msg_manager()); + } }; } // namespace alloc diff --git a/websocketpp/message_buffer/message.hpp b/websocketpp/message_buffer/message.hpp index d00a96298f..6fc9ee82ee 100644 --- a/websocketpp/message_buffer/message.hpp +++ b/websocketpp/message_buffer/message.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -83,11 +83,11 @@ namespace message_buffer { template class con_msg_manager> class message { public: - typedef lib::shared_ptr ptr; - - typedef con_msg_manager con_msg_man_type; - typedef typename con_msg_man_type::ptr con_msg_man_ptr; - typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr; + typedef lib::shared_ptr ptr; + + typedef con_msg_manager con_msg_man_type; + typedef typename con_msg_man_type::ptr con_msg_man_ptr; + typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr; /// Construct an empty message /** @@ -104,17 +104,17 @@ public: /** * */ - message(const con_msg_man_ptr manager, frame::opcode::value op, size_t size = 128) - : m_manager(manager) - , m_opcode(op) - , m_prepared(false) + message(const con_msg_man_ptr manager, frame::opcode::value op, size_t size = 128) + : m_manager(manager) + , m_opcode(op) + , m_prepared(false) , m_fin(true) , m_terminal(false) , m_compressed(false) - { - m_payload.reserve(size); - } - + { + m_payload.reserve(size); + } + /// Return whether or not the message has been prepared for sending /** * The prepared flag indicates that the message has been prepared by a @@ -122,17 +122,17 @@ public: * * @return whether or not the message has been prepared for sending */ - bool get_prepared() const { - return m_prepared; - } - + bool get_prepared() const { + return m_prepared; + } + /// Set or clear the flag that indicates that the message has been prepared /** * @param value The value to set the prepared flag to */ - void set_prepared(bool value) { - m_prepared = value; - } + void set_prepared(bool value) { + m_prepared = value; + } /// Return whether or not the message is flagged as compressed /** @@ -141,17 +141,17 @@ public: * * @return whether or not the message is/should be compressed */ - bool get_compressed() const { - return m_compressed; - } - + bool get_compressed() const { + return m_compressed; + } + /// Set or clear the compression flag /** * @param value The value to set the compressed flag to */ - void set_compressed(bool value) { - m_compressed = value; - } + void set_compressed(bool value) { + m_compressed = value; + } /// Get whether or not the message is terminal /** @@ -197,9 +197,9 @@ public: } /// Return the message opcode - frame::opcode::value get_opcode() const { - return m_opcode; - } + frame::opcode::value get_opcode() const { + return m_opcode; + } /// Set the opcode void set_opcode(frame::opcode::value op) { @@ -211,9 +211,9 @@ public: * This value is typically set by a websocket protocol processor * and shouldn't be tampered with. */ - const std::string& get_header() const { - return m_header; - } + const std::string& get_header() const { + return m_header; + } /// Set prepared frame header /** @@ -221,78 +221,78 @@ public: * * @param header A string to set the header to. */ - void set_header(const std::string& header) { - m_header = header; - } - + void set_header(const std::string& header) { + m_header = header; + } + const std::string& get_extension_data() const { - return m_extension_data; - } - + return m_extension_data; + } + /// Get a reference to the payload string /** * @return A const reference to the message's payload string */ const std::string& get_payload() const { - return m_payload; - } - + return m_payload; + } + /// Get a non-const reference to the payload string /** * @return A reference to the message's payload string */ - std::string& get_raw_payload() { - return m_payload; - } + std::string& get_raw_payload() { + return m_payload; + } - void set_payload(const std::string& payload) { - m_payload = payload; - } - - void set_payload(const void *payload, size_t len) { - m_payload.reserve(len); - const char* pl = static_cast(payload); - m_payload.assign(pl, pl + len); - } - - void append_payload(const std::string& payload) { - m_payload.append(payload); - } - - void append_payload(const void *payload, size_t len) { - m_payload.reserve(m_payload.size()+len); - m_payload.append(static_cast(payload),len); - } + void set_payload(const std::string& payload) { + m_payload = payload; + } + + void set_payload(const void *payload, size_t len) { + m_payload.reserve(len); + const char* pl = static_cast(payload); + m_payload.assign(pl, pl + len); + } + + void append_payload(const std::string& payload) { + m_payload.append(payload); + } + + void append_payload(const void *payload, size_t len) { + m_payload.reserve(m_payload.size()+len); + m_payload.append(static_cast(payload),len); + } - /// Recycle the message - /** - * A request to recycle this message was received. Forward that request to - * the connection message manager for processing. Errors and exceptions - * from the manager's recycle member function should be passed back up the - * call chain. The caller to message::recycle will deal with them. - * - * Recycle must *only* be called by the message shared_ptr's destructor. - * Once recycled successfully, ownership of the memory has been passed to - * another system and must not be accessed again. - * - * @return true if the message was successfully recycled, false otherwise. - */ - bool recycle() { - con_msg_man_ptr shared = m_manager.lock(); + /// Recycle the message + /** + * A request to recycle this message was received. Forward that request to + * the connection message manager for processing. Errors and exceptions + * from the manager's recycle member function should be passed back up the + * call chain. The caller to message::recycle will deal with them. + * + * Recycle must *only* be called by the message shared_ptr's destructor. + * Once recycled successfully, ownership of the memory has been passed to + * another system and must not be accessed again. + * + * @return true if the message was successfully recycled, false otherwise. + */ + bool recycle() { + con_msg_man_ptr shared = m_manager.lock(); - if (shared) { - return shared->recycle(this); - } else { - return false; - } - } + if (shared) { + return shared->recycle(this); + } else { + return false; + } + } private: - con_msg_man_weak_ptr m_manager; - std::string m_header; - std::string m_extension_data; - std::string m_payload; - frame::opcode::value m_opcode; - bool m_prepared; + con_msg_man_weak_ptr m_manager; + std::string m_header; + std::string m_extension_data; + std::string m_payload; + frame::opcode::value m_opcode; + bool m_prepared; bool m_fin; bool m_terminal; bool m_compressed; diff --git a/websocketpp/message_buffer/pool.hpp b/websocketpp/message_buffer/pool.hpp index 2aea183997..0163682e46 100644 --- a/websocketpp/message_buffer/pool.hpp +++ b/websocketpp/message_buffer/pool.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -82,14 +82,14 @@ namespace message_buffer { */ template void message_deleter(T* msg) { - try { - if (!msg->recycle()) { - delete msg; - } - } catch (...) { - // TODO: is there a better way to ensure this function doesn't throw? - delete msg; - } + try { + if (!msg->recycle()) { + delete msg; + } + } catch (...) { + // TODO: is there a better way to ensure this function doesn't throw? + delete msg; + } } /// Represents a buffer for a single WebSocket message. @@ -100,56 +100,56 @@ void message_deleter(T* msg) { template class message { public: - typedef lib::shared_ptr ptr; - - typedef typename con_msg_manager::weak_ptr con_msg_man_ptr; + typedef lib::shared_ptr ptr; + + typedef typename con_msg_manager::weak_ptr con_msg_man_ptr; - message(con_msg_man_ptr manager, size_t size = 128) - : m_manager(manager) - , m_payload(size) {} + message(con_msg_man_ptr manager, size_t size = 128) + : m_manager(manager) + , m_payload(size) {} - frame::opcode::value get_opcode() const { - return m_opcode; - } - const std::string& get_header() const { - return m_header; - } - const std::string& get_extension_data() const { - return m_extension_data; - } - const std::string& get_payload() const { - return m_payload; - } - - /// Recycle the message - /** - * A request to recycle this message was received. Forward that request to - * the connection message manager for processing. Errors and exceptions - * from the manager's recycle member function should be passed back up the - * call chain. The caller to message::recycle will deal with them. - * - * Recycle must *only* be called by the message shared_ptr's destructor. - * Once recycled successfully, ownership of the memory has been passed to - * another system and must not be accessed again. - * - * @return true if the message was successfully recycled, false otherwise. - */ - bool recycle() { - typename con_msg_manager::ptr shared = m_manager.lock(); + frame::opcode::value get_opcode() const { + return m_opcode; + } + const std::string& get_header() const { + return m_header; + } + const std::string& get_extension_data() const { + return m_extension_data; + } + const std::string& get_payload() const { + return m_payload; + } + + /// Recycle the message + /** + * A request to recycle this message was received. Forward that request to + * the connection message manager for processing. Errors and exceptions + * from the manager's recycle member function should be passed back up the + * call chain. The caller to message::recycle will deal with them. + * + * Recycle must *only* be called by the message shared_ptr's destructor. + * Once recycled successfully, ownership of the memory has been passed to + * another system and must not be accessed again. + * + * @return true if the message was successfully recycled, false otherwise. + */ + bool recycle() { + typename con_msg_manager::ptr shared = m_manager.lock(); - if (shared) { - return shared->(recycle(this)); - } else { - return false; - } - } + if (shared) { + return shared->(recycle(this)); + } else { + return false; + } + } private: - con_msg_man_ptr m_manager; - - frame::opcode::value m_opcode; - std::string m_header; - std::string m_extension_data; - std::string m_payload; + con_msg_man_ptr m_manager; + + frame::opcode::value m_opcode; + std::string m_header; + std::string m_extension_data; + std::string m_payload; }; namespace alloc { @@ -159,34 +159,34 @@ namespace alloc { template class con_msg_manager { public: - typedef lib::shared_ptr ptr; - typedef lib::weak_ptr weak_ptr; + typedef lib::shared_ptr ptr; + typedef lib::weak_ptr weak_ptr; - typedef typename message::ptr message_ptr; - - /// Get a message buffer with specified size - /** - * @param size Minimum size in bytes to request for the message payload. - * - * @return A shared pointer to a new message with specified size. - */ - message_ptr get_message(size_t size) const { - return message_ptr(new message(size)); - } - - /// Recycle a message - /** - * This method shouldn't be called. If it is, return false to indicate an - * error. The rest of the method recycle chain should notice this and free - * the memory. - * - * @param msg The message to be recycled. - * - * @return true if the message was successfully recycled, false otherwse. - */ - bool recycle(message * msg) { - return false; - } + typedef typename message::ptr message_ptr; + + /// Get a message buffer with specified size + /** + * @param size Minimum size in bytes to request for the message payload. + * + * @return A shared pointer to a new message with specified size. + */ + message_ptr get_message(size_t size) const { + return message_ptr(new message(size)); + } + + /// Recycle a message + /** + * This method shouldn't be called. If it is, return false to indicate an + * error. The rest of the method recycle chain should notice this and free + * the memory. + * + * @param msg The message to be recycled. + * + * @return true if the message was successfully recycled, false otherwse. + */ + bool recycle(message * msg) { + return false; + } }; /// An endpoint message manager that allocates a new manager for each @@ -194,15 +194,15 @@ public: template class endpoint_msg_manager { public: - typedef typename con_msg_manager::ptr con_msg_man_ptr; - - /// Get a pointer to a connection message manager - /** - * @return A pointer to the requested connection message manager. - */ - con_msg_man_ptr get_manager() const { - return con_msg_man_ptr(new con_msg_manager()); - } + typedef typename con_msg_manager::ptr con_msg_man_ptr; + + /// Get a pointer to a connection message manager + /** + * @return A pointer to the requested connection message manager. + */ + con_msg_man_ptr get_manager() const { + return con_msg_man_ptr(new con_msg_manager()); + } }; } // namespace alloc @@ -214,7 +214,7 @@ namespace pool { class con_msg_manager { }; - + /// An endpoint manager that maintains a shared pool of connection managers /// and returns an appropriate one for the requesting connection. class endpoint_msg_manager { diff --git a/websocketpp/processors/base.hpp b/websocketpp/processors/base.hpp index 61cdffcd9c..61f329d70c 100644 --- a/websocketpp/processors/base.hpp +++ b/websocketpp/processors/base.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -54,11 +54,11 @@ static const char handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // Processor class related error codes namespace error_cat { enum value { - BAD_REQUEST = 0, // Error was the result of improperly formatted user input - INTERNAL_ERROR = 1, // Error was a logic error internal to WebSocket++ - PROTOCOL_VIOLATION = 2, - MESSAGE_TOO_BIG = 3, - PAYLOAD_VIOLATION = 4 // Error was due to receiving invalid payload data + BAD_REQUEST = 0, // Error was the result of improperly formatted user input + INTERNAL_ERROR = 1, // Error was a logic error internal to WebSocket++ + PROTOCOL_VIOLATION = 2, + MESSAGE_TOO_BIG = 3, + PAYLOAD_VIOLATION = 4 // Error was due to receiving invalid payload data }; } // namespace error_cat @@ -166,44 +166,44 @@ enum processor_errors { class processor_category : public lib::error_category { public: - processor_category() {} + processor_category() {} - const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { - return "websocketpp.processor"; - } - - std::string message(int value) const { - switch(value) { - case error::general: - return "Generic processor error"; - case error::bad_request: - return "invalid user input"; - case error::protocol_violation: - return "Generic protocol violation"; - case error::message_too_big: - return "A message was too large"; - case error::invalid_payload: - return "A payload contained invalid data"; - case error::invalid_arguments: - return "invalid function arguments"; - case error::invalid_opcode: - return "invalid opcode"; - case error::control_too_big: - return "Control messages are limited to fewer than 125 characters"; - case error::invalid_rsv_bit: - return "Invalid use of reserved bits"; - case error::fragmented_control: - return "Control messages cannot be fragmented"; - case error::invalid_continuation: - return "Invalid message continuation"; - case error::masking_required: - return "Clients may not send unmasked frames"; - case error::masking_forbidden: - return "Servers may not send masked frames"; - case error::non_minimal_encoding: - return "Payload length was not minimally encoded"; - case error::requires_64bit: - return "64 bit frames are not supported on 32 bit systems"; + const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { + return "websocketpp.processor"; + } + + std::string message(int value) const { + switch(value) { + case error::general: + return "Generic processor error"; + case error::bad_request: + return "invalid user input"; + case error::protocol_violation: + return "Generic protocol violation"; + case error::message_too_big: + return "A message was too large"; + case error::invalid_payload: + return "A payload contained invalid data"; + case error::invalid_arguments: + return "invalid function arguments"; + case error::invalid_opcode: + return "invalid opcode"; + case error::control_too_big: + return "Control messages are limited to fewer than 125 characters"; + case error::invalid_rsv_bit: + return "Invalid use of reserved bits"; + case error::fragmented_control: + return "Control messages cannot be fragmented"; + case error::invalid_continuation: + return "Invalid message continuation"; + case error::masking_required: + return "Clients may not send unmasked frames"; + case error::masking_forbidden: + return "Servers may not send masked frames"; + case error::non_minimal_encoding: + return "Payload length was not minimally encoded"; + case error::requires_64bit: + return "64 bit frames are not supported on 32 bit systems"; case error::invalid_utf8: return "Invalid UTF8 encoding"; case error::not_implimented: @@ -232,19 +232,19 @@ public: return "Error parsing extension header"; case error::extensions_disabled: return "Extensions are disabled"; - default: - return "Unknown"; - } - } + default: + return "Unknown"; + } + } }; inline const lib::error_category& get_processor_category() { - static processor_category instance; - return instance; + static processor_category instance; + return instance; } inline lib::error_code make_error_code(error::processor_errors e) { - return lib::error_code(static_cast(e), get_processor_category()); + return lib::error_code(static_cast(e), get_processor_category()); } /// Converts a processor error_code into a websocket close code diff --git a/websocketpp/processors/hybi00.hpp b/websocketpp/processors/hybi00.hpp index a037d859b1..1b4a6cc34c 100644 --- a/websocketpp/processors/hybi00.hpp +++ b/websocketpp/processors/hybi00.hpp @@ -32,9 +32,9 @@ // For htonl #if defined(WIN32) - #include + #include #else - #include + #include #endif #include @@ -56,13 +56,13 @@ class hybi00 : public processor { public: typedef processor base; - typedef typename config::request_type request_type; - typedef typename config::response_type response_type; - - typedef typename config::message_type message_type; - typedef typename message_type::ptr message_ptr; + typedef typename config::request_type request_type; + typedef typename config::response_type response_type; + + typedef typename config::message_type message_type; + typedef typename message_type::ptr message_ptr; - typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; + typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; explicit hybi00(bool secure, bool server, msg_manager_ptr manager) : processor(secure, server) @@ -206,14 +206,14 @@ public: return ""; } - /// Process new websocket connection bytes - size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) { + /// Process new websocket connection bytes + size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) { // if in state header we are expecting a 0x00 byte, if we don't get one // it is a fatal error size_t p = 0; // bytes processed size_t l = 0; - ec = lib::error_code(); + ec = lib::error_code(); while (p < len) { if (m_state == HEADER) { @@ -262,63 +262,63 @@ public: //ec = make_error_code(error::not_implimented); return p; - } + } - bool ready() const { - return (m_state == READY); - } - - bool get_error() const { - return false; - } + bool ready() const { + return (m_state == READY); + } + + bool get_error() const { + return false; + } - message_ptr get_message() { - message_ptr ret = m_msg_ptr; + message_ptr get_message() { + message_ptr ret = m_msg_ptr; m_msg_ptr = message_ptr(); m_state = HEADER; return ret; - } - - /// Prepare a message for writing - /** - * Performs validation, masking, compression, etc. will return an error if - * there was an error, otherwise msg will be ready to be written - */ - virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) - { - if (!in || !out) { - return make_error_code(error::invalid_arguments); - } - - // TODO: check if the message is prepared already - - // validate opcode + } + + /// Prepare a message for writing + /** + * Performs validation, masking, compression, etc. will return an error if + * there was an error, otherwise msg will be ready to be written + */ + virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) + { + if (!in || !out) { + return make_error_code(error::invalid_arguments); + } + + // TODO: check if the message is prepared already + + // validate opcode if (in->get_opcode() != frame::opcode::text) { return make_error_code(error::invalid_opcode); } std::string& i = in->get_raw_payload(); - //std::string& o = out->get_raw_payload(); + //std::string& o = out->get_raw_payload(); - // validate payload utf8 - if (!utf8_validator::validate(i)) { + // validate payload utf8 + if (!utf8_validator::validate(i)) { return make_error_code(error::invalid_payload); } - // generate header + // generate header out->set_header(std::string(reinterpret_cast(&msg_hdr),1)); // process payload out->set_payload(i); out->append_payload(std::string(reinterpret_cast(&msg_ftr),1)); - // hybi00 doesn't support compression - // hybi00 doesn't have masking - + // hybi00 doesn't support compression + // hybi00 doesn't have masking + out->set_prepared(true); - return lib::error_code(); - } + return lib::error_code(); + } lib::error_code prepare_ping(const std::string & in, message_ptr out) const { @@ -372,11 +372,11 @@ private: } enum state { - HEADER = 0, - PAYLOAD = 1, - READY = 2, - FATAL_ERROR = 3 - }; + HEADER = 0, + PAYLOAD = 1, + READY = 2, + FATAL_ERROR = 3 + }; const uint8_t msg_hdr; const uint8_t msg_ftr; @@ -384,7 +384,7 @@ private: state m_state; msg_manager_ptr m_msg_manager; - message_ptr m_msg_ptr; + message_ptr m_msg_ptr; utf8_validator::validator m_validator; }; diff --git a/websocketpp/processors/hybi07.hpp b/websocketpp/processors/hybi07.hpp index fe8c928f1e..ade9777427 100644 --- a/websocketpp/processors/hybi07.hpp +++ b/websocketpp/processors/hybi07.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -43,10 +43,10 @@ public: typedef typename config::request_type request_type; typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; - typedef typename config::rng_type rng_type; - - explicit hybi07(bool secure,bool server, msg_manager_ptr manager, - rng_type& rng) + typedef typename config::rng_type rng_type; + + explicit hybi07(bool secure,bool server, msg_manager_ptr manager, + rng_type& rng) : hybi08(secure, server, manager, rng) {} // outgoing client connection processing is not supported for this version diff --git a/websocketpp/processors/hybi08.hpp b/websocketpp/processors/hybi08.hpp index 719b9d2700..370b0c68f3 100644 --- a/websocketpp/processors/hybi08.hpp +++ b/websocketpp/processors/hybi08.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -40,10 +40,10 @@ namespace processor { template class hybi08 : public hybi13 { public: - typedef hybi08 type; - typedef typename config::request_type request_type; - - typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; + typedef hybi08 type; + typedef typename config::request_type request_type; + + typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; typedef typename config::rng_type rng_type; explicit hybi08(bool secure, bool server, msg_manager_ptr manager, diff --git a/websocketpp/processors/hybi13.hpp b/websocketpp/processors/hybi13.hpp index af8baa9dee..55e22ac7af 100644 --- a/websocketpp/processors/hybi13.hpp +++ b/websocketpp/processors/hybi13.hpp @@ -30,9 +30,9 @@ // For htonl #if defined(WIN32) - #include + #include #else - #include + #include #endif #include @@ -59,14 +59,14 @@ class hybi13 : public processor { public: typedef processor base; - typedef typename config::request_type request_type; - typedef typename config::response_type response_type; + typedef typename config::request_type request_type; + typedef typename config::response_type response_type; - typedef typename config::message_type message_type; - typedef typename message_type::ptr message_ptr; + typedef typename config::message_type message_type; + typedef typename message_type::ptr message_ptr; - typedef typename config::con_msg_manager_type msg_manager_type; - typedef typename msg_manager_type::ptr msg_manager_ptr; + typedef typename config::con_msg_manager_type msg_manager_type; + typedef typename msg_manager_type::ptr msg_manager_ptr; typedef typename config::rng_type rng_type; typedef typename config::permessage_deflate_type permessage_deflate_type; @@ -76,11 +76,11 @@ public: explicit hybi13(bool secure, bool server, msg_manager_ptr manager, rng_type& rng) : processor(secure,server) - , m_msg_manager(manager) - , m_rng(rng) - { - reset_headers(); - } + , m_msg_manager(manager) + , m_rng(rng) + { + reset_headers(); + } int get_version() const { return 13; @@ -171,7 +171,7 @@ public: */ lib::error_code process_handshake(const request_type& request, const std::string & subprotocol, response_type& response) const - { + { std::string server_key = request.get_header("Sec-WebSocket-Key"); lib::error_code ec = process_handshake_key(server_key); @@ -314,95 +314,95 @@ public: // TODO: check if get_uri is a full uri } - /// Process new websocket connection bytes - /** - * - * Hybi 13 data streams represent a series of variable length frames. Each - * frame is made up of a series of fixed length fields. The lengths of later - * fields are contained in earlier fields. The first field length is fixed - * by the spec. - * - * This processor represents a state machine that keeps track of what field - * is presently being read and how many more bytes are needed to complete it - * - * - * - * - * Read two header bytes - * Extract full frame length. - * Read extra header bytes - * Validate frame header (including extension validate) - * Read extension data into extension message state object - * Read payload data into payload - * - * @param buf Input buffer - * - * @param len Length of input buffer - * - * @return Number of bytes processed or zero on error - */ - size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) { - size_t p = 0; - + /// Process new websocket connection bytes + /** + * + * Hybi 13 data streams represent a series of variable length frames. Each + * frame is made up of a series of fixed length fields. The lengths of later + * fields are contained in earlier fields. The first field length is fixed + * by the spec. + * + * This processor represents a state machine that keeps track of what field + * is presently being read and how many more bytes are needed to complete it + * + * + * + * + * Read two header bytes + * Extract full frame length. + * Read extra header bytes + * Validate frame header (including extension validate) + * Read extension data into extension message state object + * Read payload data into payload + * + * @param buf Input buffer + * + * @param len Length of input buffer + * + * @return Number of bytes processed or zero on error + */ + size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) { + size_t p = 0; + ec = lib::error_code(); - //std::cout << "consume: " << utility::to_hex(buf,len) << std::endl; + //std::cout << "consume: " << utility::to_hex(buf,len) << std::endl; - // Loop while we don't have a message ready and we still have bytes - // left to process. - while (m_state != READY && m_state != FATAL_ERROR && - (p < len || m_bytes_needed == 0)) - { - if (m_state == HEADER_BASIC) { - p += this->copy_basic_header_bytes(buf+p,len-p); - - if (m_bytes_needed > 0) { - continue; - } + // Loop while we don't have a message ready and we still have bytes + // left to process. + while (m_state != READY && m_state != FATAL_ERROR && + (p < len || m_bytes_needed == 0)) + { + if (m_state == HEADER_BASIC) { + p += this->copy_basic_header_bytes(buf+p,len-p); + + if (m_bytes_needed > 0) { + continue; + } ec = this->validate_incoming_basic_header( m_basic_header, base::m_server, !m_data_msg.msg_ptr ); - if (ec) {break;} + if (ec) {break;} - // extract full header size and adjust consume state accordingly - m_state = HEADER_EXTENDED; - m_cursor = 0; - m_bytes_needed = frame::get_header_len(m_basic_header) - - frame::BASIC_HEADER_LENGTH; - } else if (m_state == HEADER_EXTENDED) { - p += this->copy_extended_header_bytes(buf+p,len-p); + // extract full header size and adjust consume state accordingly + m_state = HEADER_EXTENDED; + m_cursor = 0; + m_bytes_needed = frame::get_header_len(m_basic_header) - + frame::BASIC_HEADER_LENGTH; + } else if (m_state == HEADER_EXTENDED) { + p += this->copy_extended_header_bytes(buf+p,len-p); - if (m_bytes_needed > 0) { - continue; - } - + if (m_bytes_needed > 0) { + continue; + } + ec = validate_incoming_extended_header(m_basic_header,m_extended_header); - if (ec){break;} - - m_state = APPLICATION; - m_bytes_needed = static_cast(get_payload_size(m_basic_header,m_extended_header)); - - // check if this frame is the start of a new message and set up - // the appropriate message metadata. - frame::opcode::value op = frame::get_opcode(m_basic_header); + if (ec){break;} + + m_state = APPLICATION; + m_bytes_needed = static_cast(get_payload_size(m_basic_header,m_extended_header)); + + // check if this frame is the start of a new message and set up + // the appropriate message metadata. + frame::opcode::value op = frame::get_opcode(m_basic_header); // TODO: get_message failure conditions - if (frame::opcode::is_control(op)) { - m_control_msg = msg_metadata( - m_msg_manager->get_message(op,m_bytes_needed), - frame::get_masking_key(m_basic_header,m_extended_header) - ); - - m_current_msg = &m_control_msg; - } else { - if (!m_data_msg.msg_ptr) { - m_data_msg = msg_metadata( - m_msg_manager->get_message(op,m_bytes_needed), - frame::get_masking_key(m_basic_header,m_extended_header) - ); - } else { + if (frame::opcode::is_control(op)) { + m_control_msg = msg_metadata( + m_msg_manager->get_message(op,m_bytes_needed), + frame::get_masking_key(m_basic_header,m_extended_header) + ); + + m_current_msg = &m_control_msg; + } else { + if (!m_data_msg.msg_ptr) { + m_data_msg = msg_metadata( + m_msg_manager->get_message(op,m_bytes_needed), + frame::get_masking_key(m_basic_header,m_extended_header) + ); + } else { // Each frame starts a new masking key. All other state // remains between frames. m_data_msg.prepared_key = prepare_masking_key( @@ -411,190 +411,190 @@ public: m_extended_header ) ); - // TODO: reserve space in the existing message for the new bytes - } - m_current_msg = &m_data_msg; - } - } else if (m_state == EXTENSION) { - m_state = APPLICATION; - } else if (m_state == APPLICATION) { - size_t bytes_to_process = std::min(m_bytes_needed,len-p); - - if (bytes_to_process > 0) { - p += this->process_payload_bytes(buf+p,bytes_to_process,ec); - - if (ec) {break;} - } + // TODO: reserve space in the existing message for the new bytes + } + m_current_msg = &m_data_msg; + } + } else if (m_state == EXTENSION) { + m_state = APPLICATION; + } else if (m_state == APPLICATION) { + size_t bytes_to_process = std::min(m_bytes_needed,len-p); + + if (bytes_to_process > 0) { + p += this->process_payload_bytes(buf+p,bytes_to_process,ec); + + if (ec) {break;} + } - if (m_bytes_needed > 0) { - continue; - } - - // If this was the last frame in the message set the ready flag. - // Otherwise, reset processor state to read additional frames. - if (frame::get_fin(m_basic_header)) { - // ensure that text messages end on a valid UTF8 code point - if (frame::get_opcode(m_basic_header) == frame::opcode::TEXT) { - if (!m_current_msg->validator.complete()) { + if (m_bytes_needed > 0) { + continue; + } + + // If this was the last frame in the message set the ready flag. + // Otherwise, reset processor state to read additional frames. + if (frame::get_fin(m_basic_header)) { + // ensure that text messages end on a valid UTF8 code point + if (frame::get_opcode(m_basic_header) == frame::opcode::TEXT) { + if (!m_current_msg->validator.complete()) { ec = make_error_code(error::invalid_utf8); - break; - } - } + break; + } + } - m_state = READY; - } else { - this->reset_headers(); - } - } else { - // shouldn't be here + m_state = READY; + } else { + this->reset_headers(); + } + } else { + // shouldn't be here ec = make_error_code(error::general); - return 0; - } - } - - return p; - } - - void reset_headers() { - m_state = HEADER_BASIC; - m_bytes_needed = frame::BASIC_HEADER_LENGTH; + return 0; + } + } + + return p; + } + + void reset_headers() { + m_state = HEADER_BASIC; + m_bytes_needed = frame::BASIC_HEADER_LENGTH; - m_basic_header.b0 = 0x00; - m_basic_header.b1 = 0x00; + m_basic_header.b0 = 0x00; + m_basic_header.b1 = 0x00; - std::fill_n( - m_extended_header.bytes, - frame::MAX_EXTENDED_HEADER_LENGTH, - 0x00 - ); - } - - /// Test whether or not the processor has a message ready - bool ready() const { - return (m_state == READY); - } - - message_ptr get_message() { - if (!ready()) { - return message_ptr(); - } - message_ptr ret = m_current_msg->msg_ptr; - m_current_msg->msg_ptr.reset(); + std::fill_n( + m_extended_header.bytes, + frame::MAX_EXTENDED_HEADER_LENGTH, + 0x00 + ); + } + + /// Test whether or not the processor has a message ready + bool ready() const { + return (m_state == READY); + } + + message_ptr get_message() { + if (!ready()) { + return message_ptr(); + } + message_ptr ret = m_current_msg->msg_ptr; + m_current_msg->msg_ptr.reset(); - if (frame::opcode::is_control(ret->get_opcode())) { - m_control_msg.msg_ptr.reset(); - } else { - m_data_msg.msg_ptr.reset(); - } - - this->reset_headers(); - - return ret; - } - - /// Test whether or not the processor is in a fatal error state. - bool get_error() const { - return m_state == FATAL_ERROR; - } + if (frame::opcode::is_control(ret->get_opcode())) { + m_control_msg.msg_ptr.reset(); + } else { + m_data_msg.msg_ptr.reset(); + } + + this->reset_headers(); + + return ret; + } + + /// Test whether or not the processor is in a fatal error state. + bool get_error() const { + return m_state == FATAL_ERROR; + } - size_t get_bytes_needed() const { - return m_bytes_needed; - } + size_t get_bytes_needed() const { + return m_bytes_needed; + } - /// Prepare a user data message for writing - /** - * Performs validation, masking, compression, etc. will return an error if - * there was an error, otherwise msg will be ready to be written - * - * By default WebSocket++ performs block masking/unmasking in a manner that - * makes assumptions about the nature of the machine and STL library used. - * In particular the assumption is either a 32 or 64 bit word size and an - * STL with std::string::data returning a contiguous char array. - * - * This method improves masking performance by 3-8x depending on the ratio - * of small to large messages and the availability of a 64 bit processor. - * - * To disable this optimization (for use with alternative STL - * implementations or processors) define WEBSOCKETPP_STRICT_MASKING when - * compiling the library. This will force the library to perform masking in - * single byte chunks. - * - * TODO: tests - * - * @param in An unprepared message to prepare - * - * @param out A message to be overwritten with the prepared message - * - * @return error code - */ - virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) - { - if (!in || !out) { - return make_error_code(error::invalid_arguments); - } - + /// Prepare a user data message for writing + /** + * Performs validation, masking, compression, etc. will return an error if + * there was an error, otherwise msg will be ready to be written + * + * By default WebSocket++ performs block masking/unmasking in a manner that + * makes assumptions about the nature of the machine and STL library used. + * In particular the assumption is either a 32 or 64 bit word size and an + * STL with std::string::data returning a contiguous char array. + * + * This method improves masking performance by 3-8x depending on the ratio + * of small to large messages and the availability of a 64 bit processor. + * + * To disable this optimization (for use with alternative STL + * implementations or processors) define WEBSOCKETPP_STRICT_MASKING when + * compiling the library. This will force the library to perform masking in + * single byte chunks. + * + * TODO: tests + * + * @param in An unprepared message to prepare + * + * @param out A message to be overwritten with the prepared message + * + * @return error code + */ + virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) + { + if (!in || !out) { + return make_error_code(error::invalid_arguments); + } + frame::opcode::value op = in->get_opcode(); // validate opcode: only regular data frames if (frame::opcode::is_control(op)) { - return make_error_code(error::invalid_opcode); - } - - std::string& i = in->get_raw_payload(); - std::string& o = out->get_raw_payload(); - - // validate payload utf8 - if (op == frame::opcode::TEXT && !utf8_validator::validate(i)) { - return make_error_code(error::invalid_payload); - } - - frame::masking_key_type key; - bool masked = !base::m_server; + return make_error_code(error::invalid_opcode); + } + + std::string& i = in->get_raw_payload(); + std::string& o = out->get_raw_payload(); + + // validate payload utf8 + if (op == frame::opcode::TEXT && !utf8_validator::validate(i)) { + return make_error_code(error::invalid_payload); + } + + frame::masking_key_type key; + bool masked = !base::m_server; bool compressed = m_permessage_deflate.is_enabled() && in->get_compressed(); bool fin = in->get_fin(); - - // generate header - frame::basic_header h(op,i.size(),fin,masked,compressed); - - if (masked) { - // Generate masking key. - key.i = m_rng(); - - frame::extended_header e(i.size(),key.i); - out->set_header(frame::prepare_header(h,e)); - } else { - frame::extended_header e(i.size()); - out->set_header(frame::prepare_header(h,e)); - } - - // prepare payload - if (compressed) { - // compress and store in o after header. + + // generate header + frame::basic_header h(op,i.size(),fin,masked,compressed); + + if (masked) { + // Generate masking key. + key.i = m_rng(); + + frame::extended_header e(i.size(),key.i); + out->set_header(frame::prepare_header(h,e)); + } else { + frame::extended_header e(i.size()); + out->set_header(frame::prepare_header(h,e)); + } + + // prepare payload + if (compressed) { + // compress and store in o after header. m_permessage_deflate.compress(i,o); - // mask in place if necessary + // mask in place if necessary if (masked) { this->masked_copy(o,o,key); } - } else { - // no compression, just copy data into the output buffer - o.resize(i.size()); - - // if we are masked, have the masking function write to the output - // buffer directly to avoid another copy. If not masked, copy - // directly without masking. - if (masked) { + } else { + // no compression, just copy data into the output buffer + o.resize(i.size()); + + // if we are masked, have the masking function write to the output + // buffer directly to avoid another copy. If not masked, copy + // directly without masking. + if (masked) { this->masked_copy(i,o,key); - } else { - std::copy(i.begin(),i.end(),o.begin()); - } - } + } else { + std::copy(i.begin(),i.end(),o.begin()); + } + } - out->set_prepared(true); - - return lib::error_code(); - } + out->set_prepared(true); + + return lib::error_code(); + } lib::error_code prepare_ping(const std::string& in, message_ptr out) const { return this->prepare_control(frame::opcode::PING,in,out); @@ -640,7 +640,7 @@ public: return this->prepare_control(frame::opcode::CLOSE,payload,out); } protected: - /// Convert a client handshake key into a server response key in place + /// Convert a client handshake key into a server response key in place lib::error_code process_handshake_key(std::string & key) const { key.append(constants::handshake_guid); @@ -668,80 +668,80 @@ protected: } /// Reads bytes from buf into m_basic_header - size_t copy_basic_header_bytes(const uint8_t * buf, size_t len) { - if (len == 0 || m_bytes_needed == 0) { - return 0; - } - - if (len > 1) { - // have at least two bytes - if (m_bytes_needed == 2) { - m_basic_header.b0 = buf[0]; - m_basic_header.b1 = buf[1]; - m_bytes_needed -= 2; - return 2; - } else { - m_basic_header.b1 = buf[0]; - m_bytes_needed--; - return 1; - } - } else { - // have exactly one byte - if (m_bytes_needed == 2) { - m_basic_header.b0 = buf[0]; - m_bytes_needed--; - return 1; - } else { - m_basic_header.b1 = buf[0]; - m_bytes_needed--; - return 1; - } - } - } + size_t copy_basic_header_bytes(const uint8_t * buf, size_t len) { + if (len == 0 || m_bytes_needed == 0) { + return 0; + } + + if (len > 1) { + // have at least two bytes + if (m_bytes_needed == 2) { + m_basic_header.b0 = buf[0]; + m_basic_header.b1 = buf[1]; + m_bytes_needed -= 2; + return 2; + } else { + m_basic_header.b1 = buf[0]; + m_bytes_needed--; + return 1; + } + } else { + // have exactly one byte + if (m_bytes_needed == 2) { + m_basic_header.b0 = buf[0]; + m_bytes_needed--; + return 1; + } else { + m_basic_header.b1 = buf[0]; + m_bytes_needed--; + return 1; + } + } + } - /// Reads bytes from buf into m_extended_header - size_t copy_extended_header_bytes(const uint8_t * buf, size_t len) { - size_t bytes_to_read = std::min(m_bytes_needed,len); - - std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor); - m_cursor += bytes_to_read; - m_bytes_needed -= bytes_to_read; + /// Reads bytes from buf into m_extended_header + size_t copy_extended_header_bytes(const uint8_t * buf, size_t len) { + size_t bytes_to_read = std::min(m_bytes_needed,len); + + std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor); + m_cursor += bytes_to_read; + m_bytes_needed -= bytes_to_read; - return bytes_to_read; - } + return bytes_to_read; + } - /// Reads bytes from buf into message payload - /** + /// Reads bytes from buf into message payload + /** * This function performs unmasking and uncompression, validates the - * decoded bytes, and writes them to the appropriate message buffer. - * - * This member function will use the input buffer as stratch space for its - * work. The raw input bytes will not be preserved. This applies only to the - * bytes actually needed. At most min(m_bytes_needed,len) will be processed. - * - * @param buf Input/working buffer - * - * @param len Length of buf - * - * @return Number of bytes processed or zero in case of an error - * - */ - size_t process_payload_bytes(uint8_t * buf, size_t len, lib::error_code& ec) + * decoded bytes, and writes them to the appropriate message buffer. + * + * This member function will use the input buffer as stratch space for its + * work. The raw input bytes will not be preserved. This applies only to the + * bytes actually needed. At most min(m_bytes_needed,len) will be processed. + * + * @param buf Input/working buffer + * + * @param len Length of buf + * + * @return Number of bytes processed or zero in case of an error + * + */ + size_t process_payload_bytes(uint8_t * buf, size_t len, lib::error_code& ec) { - // unmask if masked - if (frame::get_masked(m_basic_header)) { - m_current_msg->prepared_key = frame::word_mask_circ( - buf, - len, - m_current_msg->prepared_key - ); - } + // unmask if masked + if (frame::get_masked(m_basic_header)) { + m_current_msg->prepared_key = frame::word_mask_circ( + buf, + len, + m_current_msg->prepared_key + ); + } std::string& out = m_current_msg->msg_ptr->get_raw_payload(); size_t offset = out.size(); - // decompress message if needed. - if (m_permessage_deflate.is_enabled() + // decompress message if needed. + if (m_permessage_deflate.is_enabled() && frame::get_rsv1(m_basic_header)) { // Decompress current buffer into the message buffer @@ -754,28 +754,28 @@ protected: out.append(reinterpret_cast(buf),len); } - // validate unmasked, decompressed values - if (m_current_msg->msg_ptr->get_opcode() == frame::opcode::TEXT) { - if (!m_current_msg->validator.decode(out.begin()+offset,out.end())) { + // validate unmasked, decompressed values + if (m_current_msg->msg_ptr->get_opcode() == frame::opcode::TEXT) { + if (!m_current_msg->validator.decode(out.begin()+offset,out.end())) { ec = make_error_code(error::invalid_utf8); - return 0; - } - } - - // copy into message buffer - /*m_current_msg->msg_ptr->append_payload( - reinterpret_cast(buf), - len - );*/ - m_bytes_needed -= len; + return 0; + } + } + + // copy into message buffer + /*m_current_msg->msg_ptr->append_payload( + reinterpret_cast(buf), + len + );*/ + m_bytes_needed -= len; - return len; - } - - /// Validate an incoming basic header - /** - * Validates an incoming hybi13 basic header. - * + return len; + } + + /// Validate an incoming basic header + /** + * Validates an incoming hybi13 basic header. + * * @param h The basic header to validate * * @param is_server Whether or not the endpoint that received this frame @@ -783,21 +783,21 @@ protected: * * @param new_msg Whether or not this is the first frame of the message * - * @return 0 on success or a non-zero error code on failure - */ + * @return 0 on success or a non-zero error code on failure + */ lib::error_code validate_incoming_basic_header(const frame::basic_header &h, bool is_server, bool new_msg) const { frame::opcode::value op = frame::get_opcode(h); - // Check control frame size limit - if (frame::opcode::is_control(op) && + // Check control frame size limit + if (frame::opcode::is_control(op) && frame::get_basic_size(h) > frame::limits::payload_size_basic) - { + { return make_error_code(error::control_too_big); - } + } - // Check that RSV bits are clear + // Check that RSV bits are clear // The only RSV bits allowed are rsv1 if the permessage_compress // extension is enabled for this connection and the message is not // a control message. @@ -811,29 +811,29 @@ protected: if (frame::get_rsv2(h) || frame::get_rsv3(h)) { return make_error_code(error::invalid_rsv_bit); - } + } - // Check for reserved opcodes - if (frame::opcode::reserved(op)) { + // Check for reserved opcodes + if (frame::opcode::reserved(op)) { return make_error_code(error::invalid_opcode); - } + } - // Check for invalid opcodes - // TODO: unit tests for this? - if (frame::opcode::invalid(op)) { - return make_error_code(error::invalid_opcode); - } + // Check for invalid opcodes + // TODO: unit tests for this? + if (frame::opcode::invalid(op)) { + return make_error_code(error::invalid_opcode); + } - // Check for fragmented control message - if (frame::opcode::is_control(op) && !frame::get_fin(h)) { + // Check for fragmented control message + if (frame::opcode::is_control(op) && !frame::get_fin(h)) { return make_error_code(error::fragmented_control); - } - - // Check for continuation without an active message - if (new_msg && op == frame::opcode::CONTINUATION) { + } + + // Check for continuation without an active message + if (new_msg && op == frame::opcode::CONTINUATION) { return make_error_code(error::invalid_continuation); - } - + } + // Check for new data frame when expecting continuation if (!new_msg && !frame::opcode::is_control(op) && op != frame::opcode::CONTINUATION) @@ -841,19 +841,19 @@ protected: return make_error_code(error::invalid_continuation); } - // Servers should reject any unmasked frames from clients. - // Clients should reject any masked frames from servers. - if (is_server && !frame::get_masked(h)) { + // Servers should reject any unmasked frames from clients. + // Clients should reject any masked frames from servers. + if (is_server && !frame::get_masked(h)) { return make_error_code(error::masking_required); - } else if (!is_server && frame::get_masked(h)) { + } else if (!is_server && frame::get_masked(h)) { return make_error_code(error::masking_forbidden); - } + } - return lib::error_code(); - } - - /// Validate an incoming extended header - /** + return lib::error_code(); + } + + /// Validate an incoming extended header + /** * Validates an incoming hybi13 full header. * * @param h The basic header to validate @@ -866,31 +866,31 @@ protected: lib::error_code validate_incoming_extended_header(const frame::basic_header h, const frame::extended_header e) const { - uint8_t basic_size = frame::get_basic_size(h); - uint64_t payload_size = frame::get_payload_size(h,e); - - // Check for non-minimally encoded payloads - if (basic_size == frame::payload_size_code_16bit && - payload_size <= frame::limits::payload_size_basic) - { + uint8_t basic_size = frame::get_basic_size(h); + uint64_t payload_size = frame::get_payload_size(h,e); + + // Check for non-minimally encoded payloads + if (basic_size == frame::payload_size_code_16bit && + payload_size <= frame::limits::payload_size_basic) + { return make_error_code(error::non_minimal_encoding); - } + } - if (basic_size == frame::payload_size_code_64bit && - payload_size <= frame::limits::payload_size_extended) - { + if (basic_size == frame::payload_size_code_64bit && + payload_size <= frame::limits::payload_size_extended) + { return make_error_code(error::non_minimal_encoding); - } + } - // Check for >32bit frames on 32 bit systems - // TODO: unit test for this case - if (sizeof(size_t) == 4 && (payload_size >> 32)) { + // Check for >32bit frames on 32 bit systems + // TODO: unit test for this case + if (sizeof(size_t) == 4 && (payload_size >> 32)) { return make_error_code(error::requires_64bit); - } + } - return lib::error_code(); - } - + return lib::error_code(); + } + void masked_copy (const std::string & i, std::string & o, frame::masking_key_type key) const { @@ -921,92 +921,92 @@ protected: lib::error_code prepare_control(frame::opcode::value op, const std::string & payload, message_ptr out) const { - if (!out) { - return make_error_code(error::invalid_arguments); - } + if (!out) { + return make_error_code(error::invalid_arguments); + } if (!frame::opcode::is_control(op)) { return make_error_code(error::invalid_opcode); } - if (payload.size() > frame::limits::payload_size_basic) { - return make_error_code(error::control_too_big); - } + if (payload.size() > frame::limits::payload_size_basic) { + return make_error_code(error::control_too_big); + } - frame::masking_key_type key; - bool masked = !base::m_server; - - frame::basic_header h(op,payload.size(),true,masked); + frame::masking_key_type key; + bool masked = !base::m_server; + + frame::basic_header h(op,payload.size(),true,masked); - std::string& o = out->get_raw_payload(); + std::string& o = out->get_raw_payload(); o.resize(payload.size()); - if (masked) { - // Generate masking key. - key.i = m_rng(); - - frame::extended_header e(payload.size(),key.i); - out->set_header(frame::prepare_header(h,e)); + if (masked) { + // Generate masking key. + key.i = m_rng(); + + frame::extended_header e(payload.size(),key.i); + out->set_header(frame::prepare_header(h,e)); this->masked_copy(payload,o,key); - } else { - frame::extended_header e(payload.size()); - out->set_header(frame::prepare_header(h,e)); + } else { + frame::extended_header e(payload.size()); + out->set_header(frame::prepare_header(h,e)); //std::cout << "o: " << o.size() << std::endl; std::copy(payload.begin(),payload.end(),o.begin()); //std::cout << "o: " << o.size() << std::endl; - } - - out->set_prepared(true); - - return lib::error_code(); + } + + out->set_prepared(true); + + return lib::error_code(); } - enum state { - HEADER_BASIC = 0, - HEADER_EXTENDED = 1, - EXTENSION = 2, - APPLICATION = 3, - READY = 4, - FATAL_ERROR = 5 - }; - - /// This data structure holds data related to processing a message, such as - /// the buffer it is being written to, its masking key, its UTF8 validation - /// state, and sometimes its compression state. - struct msg_metadata { - msg_metadata() {} - msg_metadata(message_ptr m, size_t p) : msg_ptr(m),prepared_key(p) {} - msg_metadata(message_ptr m, frame::masking_key_type p) - : msg_ptr(m) - , prepared_key(prepare_masking_key(p)) {} + enum state { + HEADER_BASIC = 0, + HEADER_EXTENDED = 1, + EXTENSION = 2, + APPLICATION = 3, + READY = 4, + FATAL_ERROR = 5 + }; + + /// This data structure holds data related to processing a message, such as + /// the buffer it is being written to, its masking key, its UTF8 validation + /// state, and sometimes its compression state. + struct msg_metadata { + msg_metadata() {} + msg_metadata(message_ptr m, size_t p) : msg_ptr(m),prepared_key(p) {} + msg_metadata(message_ptr m, frame::masking_key_type p) + : msg_ptr(m) + , prepared_key(prepare_masking_key(p)) {} - message_ptr msg_ptr; // pointer to the message data buffer - size_t prepared_key; // prepared masking key - utf8_validator::validator validator; // utf8 validation state - }; + message_ptr msg_ptr; // pointer to the message data buffer + size_t prepared_key; // prepared masking key + utf8_validator::validator validator; // utf8 validation state + }; // Basic header of the frame being read - frame::basic_header m_basic_header; + frame::basic_header m_basic_header; - // Pointer to a manager that can create message buffers for us. - msg_manager_ptr m_msg_manager; + // Pointer to a manager that can create message buffers for us. + msg_manager_ptr m_msg_manager; - // Number of bytes needed to complete the current operation - size_t m_bytes_needed; - - // Number of extended header bytes read - size_t m_cursor; - - // Metadata for the current data msg - msg_metadata m_data_msg; - // Metadata for the current control msg - msg_metadata m_control_msg; + // Number of bytes needed to complete the current operation + size_t m_bytes_needed; + + // Number of extended header bytes read + size_t m_cursor; + + // Metadata for the current data msg + msg_metadata m_data_msg; + // Metadata for the current control msg + msg_metadata m_control_msg; // Pointer to the metadata associated with the frame being read - msg_metadata *m_current_msg; - - // Extended header of current frame - frame::extended_header m_extended_header; + msg_metadata *m_current_msg; + + // Extended header of current frame + frame::extended_header m_extended_header; // write/prep state @@ -1016,8 +1016,8 @@ protected: rng_type& m_rng; - // Overall state of the processor - state m_state; + // Overall state of the processor + state m_state; // Extensions permessage_deflate_type m_permessage_deflate; diff --git a/websocketpp/processors/processor.hpp b/websocketpp/processors/processor.hpp index d06d88f9a2..6725c97c50 100644 --- a/websocketpp/processors/processor.hpp +++ b/websocketpp/processors/processor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -53,25 +53,25 @@ namespace processor { */ template bool is_websocket_handshake(request_type& r) { - using utility::ci_find_substr; - - const std::string& upgrade_header = r.get_header("Upgrade"); - - if (ci_find_substr(upgrade_header, constants::upgrade_token, - sizeof(constants::upgrade_token)-1) == upgrade_header.end()) - { - return false; - } - - const std::string& con_header = r.get_header("Connection"); - - if (ci_find_substr(con_header, constants::connection_token, - sizeof(constants::connection_token)-1) == con_header.end()) - { - return false; - } + using utility::ci_find_substr; + + const std::string& upgrade_header = r.get_header("Upgrade"); + + if (ci_find_substr(upgrade_header, constants::upgrade_token, + sizeof(constants::upgrade_token)-1) == upgrade_header.end()) + { + return false; + } + + const std::string& con_header = r.get_header("Connection"); + + if (ci_find_substr(con_header, constants::connection_token, + sizeof(constants::connection_token)-1) == con_header.end()) + { + return false; + } - return true; + return true; } /// Extract the version from a WebSocket handshake request @@ -98,7 +98,7 @@ int get_websocket_version(request_type& r) { int version; std::istringstream ss(r.get_header("Sec-WebSocket-Version")); - + if ((ss >> version).fail()) { return -1; } @@ -121,7 +121,7 @@ int get_websocket_version(request_type& r) { // // while(len = read(buf)) { // if (processor.consume(buf,len) == 0) { -// // handle errors +// // handle errors // } // if (processor.ready()) { // message_ptr msg = processor.get_message(); @@ -135,18 +135,18 @@ class processor { public: typedef processor type; typedef typename config::request_type request_type; - typedef typename config::response_type response_type; - typedef typename config::message_type::ptr message_ptr; + typedef typename config::response_type response_type; + typedef typename config::message_type::ptr message_ptr; typedef std::pair err_str_pair; explicit processor(bool secure, bool server) : m_secure(secure) - , m_server(server) {} + , m_server(server) {} virtual ~processor() {} /// Returns the version of the WebSocket protocol that this processor - /// understands. + /// understands. virtual int get_version() const = 0; /// Returns whether or not the permessage_compress extension is implimented @@ -171,8 +171,8 @@ public: /// validate a WebSocket handshake request for this version /** * @param r The WebSocket handshake request to validate. - * is_websocket_handshake(r) must be true and get_websocket_version(r) - * must equal this->get_version(). + * is_websocket_handshake(r) must be true and get_websocket_version(r) + * must equal this->get_version(). * * @return A status code, 0 on success, non-zero for specific sorts of * failure @@ -218,7 +218,7 @@ public: /// Return the value of the header containing the CORS origin. virtual const std::string& get_origin(const request_type& request) - const = 0; + const = 0; /// Extracts requested subprotocols from a handshake request /** @@ -236,62 +236,62 @@ public: /// Extracts client uri from a handshake request virtual uri_ptr get_uri(const request_type& request) const = 0; - /// process new websocket connection bytes - /** - * WebSocket connections are a continous stream of bytes that must be - * interpreted by a protocol processor into discrete frames. - * - * @param buf Buffer from which bytes should be read. - * - * @param len Length of buffer + /// process new websocket connection bytes + /** + * WebSocket connections are a continous stream of bytes that must be + * interpreted by a protocol processor into discrete frames. + * + * @param buf Buffer from which bytes should be read. + * + * @param len Length of buffer * * @param ec Reference to an error code to return any errors in - * - * @return Number of bytes processed - */ - virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0; - - /// Checks if there is a message ready - /** - * Checks if the most recent consume operation processed enough bytes to - * complete a new WebSocket message. The message can be retrieved by calling - * get_message() which will reset the internal state to not-ready and allow - * consume to read more bytes. - * - * @return Whether or not a message is ready. - */ - virtual bool ready() const = 0; + * + * @return Number of bytes processed + */ + virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0; + + /// Checks if there is a message ready + /** + * Checks if the most recent consume operation processed enough bytes to + * complete a new WebSocket message. The message can be retrieved by calling + * get_message() which will reset the internal state to not-ready and allow + * consume to read more bytes. + * + * @return Whether or not a message is ready. + */ + virtual bool ready() const = 0; - /// Retrieves the most recently processed message - /** - * Retrieves a shared pointer to the recently completed message if there is - * one. If ready() returns true then there is a message avaliable. - * Retrieving the message with get_message will reset the state of ready. - * As such, each new message may be retrieved only once. Calling get_message - * when there is no message avaliable will result in a null pointer being - * returned. - * - * @return A pointer to the most recently processed message or a null shared - * pointer. - */ - virtual message_ptr get_message() = 0; - - /// Tests whether the processor is in a fatal error state - virtual bool get_error() const = 0; + /// Retrieves the most recently processed message + /** + * Retrieves a shared pointer to the recently completed message if there is + * one. If ready() returns true then there is a message avaliable. + * Retrieving the message with get_message will reset the state of ready. + * As such, each new message may be retrieved only once. Calling get_message + * when there is no message avaliable will result in a null pointer being + * returned. + * + * @return A pointer to the most recently processed message or a null shared + * pointer. + */ + virtual message_ptr get_message() = 0; + + /// Tests whether the processor is in a fatal error state + virtual bool get_error() const = 0; - /// Retrieves the number of bytes presently needed by the processor - /// This value may be used as a hint to the transport layer as to how many + /// Retrieves the number of bytes presently needed by the processor + /// This value may be used as a hint to the transport layer as to how many /// bytes to wait for before running consume again. - virtual size_t get_bytes_needed() const { - return 1; - } - - /// Prepare a data message for writing - /** - * Performs validation, masking, compression, etc. will return an error if - * there was an error, otherwise msg will be ready to be written - */ - virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) + virtual size_t get_bytes_needed() const { + return 1; + } + + /// Prepare a data message for writing + /** + * Performs validation, masking, compression, etc. will return an error if + * there was an error, otherwise msg will be ready to be written + */ + virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) = 0; /// Prepare a ping frame @@ -341,7 +341,7 @@ public: const std::string & reason, message_ptr out) const = 0; protected: const bool m_secure; - const bool m_server; + const bool m_server; }; diff --git a/websocketpp/random/none.hpp b/websocketpp/random/none.hpp index 9760c37e72..c2d3e20fdd 100644 --- a/websocketpp/random/none.hpp +++ b/websocketpp/random/none.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -42,13 +42,13 @@ namespace none { */ template class int_generator { - public: - int_generator() {} - - /// advances the engine's state and returns the generated value - int_type operator()() { - return 0; - } + public: + int_generator() {} + + /// advances the engine's state and returns the generated value + int_type operator()() { + return 0; + } }; } // namespace none diff --git a/websocketpp/random/random_device.hpp b/websocketpp/random/random_device.hpp index 0d94a4cc6d..47d06a7a4c 100644 --- a/websocketpp/random/random_device.hpp +++ b/websocketpp/random/random_device.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -50,26 +50,26 @@ namespace random_device { */ template class int_generator { - public: - typedef typename concurrency::scoped_lock_type scoped_lock_type; - typedef typename concurrency::mutex_type mutex_type; - - /// constructor - //mac TODO: figure out if signed types present a range problem - int_generator() {} - - /// advances the engine's state and returns the generated value - int_type operator()() { - scoped_lock_type guard(m_lock); - return m_dis(m_rng); - } - private: - - - lib::random_device m_rng; - lib::uniform_int_distribution m_dis; - - mutex_type m_lock; + public: + typedef typename concurrency::scoped_lock_type scoped_lock_type; + typedef typename concurrency::mutex_type mutex_type; + + /// constructor + //mac TODO: figure out if signed types present a range problem + int_generator() {} + + /// advances the engine's state and returns the generated value + int_type operator()() { + scoped_lock_type guard(m_lock); + return m_dis(m_rng); + } + private: + + + lib::random_device m_rng; + lib::uniform_int_distribution m_dis; + + mutex_type m_lock; }; } // namespace random_device diff --git a/websocketpp/roles/client.hpp b/websocketpp/roles/client.hpp index 687121748d..b09911aaa4 100644 --- a/websocketpp/roles/client.hpp +++ b/websocketpp/roles/client.hpp @@ -35,7 +35,7 @@ namespace role { class client { public: - static bool is_server = false; + static bool is_server = false; } } // namespace role diff --git a/websocketpp/roles/client_endpoint.hpp b/websocketpp/roles/client_endpoint.hpp index 736d554a81..90539682e8 100644 --- a/websocketpp/roles/client_endpoint.hpp +++ b/websocketpp/roles/client_endpoint.hpp @@ -44,16 +44,16 @@ template class client : public endpoint,config> { public: /// Type of this endpoint - typedef client type; - - /// Type of the endpoint concurrency component - typedef typename config::concurrency_type concurrency_type; + typedef client type; + + /// Type of the endpoint concurrency component + typedef typename config::concurrency_type concurrency_type; /// Type of the endpoint transport component - typedef typename config::transport_type transport_type; - - /// Type of the connections this server will create - typedef connection connection_type; - /// Type of a shared pointer to the connections this server will create + typedef typename config::transport_type transport_type; + + /// Type of the connections this server will create + typedef connection connection_type; + /// Type of a shared pointer to the connections this server will create typedef typename connection_type::ptr connection_ptr; /// Type of the connection transport component @@ -61,26 +61,26 @@ public: /// Type of a shared pointer to the connection transport component typedef typename transport_con_type::ptr transport_con_ptr; - /// Type of the endpoint component of this server - typedef endpoint endpoint_type; - - explicit client() : endpoint_type(false) - { - endpoint_type::m_alog.write(log::alevel::devel, + /// Type of the endpoint component of this server + typedef endpoint endpoint_type; + + explicit client() : endpoint_type(false) + { + endpoint_type::m_alog.write(log::alevel::devel, "client constructor"); - } - - /// Get a new connection - /** - * Creates and returns a pointer to a new connection to the given URI - * suitable for passing to connect(connection_ptr). This method allows - * applying connection specific settings before performing the opening - * handshake. - * - * @return A connection_ptr to the new connection - */ - connection_ptr get_connection(const std::string& u, lib::error_code &ec) { - // parse uri + } + + /// Get a new connection + /** + * Creates and returns a pointer to a new connection to the given URI + * suitable for passing to connect(connection_ptr). This method allows + * applying connection specific settings before performing the opening + * handshake. + * + * @return A connection_ptr to the new connection + */ + connection_ptr get_connection(const std::string& u, lib::error_code &ec) { + // parse uri try { // uri validation uri_ptr location(new uri(u)); @@ -107,36 +107,36 @@ public: ec = error::make_error_code(error::invalid_uri); return connection_ptr(); } - } - - /// Begin the connection process for the given connection - /** - * Initiates the opening connection handshake for connection con. Exact - * behavior depends on the underlying transport policy. - * + } + + /// Begin the connection process for the given connection + /** + * Initiates the opening connection handshake for connection con. Exact + * behavior depends on the underlying transport policy. + * * @param con The connection to connect * - * @return The pointer to the connection originally passed in. - */ - connection_ptr connect(connection_ptr con) { - // Ask transport to perform a connection + * @return The pointer to the connection originally passed in. + */ + connection_ptr connect(connection_ptr con) { + // Ask transport to perform a connection transport_type::async_connect( - lib::static_pointer_cast(con), - con->get_uri(), - lib::bind( - &type::handle_connect, - this, - lib::placeholders::_1, - lib::placeholders::_2 - ) - ); + lib::static_pointer_cast(con), + con->get_uri(), + lib::bind( + &type::handle_connect, + this, + lib::placeholders::_1, + lib::placeholders::_2 + ) + ); - return con; - } - - - - // connect(...) + return con; + } + + + + // connect(...) private: // handle_connect void handle_connect(connection_hdl hdl, const lib::error_code & ec) { diff --git a/websocketpp/roles/server.hpp b/websocketpp/roles/server.hpp index 8e16b57bfc..b0e875cd41 100644 --- a/websocketpp/roles/server.hpp +++ b/websocketpp/roles/server.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -35,7 +35,7 @@ namespace role { class server { public: - static bool is_server = true; + static bool is_server = true; } } // namespace role diff --git a/websocketpp/roles/server_endpoint.hpp b/websocketpp/roles/server_endpoint.hpp index a07a2ea38e..723417e7ba 100644 --- a/websocketpp/roles/server_endpoint.hpp +++ b/websocketpp/roles/server_endpoint.hpp @@ -44,16 +44,16 @@ template class server : public endpoint,config> { public: /// Type of this endpoint - typedef server type; - - /// Type of the endpoint concurrency component - typedef typename config::concurrency_type concurrency_type; + typedef server type; + + /// Type of the endpoint concurrency component + typedef typename config::concurrency_type concurrency_type; /// Type of the endpoint transport component - typedef typename config::transport_type transport_type; - - /// Type of the connections this server will create - typedef connection connection_type; - /// Type of a shared pointer to the connections this server will create + typedef typename config::transport_type transport_type; + + /// Type of the connections this server will create + typedef connection connection_type; + /// Type of a shared pointer to the connections this server will create typedef typename connection_type::ptr connection_ptr; /// Type of the connection transport component @@ -61,42 +61,42 @@ public: /// Type of a shared pointer to the connection transport component typedef typename transport_con_type::ptr transport_con_ptr; - /// Type of the endpoint component of this server - typedef endpoint endpoint_type; - - - // TODO: clean up these types + /// Type of the endpoint component of this server + typedef endpoint endpoint_type; + + + // TODO: clean up these types - explicit server() : endpoint_type(true) - { - endpoint_type::m_alog.write(log::alevel::devel, + explicit server() : endpoint_type(true) + { + endpoint_type::m_alog.write(log::alevel::devel, "server constructor"); - } - - // return an initialized connection_ptr. Call start() on this object to - // begin the processing loop. - connection_ptr get_connection() { - connection_ptr con = endpoint_type::create_connection(); - - return con; - } - - // Starts the server's async connection acceptance loop. - void start_accept() { - connection_ptr con = get_connection(); - - transport_type::async_accept( - lib::static_pointer_cast(con), - lib::bind( - &type::handle_accept, - this, - lib::placeholders::_1, - lib::placeholders::_2 - ) - ); - } - - void handle_accept(connection_hdl hdl, const lib::error_code& ec) { + } + + // return an initialized connection_ptr. Call start() on this object to + // begin the processing loop. + connection_ptr get_connection() { + connection_ptr con = endpoint_type::create_connection(); + + return con; + } + + // Starts the server's async connection acceptance loop. + void start_accept() { + connection_ptr con = get_connection(); + + transport_type::async_accept( + lib::static_pointer_cast(con), + lib::bind( + &type::handle_accept, + this, + lib::placeholders::_1, + lib::placeholders::_2 + ) + ); + } + + void handle_accept(connection_hdl hdl, const lib::error_code& ec) { lib::error_code hdl_ec; connection_ptr con = endpoint_type::get_con_from_hdl(hdl,hdl_ec); @@ -122,10 +122,10 @@ public: con->start(); } } - + // TODO: are there cases where we should terminate this loop? - start_accept(); - } + start_accept(); + } private: }; diff --git a/websocketpp/transport/asio/base.hpp b/websocketpp/transport/asio/base.hpp index 1c618d5c66..3796fae2f0 100644 --- a/websocketpp/transport/asio/base.hpp +++ b/websocketpp/transport/asio/base.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -67,35 +67,35 @@ enum value { class category : public lib::error_category { public: - const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { - return "websocketpp.transport.asio"; - } - - std::string message(int value) const { - switch(value) { - case error::general: - return "Generic asio transport policy error"; - case error::invalid_num_bytes: - return "async_read_at_least call requested more bytes than buffer can store"; - case error::pass_through: - return "Underlying Transport Error"; - case error::proxy_failed: - return "Proxy connection failed"; - case error::proxy_invalid: - return "Invalid proxy URI"; - default: - return "Unknown"; - } - } + const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { + return "websocketpp.transport.asio"; + } + + std::string message(int value) const { + switch(value) { + case error::general: + return "Generic asio transport policy error"; + case error::invalid_num_bytes: + return "async_read_at_least call requested more bytes than buffer can store"; + case error::pass_through: + return "Underlying Transport Error"; + case error::proxy_failed: + return "Proxy connection failed"; + case error::proxy_invalid: + return "Invalid proxy URI"; + default: + return "Unknown"; + } + } }; inline const lib::error_category& get_category() { - static category instance; - return instance; + static category instance; + return instance; } inline lib::error_code make_error_code(error::value e) { - return lib::error_code(static_cast(e), get_category()); + return lib::error_code(static_cast(e), get_category()); } } // namespace error diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp index cc2e3829bd..ddd1680406 100644 --- a/websocketpp/transport/asio/endpoint.hpp +++ b/websocketpp/transport/asio/endpoint.hpp @@ -36,7 +36,7 @@ #include #include #include - + #include namespace websocketpp { @@ -52,7 +52,7 @@ template class endpoint : public config::socket_type { public: /// Type of this endpoint transport component - typedef endpoint type; + typedef endpoint type; /// Type of the concurrency policy typedef typename config::concurrency_type concurrency_type; @@ -70,109 +70,109 @@ public: /// Type of the connection transport component associated with this /// endpoint transport component - typedef asio::connection transport_con_type; + typedef asio::connection transport_con_type; /// Type of a shared pointer to the connection transport component /// associated with this endpoint transport component typedef typename transport_con_type::ptr transport_con_ptr; /// Type of a pointer to the ASIO io_service being used - typedef boost::asio::io_service* io_service_ptr; + typedef boost::asio::io_service* io_service_ptr; /// Type of a shared pointer to the acceptor being used - typedef lib::shared_ptr acceptor_ptr; + typedef lib::shared_ptr acceptor_ptr; /// Type of a shared pointer to the resolver being used - typedef lib::shared_ptr resolver_ptr; + typedef lib::shared_ptr resolver_ptr; - // generate and manage our own io_service - explicit endpoint() - : m_external_io_service(false) - , m_state(UNINITIALIZED) - { - //std::cout << "transport::asio::endpoint constructor" << std::endl; - } - - ~endpoint() { - // clean up our io_service if we were initialized with an internal one. + // generate and manage our own io_service + explicit endpoint() + : m_external_io_service(false) + , m_state(UNINITIALIZED) + { + //std::cout << "transport::asio::endpoint constructor" << std::endl; + } + + ~endpoint() { + // clean up our io_service if we were initialized with an internal one. m_acceptor.reset(); - if (m_state != UNINITIALIZED && !m_external_io_service) { - delete m_io_service; - } - } + if (m_state != UNINITIALIZED && !m_external_io_service) { + delete m_io_service; + } + } - /// transport::asio objects are moveable but not copyable or assignable. - /// The following code sets this situation up based on whether or not we - /// have C++11 support or not + /// transport::asio objects are moveable but not copyable or assignable. + /// The following code sets this situation up based on whether or not we + /// have C++11 support or not #ifdef _WEBSOCKETPP_DELETED_FUNCTIONS_ - endpoint(const endpoint& src) = delete; - endpoint& operator= (const endpoint & rhs) = delete; + endpoint(const endpoint& src) = delete; + endpoint& operator= (const endpoint & rhs) = delete; #else private: - endpoint(const endpoint& src); - endpoint& operator= (const endpoint & rhs); + endpoint(const endpoint& src); + endpoint& operator= (const endpoint & rhs); public: #endif #ifdef _WEBSOCKETPP_RVALUE_REFERENCES_ - endpoint (endpoint&& src) - : m_io_service(src.m_io_service) - , m_external_io_service(src.m_external_io_service) - , m_acceptor(src.m_acceptor) - , m_state(src.m_state) - { - src.m_io_service = NULL; - src.m_external_io_service = false; - src.m_acceptor = NULL; - src.m_state = UNINITIALIZED; - } - - endpoint& operator= (const endpoint && rhs) { - if (this != &rhs) { - m_io_service = rhs.m_io_service; - m_external_io_service = rhs.m_external_io_service; - m_acceptor = rhs.m_acceptor; - m_state = rhs.m_state; - - rhs.m_io_service = NULL; - rhs.m_external_io_service = false; - rhs.m_acceptor = NULL; - rhs.m_state = UNINITIALIZED; - } - return *this; - } + endpoint (endpoint&& src) + : m_io_service(src.m_io_service) + , m_external_io_service(src.m_external_io_service) + , m_acceptor(src.m_acceptor) + , m_state(src.m_state) + { + src.m_io_service = NULL; + src.m_external_io_service = false; + src.m_acceptor = NULL; + src.m_state = UNINITIALIZED; + } + + endpoint& operator= (const endpoint && rhs) { + if (this != &rhs) { + m_io_service = rhs.m_io_service; + m_external_io_service = rhs.m_external_io_service; + m_acceptor = rhs.m_acceptor; + m_state = rhs.m_state; + + rhs.m_io_service = NULL; + rhs.m_external_io_service = false; + rhs.m_acceptor = NULL; + rhs.m_state = UNINITIALIZED; + } + return *this; + } #endif - - /// initialize asio transport with external io_service - /** - * Initialize the ASIO transport policy for this endpoint using the - * io_service object. asio_init must be called exactly once on any endpoint - * that uses transport::asio before it can be used. - * - * Calling init_asio shifts the internal state from UNINITIALIZED to READY - */ - void init_asio(io_service_ptr ptr) { - if (m_state != UNINITIALIZED) { - // TODO: throw invalid state - m_elog->write(log::elevel::library, + + /// initialize asio transport with external io_service + /** + * Initialize the ASIO transport policy for this endpoint using the + * io_service object. asio_init must be called exactly once on any endpoint + * that uses transport::asio before it can be used. + * + * Calling init_asio shifts the internal state from UNINITIALIZED to READY + */ + void init_asio(io_service_ptr ptr) { + if (m_state != UNINITIALIZED) { + // TODO: throw invalid state + m_elog->write(log::elevel::library, "asio::init_asio called from the wrong state"); - throw; - } - - m_alog->write(log::alevel::devel,"asio::init_asio"); - - m_io_service = ptr; + throw; + } + + m_alog->write(log::alevel::devel,"asio::init_asio"); + + m_io_service = ptr; m_external_io_service = true; - m_acceptor.reset(new boost::asio::ip::tcp::acceptor(*m_io_service)); - m_state = READY; - } - - /// Initialize asio transport with internal io_service - /** - * @see init_asio(io_service_ptr ptr) - */ - void init_asio() { - init_asio(new boost::asio::io_service()); + m_acceptor.reset(new boost::asio::ip::tcp::acceptor(*m_io_service)); + m_state = READY; + } + + /// Initialize asio transport with internal io_service + /** + * @see init_asio(io_service_ptr ptr) + */ + void init_asio() { + init_asio(new boost::asio::io_service()); m_external_io_service = false; - } - + } + /// Sets the tcp init handler /** * The tcp init handler is called after the tcp connection has been @@ -185,115 +185,115 @@ public: m_tcp_init_handler = h; } - // listen manually - void listen(const boost::asio::ip::tcp::endpoint& e) { - if (m_state != READY) { - // TODO + // listen manually + void listen(const boost::asio::ip::tcp::endpoint& e) { + if (m_state != READY) { + // TODO m_elog->write(log::elevel::library, "asio::listen called from the wrong state"); - throw; - } - - m_alog->write(log::alevel::devel,"asio::listen"); - - m_acceptor->open(e.protocol()); + throw; + } + + m_alog->write(log::alevel::devel,"asio::listen"); + + m_acceptor->open(e.protocol()); m_acceptor->set_option(boost::asio::socket_base::reuse_address(true)); m_acceptor->bind(e); m_acceptor->listen(); m_state = LISTENING; m_alog->write(log::alevel::devel,"mark"); - } - - void cancel() { - if (m_state != LISTENING) { - // TODO - throw; - } - - // TODO: figure out if this is a good way to stop listening. - m_acceptor->cancel(); - m_acceptor->close(); - } + } + + void cancel() { + if (m_state != LISTENING) { + // TODO + throw; + } + + // TODO: figure out if this is a good way to stop listening. + m_acceptor->cancel(); + m_acceptor->close(); + } - // Accept the next connection attempt via m_acceptor and assign it to con. - // callback is called - void async_accept(transport_con_ptr tcon, accept_handler callback) { - if (m_state != LISTENING) { - // TODO: throw invalid state + // Accept the next connection attempt via m_acceptor and assign it to con. + // callback is called + void async_accept(transport_con_ptr tcon, accept_handler callback) { + if (m_state != LISTENING) { + // TODO: throw invalid state m_elog->write(log::elevel::library, "asio::async_accept called from the wrong state"); - throw; - } - + throw; + } + m_alog->write(log::alevel::devel, "asio::async_accept"); - - // TEMP - m_acceptor->async_accept( - tcon->get_raw_socket(), - lib::bind( - &type::handle_accept, - this, - tcon->get_handle(), - callback, - lib::placeholders::_1 - ) - ); - } + + // TEMP + m_acceptor->async_accept( + tcon->get_raw_socket(), + lib::bind( + &type::handle_accept, + this, + tcon->get_handle(), + callback, + lib::placeholders::_1 + ) + ); + } - /// wraps the run method of the internal io_service object - std::size_t run() { - return m_io_service->run(); - } - - /// wraps the stop method of the internal io_service object - void stop() { - m_io_service->stop(); - } - - /// wraps the poll method of the internal io_service object - std::size_t poll() { - return m_io_service->poll(); - } - - /// wraps the poll_one method of the internal io_service object - std::size_t poll_one() { - return m_io_service->poll_one(); - } - - /// wraps the reset method of the internal io_service object - void reset() { - m_io_service->reset(); - } - - /// wraps the stopped method of the internal io_service object - bool stopped() const { - return m_io_service->stopped(); - } + /// wraps the run method of the internal io_service object + std::size_t run() { + return m_io_service->run(); + } + + /// wraps the stop method of the internal io_service object + void stop() { + m_io_service->stop(); + } + + /// wraps the poll method of the internal io_service object + std::size_t poll() { + return m_io_service->poll(); + } + + /// wraps the poll_one method of the internal io_service object + std::size_t poll_one() { + return m_io_service->poll_one(); + } + + /// wraps the reset method of the internal io_service object + void reset() { + m_io_service->reset(); + } + + /// wraps the stopped method of the internal io_service object + bool stopped() const { + return m_io_service->stopped(); + } - // convenience methods - template + // convenience methods + template void listen(const InternetProtocol &internet_protocol, uint16_t port) { boost::asio::ip::tcp::endpoint e(internet_protocol, port); listen(e); } - - void listen(uint16_t port) { - listen(boost::asio::ip::tcp::v6(), port); - } - - void listen(const std::string &host, const std::string &service) { - boost::asio::ip::tcp::resolver resolver(*m_io_service); - boost::asio::ip::tcp::resolver::query query(host, service); - boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); - boost::asio::ip::tcp::resolver::iterator end; - if (endpoint_iterator == end) { - throw std::invalid_argument("Can't resolve host/service to listen"); - } - listen(*endpoint_iterator); - } - - typedef lib::shared_ptr timer_ptr; + + void listen(uint16_t port) { + listen(boost::asio::ip::tcp::v6(), port); + } + + void listen(const std::string &host, const std::string &service) { + boost::asio::ip::tcp::resolver resolver(*m_io_service); + boost::asio::ip::tcp::resolver::query query(host, service); + boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + boost::asio::ip::tcp::resolver::iterator end; + if (endpoint_iterator == end) { + throw std::invalid_argument("Can't resolve host/service to listen"); + } + listen(*endpoint_iterator); + } + + typedef lib::shared_ptr timer_ptr; timer_ptr set_timer(long duration, timer_handler handler) { timer_ptr timer(new boost::asio::deadline_timer(*m_io_service)); @@ -318,7 +318,7 @@ public: } boost::asio::io_service& get_io_service() { - return *m_io_service; + return *m_io_service; } bool is_secure() const { @@ -340,22 +340,22 @@ protected: m_alog = a; } - void handle_accept(connection_hdl hdl, accept_handler callback, + void handle_accept(connection_hdl hdl, accept_handler callback, const boost::system::error_code& error) { - if (error) { - //con->terminate(); - // TODO: Better translation of errors at this point - callback(hdl,make_error_code(error::pass_through)); - return; - } - - //con->start(); - callback(hdl,lib::error_code()); - } - - /// Initiate a new connection - // TODO: there have to be some more failure conditions here + if (error) { + //con->terminate(); + // TODO: Better translation of errors at this point + callback(hdl,make_error_code(error::pass_through)); + return; + } + + //con->start(); + callback(hdl,lib::error_code()); + } + + /// Initiate a new connection + // TODO: there have to be some more failure conditions here void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb) { using namespace boost::asio::ip; @@ -409,18 +409,18 @@ protected: const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator iterator) { - if (ec) { - //con->terminate(); - // TODO: Better translation of errors at this point - std::stringstream s; + if (ec) { + //con->terminate(); + // TODO: Better translation of errors at this point + std::stringstream s; s << "asio async_resolve error::pass_through: " << "Original Error: " << ec << " (" << ec.message() << ")"; m_elog->write(log::elevel::info,s.str()); - callback(tcon->get_handle(),make_error_code(error::pass_through)); - return; - } - - boost::asio::async_connect( + callback(tcon->get_handle(),make_error_code(error::pass_through)); + return; + } + + boost::asio::async_connect( tcon->get_raw_socket(), iterator, lib::bind( @@ -428,35 +428,35 @@ protected: this, // shared from this? tcon, callback, - lib::placeholders::_1 + lib::placeholders::_1 ) ); - } + } void handle_connect(transport_con_ptr tcon, connect_handler callback, const boost::system::error_code& ec) { - if (ec) { - //con->terminate(); - // TODO: Better translation of errors at this point - std::stringstream s; + if (ec) { + //con->terminate(); + // TODO: Better translation of errors at this point + std::stringstream s; s << "asio async_connect error::pass_through: " << "Original Error: " << ec << " (" << ec.message() << ")"; m_elog->write(log::elevel::info,s.str()); - callback(tcon->get_handle(),make_error_code(error::pass_through)); - return; - } - - callback(tcon->get_handle(),lib::error_code()); - } - - bool is_listening() const { - return (m_state == LISTENING); - } - - /// Initialize a connection - /** - * init is called by an endpoint once for each newly created connection. + callback(tcon->get_handle(),make_error_code(error::pass_through)); + return; + } + + callback(tcon->get_handle(),lib::error_code()); + } + + bool is_listening() const { + return (m_state == LISTENING); + } + + /// 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. @@ -464,8 +464,8 @@ protected: * @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) { + */ + lib::error_code init(transport_con_ptr tcon) { m_alog->write(log::alevel::devel, "transport::asio::init"); // Initialize the connection socket component @@ -474,34 +474,34 @@ protected: lib::error_code ec; - ec = tcon->init_asio(m_io_service); - if (ec) {return ec;} - + ec = tcon->init_asio(m_io_service); + if (ec) {return ec;} + tcon->set_tcp_init_handler(m_tcp_init_handler); return lib::error_code(); - } + } private: - enum state { - UNINITIALIZED = 0, - READY = 1, - LISTENING = 2 - }; + enum state { + UNINITIALIZED = 0, + READY = 1, + LISTENING = 2 + }; // Handlers tcp_init_handler m_tcp_init_handler; - // Network Resources - io_service_ptr m_io_service; - bool m_external_io_service; - acceptor_ptr m_acceptor; - resolver_ptr m_resolver; - + // Network Resources + io_service_ptr m_io_service; + bool m_external_io_service; + acceptor_ptr m_acceptor; + resolver_ptr m_resolver; + elog_type* m_elog; alog_type* m_alog; - // Transport state - state m_state; + // Transport state + state m_state; }; } // namespace asio diff --git a/websocketpp/transport/base/connection.hpp b/websocketpp/transport/base/connection.hpp index a84064d5ad..9a508aca70 100644 --- a/websocketpp/transport/base/connection.hpp +++ b/websocketpp/transport/base/connection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -109,39 +109,39 @@ enum value { class category : public lib::error_category { public: - category() {} + category() {} - const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { - return "websocketpp.transport"; - } - - std::string message(int value) const { - switch(value) { - case general: - return "Generic transport policy error"; - case pass_through: - return "Underlying Transport Error"; - case invalid_num_bytes: - return "async_read_at_least call requested more bytes than buffer can store"; - case operation_aborted: - return "The operation was aborted"; - case operation_not_supported: - return "The operation is not supported by this transport"; - case eof: - return "End of File"; - default: - return "Unknown"; - } - } + const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { + return "websocketpp.transport"; + } + + std::string message(int value) const { + switch(value) { + case general: + return "Generic transport policy error"; + case pass_through: + return "Underlying Transport Error"; + case invalid_num_bytes: + return "async_read_at_least call requested more bytes than buffer can store"; + case operation_aborted: + return "The operation was aborted"; + case operation_not_supported: + return "The operation is not supported by this transport"; + case eof: + return "End of File"; + default: + return "Unknown"; + } + } }; inline const lib::error_category& get_category() { - static category instance; - return instance; + static category instance; + return instance; } inline lib::error_code make_error_code(error::value e) { - return lib::error_code(static_cast(e), get_category()); + return lib::error_code(static_cast(e), get_category()); } } // namespace error diff --git a/websocketpp/transport/iostream/base.hpp b/websocketpp/transport/iostream/base.hpp index 392a4455bd..6818de4121 100644 --- a/websocketpp/transport/iostream/base.hpp +++ b/websocketpp/transport/iostream/base.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Peter Thorson. All rights reserved. + * Copyright (c) 2013, 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: @@ -59,37 +59,37 @@ enum value { class category : public lib::error_category { public: - category() {} + category() {} - const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { - return "websocketpp.transport.iostream"; - } - - std::string message(int value) const { - switch(value) { - case general: - return "Generic iostream transport policy error"; - case invalid_num_bytes: - return "async_read_at_least call requested more bytes than buffer can store"; - case double_read: - return "Async read already in progress"; - case output_stream_required: - return "An output stream to be set before async_write can be used"; - case bad_stream: - return "A stream operation returned ios::bad"; - default: - return "Unknown"; - } - } + const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { + return "websocketpp.transport.iostream"; + } + + std::string message(int value) const { + switch(value) { + case general: + return "Generic iostream transport policy error"; + case invalid_num_bytes: + return "async_read_at_least call requested more bytes than buffer can store"; + case double_read: + return "Async read already in progress"; + case output_stream_required: + return "An output stream to be set before async_write can be used"; + case bad_stream: + return "A stream operation returned ios::bad"; + default: + return "Unknown"; + } + } }; inline const lib::error_category& get_category() { - static category instance; - return instance; + static category instance; + return instance; } inline lib::error_code make_error_code(error::value e) { - return lib::error_code(static_cast(e), get_category()); + return lib::error_code(static_cast(e), get_category()); } } // namespace error diff --git a/websocketpp/transport/iostream/connection.hpp b/websocketpp/transport/iostream/connection.hpp index 6bb94426dc..ed801e421c 100644 --- a/websocketpp/transport/iostream/connection.hpp +++ b/websocketpp/transport/iostream/connection.hpp @@ -46,10 +46,10 @@ template class connection { public: /// Type of this connection transport component - typedef connection type; + 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 @@ -58,227 +58,227 @@ public: 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; - - explicit connection(bool is_server, alog_type& alog, elog_type& elog) - : m_output_stream(NULL) - , m_reading(false) - , m_is_server(is_server) - , m_alog(alog) - , m_elog(elog) - { + typedef typename concurrency_type::scoped_lock_type scoped_lock_type; + typedef typename concurrency_type::mutex_type mutex_type; + + explicit connection(bool is_server, alog_type& alog, elog_type& elog) + : m_output_stream(NULL) + , m_reading(false) + , m_is_server(is_server) + , m_alog(alog) + , m_elog(elog) + { m_alog.write(log::alevel::devel,"iostream con transport constructor"); - } - - /// Register a std::ostream with the transport for writing output - /** - * Register a std::ostream with the transport. All future writes will be - * done to this output stream. - * - * @param o A pointer to the ostream to use for output. - */ - void register_ostream(std::ostream* o) { - // TODO: lock transport state? - scoped_lock_type lock(m_read_mutex); - m_output_stream = o; - } - - /// Overloaded stream input operator - /** - * Attempts to read input from the given stream into the transport. Bytes - * will be extracted from the input stream to fullfill any pending reads. - * Input in this manner will only read until the current read buffer has - * been filled. Then it will signal the library to process the input. If the - * library's input handler adds a new async_read, additional bytes will be - * read, otherwise the input operation will end. - * - * When this function returns one of the following conditions is true: - * - There is no outstanding read operation - * - There are no more bytes avaliable in the input stream - * - * You can use tellg() on the input stream to determine if all of the input - * bytes were read or not. - * - * If there is no pending read operation when the input method is called, it - * will return immediately and tellg() will not have changed. - */ - friend std::istream& operator>> (std::istream &in, type &t) { - // this serializes calls to external read. - scoped_lock_type lock(t.m_read_mutex); - - t.read(in); - - return in; - } - - /// Manual input supply - /** - * Copies bytes from buf into WebSocket++'s input buffers. Bytes will be - * copied from the supplied buffer to fullfull any pending library reads. It - * will return the number of bytes successfully processed. If there are no - * pending reads readsome will return immediately. Not all of the bytes may - * be able to be read in one call - */ - size_t readsome(const char *buf, size_t len) { - // this serializes calls to external read. - scoped_lock_type lock(m_read_mutex); - - return this->readsome_impl(buf,len); - } - - - /// Tests whether or not the underlying transport is secure - /** - * iostream transport will return false always because it has no information - * about the ultimate remote endpoint. This may or may not be accurate - * depending on the real source of bytes being input. - * - * TODO: allow user settable is_secure flag if this seems useful - * - * @return Whether or not the underlying transport is secure - */ - bool is_secure() const { - return false; - } - - /// Get the remote endpoint address - /** - * The iostream transport has no information about the ultimate remote - * endpoint. It will return the string "iostream transport". To indicate - * this. - * - * TODO: allow user settable remote endpoint addresses if this seems useful - * - * @return A string identifying the address of the remote endpoint - */ - std::string get_remote_endpoint() const { - return "iostream transport"; - } - - /// Get the connection handle + } + + /// Register a std::ostream with the transport for writing output + /** + * Register a std::ostream with the transport. All future writes will be + * done to this output stream. + * + * @param o A pointer to the ostream to use for output. + */ + void register_ostream(std::ostream* o) { + // TODO: lock transport state? + scoped_lock_type lock(m_read_mutex); + m_output_stream = o; + } + + /// Overloaded stream input operator + /** + * Attempts to read input from the given stream into the transport. Bytes + * will be extracted from the input stream to fullfill any pending reads. + * Input in this manner will only read until the current read buffer has + * been filled. Then it will signal the library to process the input. If the + * library's input handler adds a new async_read, additional bytes will be + * read, otherwise the input operation will end. + * + * When this function returns one of the following conditions is true: + * - There is no outstanding read operation + * - There are no more bytes avaliable in the input stream + * + * You can use tellg() on the input stream to determine if all of the input + * bytes were read or not. + * + * If there is no pending read operation when the input method is called, it + * will return immediately and tellg() will not have changed. + */ + friend std::istream& operator>> (std::istream &in, type &t) { + // this serializes calls to external read. + scoped_lock_type lock(t.m_read_mutex); + + t.read(in); + + return in; + } + + /// Manual input supply + /** + * Copies bytes from buf into WebSocket++'s input buffers. Bytes will be + * copied from the supplied buffer to fullfull any pending library reads. It + * will return the number of bytes successfully processed. If there are no + * pending reads readsome will return immediately. Not all of the bytes may + * be able to be read in one call + */ + size_t readsome(const char *buf, size_t len) { + // this serializes calls to external read. + scoped_lock_type lock(m_read_mutex); + + return this->readsome_impl(buf,len); + } + + + /// Tests whether or not the underlying transport is secure + /** + * iostream transport will return false always because it has no information + * about the ultimate remote endpoint. This may or may not be accurate + * depending on the real source of bytes being input. + * + * TODO: allow user settable is_secure flag if this seems useful + * + * @return Whether or not the underlying transport is secure + */ + bool is_secure() const { + return false; + } + + /// Get the remote endpoint address + /** + * The iostream transport has no information about the ultimate remote + * endpoint. It will return the string "iostream transport". To indicate + * this. + * + * TODO: allow user settable remote endpoint addresses if this seems useful + * + * @return A string identifying the address of the remote endpoint + */ + std::string get_remote_endpoint() const { + return "iostream transport"; + } + + /// Get the connection handle connection_hdl get_handle() const { return m_connection_hdl; } protected: - void init(init_handler callback) { + void init(init_handler callback) { m_alog.write(log::alevel::devel,"iostream connection init"); - callback(lib::error_code()); - } - - /// 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) - { + callback(lib::error_code()); + } + + /// 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) + { std::stringstream s; s << "iostream_con async_read_at_least: " << num_bytes; m_alog.write(log::alevel::devel,s.str()); - - if (num_bytes > len) { - handler(make_error_code(error::invalid_num_bytes),size_t(0)); - return; - } - - if (m_reading == true) { - handler(make_error_code(error::double_read),size_t(0)); - return; - } - - if (num_bytes == 0 || len == 0) { - handler(lib::error_code(),size_t(0)); - return; - } - - m_buf = buf; - m_len = len; - m_bytes_needed = num_bytes; - m_read_handler = handler; - m_cursor = 0; - m_reading = true; - } - - /// 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. Other possible errors (not exhaustive) - * output_stream_required: No output stream was registered to write to - * bad_stream: a ostream pass through error - * - * @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(const char* buf, size_t len, write_handler handler) { + + if (num_bytes > len) { + handler(make_error_code(error::invalid_num_bytes),size_t(0)); + return; + } + + if (m_reading == true) { + handler(make_error_code(error::double_read),size_t(0)); + return; + } + + if (num_bytes == 0 || len == 0) { + handler(lib::error_code(),size_t(0)); + return; + } + + m_buf = buf; + m_len = len; + m_bytes_needed = num_bytes; + m_read_handler = handler; + m_cursor = 0; + m_reading = true; + } + + /// 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. Other possible errors (not exhaustive) + * output_stream_required: No output stream was registered to write to + * bad_stream: a ostream pass through error + * + * @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(const char* buf, size_t len, write_handler handler) { m_alog.write(log::alevel::devel,"iostream_con async_write"); - // TODO: lock transport state? - - if (!m_output_stream) { - handler(make_error_code(error::output_stream_required)); - return; - } - - m_output_stream->write(buf,len); - - if (m_output_stream->bad()) { - handler(make_error_code(error::bad_stream)); - } else { - handler(lib::error_code()); - } - } - + // TODO: lock transport state? + + if (!m_output_stream) { + handler(make_error_code(error::output_stream_required)); + return; + } + + m_output_stream->write(buf,len); + + if (m_output_stream->bad()) { + handler(make_error_code(error::bad_stream)); + } else { + handler(lib::error_code()); + } + } + /// 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. Other possible errors (not exhaustive) - * output_stream_required: No output stream was registered to write to - * bad_stream: a ostream pass through error - * - * @param bufs vector of buffers to write - * @param handler Callback to invoke with operation status. - */ + /** + * 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. Other possible errors (not exhaustive) + * output_stream_required: No output stream was registered to write to + * bad_stream: a ostream pass through error + * + * @param bufs vector of buffers to write + * @param handler Callback to invoke with operation status. + */ void async_write(const std::vector& bufs, write_handler handler) { m_alog.write(log::alevel::devel,"iostream_con async_write buffer list"); - // TODO: lock transport state? - - if (!m_output_stream) { - handler(make_error_code(error::output_stream_required)); - return; - } + // TODO: lock transport state? + + if (!m_output_stream) { + handler(make_error_code(error::output_stream_required)); + return; + } std::vector::const_iterator it; - for (it = bufs.begin(); it != bufs.end(); it++) { + for (it = bufs.begin(); it != bufs.end(); it++) { m_output_stream->write((*it).buf,(*it).len); if (m_output_stream->bad()) { @@ -317,10 +317,10 @@ protected: // TODO: } private: - void read(std::istream &in) { + void read(std::istream &in) { m_alog.write(log::alevel::devel,"iostream_con read"); - - while (in.good()) { + + while (in.good()) { if (!m_reading) { m_elog.write(log::elevel::devel,"write while not reading"); break; @@ -346,12 +346,12 @@ private: m_read_handler(lib::error_code(), m_cursor); } } - } - - size_t readsome_impl(const char * buf, size_t len) { - m_alog.write(log::alevel::devel,"iostream_con readsome"); - - if (!m_reading) { + } + + size_t readsome_impl(const char * buf, size_t len) { + m_alog.write(log::alevel::devel,"iostream_con readsome"); + + if (!m_reading) { m_elog.write(log::elevel::devel,"write while not reading"); return 0; } @@ -368,30 +368,30 @@ private: } return bytes_to_copy; - } - - // Read space (Protected by m_read_mutex) - char* m_buf; - size_t m_len; - size_t m_bytes_needed; - read_handler m_read_handler; - size_t m_cursor; - - // transport resources - std::ostream* m_output_stream; + } + + // Read space (Protected by m_read_mutex) + char* m_buf; + size_t m_len; + size_t m_bytes_needed; + read_handler m_read_handler; + size_t m_cursor; + + // transport resources + std::ostream* m_output_stream; connection_hdl m_connection_hdl; - - bool m_reading; - const bool m_is_server; + + bool m_reading; + const bool m_is_server; alog_type& m_alog; elog_type& m_elog; - // This lock ensures that only one thread can edit read data for this - // connection. This is a very coarse lock that is basically locked all the - // time. The nature of the connection is such that it cannot be - // parallelized, the locking is here to prevent intra-connection concurrency - // in order to allow inter-connection concurrency. - mutex_type m_read_mutex; + // This lock ensures that only one thread can edit read data for this + // connection. This is a very coarse lock that is basically locked all the + // time. The nature of the connection is such that it cannot be + // parallelized, the locking is here to prevent intra-connection concurrency + // in order to allow inter-connection concurrency. + mutex_type m_read_mutex; }; diff --git a/websocketpp/transport/iostream/endpoint.hpp b/websocketpp/transport/iostream/endpoint.hpp index dfaf82f20c..fd80aae671 100644 --- a/websocketpp/transport/iostream/endpoint.hpp +++ b/websocketpp/transport/iostream/endpoint.hpp @@ -57,35 +57,35 @@ public: /// Type of this endpoint transport component's associated connection /// transport component. - typedef iostream::connection transport_con_type; + 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() : m_output_stream(NULL) - { - //std::cout << "transport::iostream::endpoint constructor" << std::endl; - } - - void register_ostream(std::ostream* o) { + // generate and manage our own io_service + explicit endpoint() : m_output_stream(NULL) + { + //std::cout << "transport::iostream::endpoint constructor" << std::endl; + } + + void register_ostream(std::ostream* o) { m_alog->write(log::alevel::devel,"register_ostream"); - m_output_stream = o; - } - - /// Tests whether or not the underlying transport is secure - /** - * iostream transport will return false always because it has no information - * about the ultimate remote endpoint. This may or may not be accurate - * depending on the real source of bytes being input. - * - * TODO: allow user settable is_secure flag if this seems useful - * - * @return Whether or not the underlying transport is secure - */ - bool is_secure() const { - return false; - } + m_output_stream = o; + } + + /// Tests whether or not the underlying transport is secure + /** + * iostream transport will return false always because it has no information + * about the ultimate remote endpoint. This may or may not be accurate + * depending on the real source of bytes being input. + * + * TODO: allow user settable is_secure flag if this seems useful + * + * @return Whether or not the underlying transport is secure + */ + bool is_secure() const { + return false; + } protected: /// Initialize logging /** @@ -119,12 +119,12 @@ protected: * * @return A status code indicating the success or failure of the operation */ - lib::error_code init(transport_con_ptr tcon) { - tcon->register_ostream(m_output_stream); - return lib::error_code(); - } + lib::error_code init(transport_con_ptr tcon) { + tcon->register_ostream(m_output_stream); + return lib::error_code(); + } private: - std::ostream* m_output_stream; + std::ostream* m_output_stream; elog_type* m_elog; alog_type* m_alog; }; diff --git a/websocketpp/utilities.hpp b/websocketpp/utilities.hpp index 991ab3dcce..bdc2a43fdb 100644 --- a/websocketpp/utilities.hpp +++ b/websocketpp/utilities.hpp @@ -51,7 +51,7 @@ private: // find substring (case insensitive) template typename T::const_iterator ci_find_substr( const T& str1, const T& str2, - const std::locale& loc = std::locale() ) + const std::locale& loc = std::locale() ) { return std::search( str1.begin(), str1.end(), str2.begin(), str2.end(), my_equal(loc) ); @@ -59,8 +59,8 @@ typename T::const_iterator ci_find_substr( const T& str1, const T& str2, template typename T::const_iterator ci_find_substr(const T& str1, - const typename T::value_type* str2, typename T::size_type size, - const std::locale& loc = std::locale()) + const typename T::value_type* str2, typename T::size_type size, + const std::locale& loc = std::locale()) { return std::search( str1.begin(), str1.end(), str2, str2+size, my_equal(loc) );