From c937f71b493a6c1efedfc4968129fd1458908957 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Thu, 4 Apr 2013 08:18:39 -0500 Subject: [PATCH] changes extension permessage-compress to permessage-deflate per latest draft spec --- .../extension_permessage_compress.cpp | 12 +-- test/processors/hybi07.cpp | 8 +- test/processors/hybi08.cpp | 10 +-- test/processors/hybi13.cpp | 86 ++++++++++++++++--- websocketpp/config/core.hpp | 14 +-- websocketpp/config/core_client.hpp | 10 +-- websocketpp/extensions/extension.hpp | 2 +- .../disabled.hpp | 22 ++--- .../enabled.hpp | 65 ++++++++++---- websocketpp/processors/hybi13.hpp | 19 ++-- 10 files changed, 171 insertions(+), 77 deletions(-) rename websocketpp/extensions/{permessage_compress => permessage_deflate}/disabled.hpp (81%) rename websocketpp/extensions/{permessage_compress => permessage_deflate}/enabled.hpp (90%) diff --git a/test/processors/extension_permessage_compress.cpp b/test/processors/extension_permessage_compress.cpp index 8321871821..d8e23f62aa 100644 --- a/test/processors/extension_permessage_compress.cpp +++ b/test/processors/extension_permessage_compress.cpp @@ -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: @@ -25,7 +25,7 @@ * */ //#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE extension_permessage_compress +#define BOOST_TEST_MODULE extension_permessage_deflate #include #include @@ -33,25 +33,25 @@ #include #include -#include +#include struct config { typedef websocketpp::http::parser::request request_type; }; -typedef websocketpp::extensions::permessage_compress::enabled +typedef websocketpp::extensions::permessage_deflate::enabled compressor_type; using namespace websocketpp; BOOST_AUTO_TEST_CASE( deflate_init ) { - compressor_type compressor; + /*compressor_type compressor; websocketpp::http::parser::attribute_list attributes; std::pair neg_ret; neg_ret = compressor.negotiate(attributes); BOOST_CHECK_EQUAL( neg_ret.first, - extensions::permessage_compress::error::invalid_parameters ); + extensions::permessage_deflate::error::invalid_parameters );*/ /** * Window size is primarily controlled by the writer. A stream can only be diff --git a/test/processors/hybi07.cpp b/test/processors/hybi07.cpp index f07042d3a1..02310400d6 100644 --- a/test/processors/hybi07.cpp +++ b/test/processors/hybi07.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include struct stub_config { @@ -56,12 +56,12 @@ struct stub_config { /// Extension specific config /// permessage_compress_config - struct permessage_compress_config { + struct permessage_deflate_config { typedef stub_config::request_type request_type; }; - typedef websocketpp::extensions::permessage_compress::disabled - permessage_compress_type; + typedef websocketpp::extensions::permessage_deflate::disabled + permessage_deflate_type; }; BOOST_AUTO_TEST_CASE( exact_match ) { diff --git a/test/processors/hybi08.cpp b/test/processors/hybi08.cpp index 60336b903d..df3b16d39e 100644 --- a/test/processors/hybi08.cpp +++ b/test/processors/hybi08.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include struct stub_config { @@ -55,13 +55,13 @@ struct stub_config { /// Extension specific config - /// permessage_compress_config - struct permessage_compress_config { + /// permessage_deflate_config + struct permessage_deflate_config { typedef stub_config::request_type request_type; }; - typedef websocketpp::extensions::permessage_compress::disabled - permessage_compress_type; + typedef websocketpp::extensions::permessage_deflate::disabled + permessage_deflate_type; }; BOOST_AUTO_TEST_CASE( exact_match ) { diff --git a/test/processors/hybi13.cpp b/test/processors/hybi13.cpp index 85104f2f11..e97a86707f 100644 --- a/test/processors/hybi13.cpp +++ b/test/processors/hybi13.cpp @@ -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,8 +39,8 @@ #include #include -#include -#include +#include +#include struct stub_config { typedef websocketpp::http::parser::request request_type; @@ -53,12 +53,12 @@ struct stub_config { typedef websocketpp::random::none::int_generator rng_type; - struct permessage_compress_config { + struct permessage_deflate_config { typedef stub_config::request_type request_type; }; - typedef websocketpp::extensions::permessage_compress::disabled - permessage_compress_type; + typedef websocketpp::extensions::permessage_deflate::disabled + permessage_deflate_type; static const bool enable_extensions = false; }; @@ -74,14 +74,14 @@ struct stub_config_ext { typedef websocketpp::random::none::int_generator rng_type; - struct permessage_compress_config { + struct permessage_deflate_config { typedef stub_config_ext::request_type request_type; }; - typedef websocketpp::extensions::permessage_compress::enabled - permessage_compress_type; + typedef websocketpp::extensions::permessage_deflate::enabled + permessage_deflate_type; - static const bool enable_extensions = false; + static const bool enable_extensions = true; }; typedef stub_config::con_msg_manager_type con_msg_manager_type; @@ -102,6 +102,19 @@ struct processor_setup { websocketpp::processor::hybi13 p; }; +struct processor_setup_ext { + processor_setup_ext(bool server) + : msg_manager(new con_msg_manager_type()) + , p(false,server,msg_manager,rng) {} + + websocketpp::lib::error_code ec; + con_msg_manager_type::ptr msg_manager; + stub_config::rng_type rng; + stub_config::request_type req; + stub_config::response_type res; + websocketpp::processor::hybi13 p; +}; + BOOST_AUTO_TEST_CASE( exact_match ) { processor_setup env(true); @@ -554,4 +567,55 @@ BOOST_AUTO_TEST_CASE( client_handshake_response ) { env.res.consume(res.data(),res.size()); BOOST_CHECK( !env.p.validate_server_handshake_response(env.req,env.res) ); -} \ No newline at end of file +} + +BOOST_AUTO_TEST_CASE( extensions_disabled ) { + processor_setup env(true); + + env.req.replace_header("Sec-WebSocket-Extensions",""); + + std::pair neg_results; + neg_results = env.p.negotiate_extensions(env.req); + + BOOST_CHECK_EQUAL( neg_results.first, websocketpp::processor::error::extensions_disabled ); + BOOST_CHECK_EQUAL( neg_results.second, "" ); +} + +BOOST_AUTO_TEST_CASE( extension_negotiation_blank ) { + processor_setup_ext env(true); + + env.req.replace_header("Sec-WebSocket-Extensions",""); + + std::pair neg_results; + neg_results = env.p.negotiate_extensions(env.req); + + BOOST_CHECK( !neg_results.first ); + BOOST_CHECK_EQUAL( neg_results.second, "" ); +} + +BOOST_AUTO_TEST_CASE( extension_negotiation_unknown ) { + processor_setup_ext env(true); + + env.req.replace_header("Sec-WebSocket-Extensions","foo"); + + std::pair neg_results; + neg_results = env.p.negotiate_extensions(env.req); + + BOOST_CHECK( !neg_results.first ); + BOOST_CHECK_EQUAL( neg_results.second, "" ); +} + +/*BOOST_AUTO_TEST_CASE( extension_negotiation_permessage_deflate ) { + processor_setup_ext env(true); + + env.req.replace_header("Sec-WebSocket-Extensions","permessage-deflate; foo; bar=\"x x\""); + + std::pair neg_results; + neg_results = env.p.negotiate_extensions(env.req); + + std::cout << neg_results.first.message() << neg_results.second << std::endl; + + BOOST_CHECK( !neg_results.first ); + BOOST_CHECK_EQUAL( neg_results.second, "permessage-deflate" ); +}*/ + diff --git a/websocketpp/config/core.hpp b/websocketpp/config/core.hpp index 9fea55fbbb..adab8992db 100644 --- a/websocketpp/config/core.hpp +++ b/websocketpp/config/core.hpp @@ -59,7 +59,7 @@ #include // Extensions -#include +#include namespace websocketpp { namespace config { @@ -145,7 +145,7 @@ struct core { /// Extension specific settings: /// permessage_compress extension - struct permessage_compress_config { + struct permessage_deflate_config { typedef core::request_type request_type; /// If the remote endpoint requests that we reset the compression @@ -160,14 +160,14 @@ struct core { static const uint8_t minimum_outgoing_window_bits = 8; }; - typedef websocketpp::extensions::permessage_compress::disabled - permessage_compress_type; + typedef websocketpp::extensions::permessage_deflate::disabled + permessage_deflate_type; - /// Autonegotiate permessage-compress + /// Autonegotiate permessage-deflate /** - * Automatically enables the permessage-compress extension. + * Automatically enables the permessage-deflate extension. * - * For clients this results in a permessage-compress extension request being + * For clients this results in a permessage-deflate extension request being * sent with every request rather than requiring it to be requested manually * * For servers this results in accepting the first set of extension settings diff --git a/websocketpp/config/core_client.hpp b/websocketpp/config/core_client.hpp index 222eb35952..8cb0981ddb 100644 --- a/websocketpp/config/core_client.hpp +++ b/websocketpp/config/core_client.hpp @@ -57,7 +57,7 @@ #include // Extensions -#include +#include namespace websocketpp { namespace config { @@ -143,8 +143,8 @@ struct core_client { /// Extension specific settings: - /// permessage_compress extension - struct permessage_compress_config { + /// permessage_deflate extension + struct permessage_deflate_config { typedef core_client::request_type request_type; /// If the remote endpoint requests that we reset the compression @@ -159,8 +159,8 @@ struct core_client { static const uint8_t minimum_outgoing_window_bits = 8; }; - typedef websocketpp::extensions::permessage_compress::disabled - permessage_compress_type; + typedef websocketpp::extensions::permessage_deflate::disabled + permessage_deflate_type; /// Autonegotiate permessage-compress /** diff --git a/websocketpp/extensions/extension.hpp b/websocketpp/extensions/extension.hpp index 7e2c020bd0..4b89a9ed80 100644 --- a/websocketpp/extensions/extension.hpp +++ b/websocketpp/extensions/extension.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/extensions/permessage_compress/disabled.hpp b/websocketpp/extensions/permessage_deflate/disabled.hpp similarity index 81% rename from websocketpp/extensions/permessage_compress/disabled.hpp rename to websocketpp/extensions/permessage_deflate/disabled.hpp index fb59aa4ba9..b9ad025f38 100644 --- a/websocketpp/extensions/permessage_compress/disabled.hpp +++ b/websocketpp/extensions/permessage_deflate/disabled.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: @@ -25,8 +25,8 @@ * */ -#ifndef WEBSOCKETPP_EXTENSION_PERMESSAGE_COMPRESS_DISABLED_HPP -#define WEBSOCKETPP_EXTENSION_PERMESSAGE_COMPRESS_DISABLED_HPP +#ifndef WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP +#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP #include #include @@ -39,12 +39,12 @@ namespace websocketpp { namespace extensions { -namespace permessage_compress { +namespace permessage_deflate { -/// Stub class for use when disabling permessage_compress extension +/// Stub class for use when disabling permessage_deflate extension /** - * This class is a stub that impliments the permessage_compress interface - * with minimal dependencies. It is used to disable permessage_compress + * This class is a stub that impliments the permessage_deflate interface + * with minimal dependencies. It is used to disable permessage_deflate * functionality at compile time without loading any unnecessary code. */ template @@ -58,12 +58,12 @@ public: } /// Returns true if the extension is capable of providing - /// permessage_compress functionality + /// permessage_deflate functionality bool is_implimented() const { return false; } - /// Returns true if permessage_compress functionality is active for this + /// Returns true if permessage_deflate functionality is active for this /// connection bool is_enabled() const { return false; @@ -84,8 +84,8 @@ public: } }; -} // namespace permessage_compress +} // namespace permessage_deflate } // namespace extensions } // namespace websocketpp -#endif // WEBSOCKETPP_EXTENSION_PERMESSAGE_COMPRESS_DISABLED_HPP +#endif // WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP diff --git a/websocketpp/extensions/permessage_compress/enabled.hpp b/websocketpp/extensions/permessage_deflate/enabled.hpp similarity index 90% rename from websocketpp/extensions/permessage_compress/enabled.hpp rename to websocketpp/extensions/permessage_deflate/enabled.hpp index 386085b6fa..937a81963d 100644 --- a/websocketpp/extensions/permessage_compress/enabled.hpp +++ b/websocketpp/extensions/permessage_deflate/enabled.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: @@ -25,8 +25,8 @@ * */ -#ifndef WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGECOMPRESS_HPP -#define WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGECOMPRESS_HPP +#ifndef WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP +#define WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP #include #include @@ -41,7 +41,7 @@ namespace websocketpp { namespace extensions { -namespace permessage_compress { +namespace permessage_deflate { namespace error { enum value { @@ -72,7 +72,7 @@ public: category() {} const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { - return "websocketpp.extension.permessage-compress"; + return "websocketpp.extension.permessage-deflate"; } std::string message(int value) const { @@ -107,20 +107,20 @@ lib::error_code make_error_code(error::value e) { } } // namespace error -} // namespace permessage_compress +} // namespace permessage_deflate } // namespace extensions } // namespace websocketpp _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ template<> struct is_error_code_enum - + { static const bool value = true; }; _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ namespace websocketpp { namespace extensions { -namespace permessage_compress { +namespace permessage_deflate { template class method { @@ -404,7 +404,7 @@ private: z_stream m_istate; // inflate state }; -/// Impliments the permessage_compress extension interface +/// Impliments the permessage_deflate extension interface /** * * Template parameter econfig defines compile time types, constants, and @@ -422,7 +422,7 @@ private: * * * Methods: - * permessage_compress::enabled does not define or impliment any methods + * permessage_deflate::enabled does not define or impliment any methods * itself. It uses the attribute list to determine * * @@ -431,6 +431,8 @@ private: */ template class enabled { + typedef std::map string_map; + typedef typename econfig::request_type::attribute_list attribute_list; typedef typename attribute_list::const_iterator attribute_iterator; typedef lib::shared_ptr< method > method_ptr; @@ -442,7 +444,7 @@ class enabled { public: enabled() : m_enabled(false) {} - /// Attempt to negotiate the permessage_compress extension + /// Attempt to negotiate the permessage_deflate extension /** * Parses the attribute list for this extension and attempts to negotiate * the extension. Returns a pair. On success @@ -450,14 +452,41 @@ public: * to return in the handshake response. On error * * @param attributes A list of attributes extracted from the - * 'permessage_compress' extension parameter from the original handshake. + * 'permessage_deflate' extension parameter from the original handshake. * * @return A pair containing a status code * and a value whose interpretation is dependent on the status code. */ - err_str_pair negotiate(const attribute_list& attributes) { + err_str_pair negotiate(const string_map& attributes) { err_str_pair ret; + std::cout << "foo: " << attributes.size() << std::endl; + + string_map::const_iterator it; + + for (it = attributes.begin(); it != attributes.end(); ++it) { + std::cout << it->first << ": " << it->second << std::endl; + } + + // start by not accepting any parameters + if (attributes.size() == 0) { + ret.second = "permessage-deflate"; + } else { + ret.first = make_error_code(error::invalid_parameters); + } + + /* + * + * Sec-WebSocket-Extensions: foo; bar; baz=5, foo2; bar2; baz2=5 + * + * map> + * + * vector>>> + * + */ + + + /* // Exactly one parameter is required if (attributes.size() != 1) { ret.first = make_error_code(error::invalid_parameters); @@ -500,17 +529,17 @@ public: } } - m_enabled = true; + m_enabled = true;*/ return ret; } - /// Returns true if this object impliments permessage_compress functionality + /// Returns true if this object impliments permessage_deflate functionality bool is_implimented() const { return true; } /// returns true if this object is initialized and ready to provide - /// permessage_compress functionality. + /// permessage_deflate functionality. bool is_enabled() const { return m_enabled; } @@ -542,8 +571,8 @@ private: method_ptr m_method; }; -} // namespace permessage_compress +} // namespace permessage_deflate } // namespace extensions } // namespace websocketpp -#endif // WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGECOMPRESS_HPP +#endif // WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP diff --git a/websocketpp/processors/hybi13.hpp b/websocketpp/processors/hybi13.hpp index 7bedcf5156..91a5604a15 100644 --- a/websocketpp/processors/hybi13.hpp +++ b/websocketpp/processors/hybi13.hpp @@ -69,7 +69,7 @@ public: typedef typename msg_manager_type::ptr msg_manager_ptr; typedef typename config::rng_type rng_type; - typedef typename config::permessage_compress_type permessage_compress_type; + typedef typename config::permessage_deflate_type permessage_deflate_type; typedef std::pair err_str_pair; @@ -86,8 +86,8 @@ public: return 13; } - bool has_permessage_compress() const { - return m_permessage_compress.is_implimented(); + bool has_permessage_deflate() const { + return m_permessage_deflate.is_implimented(); } err_str_pair negotiate_extensions(const request_type& req) { @@ -123,6 +123,7 @@ public: if (it->first == "permessage-deflate") { std::cout << "mark3: " << std::endl; neg_ret = m_permessage_deflate.negotiate(it->second); + std::cout << neg_ret.first.message() << " - " << neg_ret.second << std::endl; if (neg_ret.first) { @@ -509,7 +510,7 @@ public: frame::masking_key_type key; bool masked = !base::m_server; - bool compressed = m_permessage_compress.is_enabled() + bool compressed = m_permessage_deflate.is_enabled() && in->get_compressed(); bool fin = in->get_fin(); @@ -530,7 +531,7 @@ public: // prepare payload if (compressed) { // compress and store in o after header. - m_permessage_compress.compress(i,o); + m_permessage_deflate.compress(i,o); // mask in place if necessary if (masked) { @@ -700,11 +701,11 @@ protected: size_t offset = out.size(); // decompress message if needed. - if (m_permessage_compress.is_enabled() + if (m_permessage_deflate.is_enabled() && frame::get_rsv1(m_basic_header)) { // Decompress current buffer into the message buffer - m_permessage_compress.decompress(buf,len,out); + m_permessage_deflate.decompress(buf,len,out); // get the length of the newly uncompressed output offset = out.size() - offset; @@ -762,7 +763,7 @@ protected: // a control message. // // TODO: unit tests for this - if (frame::get_rsv1(h) && (!m_permessage_compress.is_enabled() + if (frame::get_rsv1(h) && (!m_permessage_deflate.is_enabled() || frame::opcode::is_control(op))) { return make_error_code(error::invalid_rsv_bit); @@ -979,7 +980,7 @@ protected: state m_state; // Extensions - permessage_compress_type m_permessage_compress; + permessage_deflate_type m_permessage_deflate; }; } // namespace processor