Add maximum message size functionality to processors

This commit is contained in:
Peter Thorson
2014-02-10 08:38:54 -06:00
parent d9aa498310
commit ba6320ba1c
9 changed files with 109 additions and 2 deletions

View File

@@ -45,6 +45,8 @@ struct stub_config {
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type;
static const size_t max_message_size = 16000000;
};
struct processor_setup {

View File

@@ -50,6 +50,8 @@ struct stub_config {
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
static const size_t max_message_size = 16000000;
/// Extension related config
static const bool enable_extensions = false;

View File

@@ -50,6 +50,8 @@ struct stub_config {
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
static const size_t max_message_size = 16000000;
/// Extension related config
static const bool enable_extensions = false;

View File

@@ -60,6 +60,7 @@ struct stub_config {
typedef websocketpp::extensions::permessage_deflate::disabled
<permessage_deflate_config> permessage_deflate_type;
static const size_t max_message_size = 16000000;
static const bool enable_extensions = false;
};
@@ -81,6 +82,7 @@ struct stub_config_ext {
typedef websocketpp::extensions::permessage_deflate::enabled
<permessage_deflate_config> permessage_deflate_type;
static const size_t max_message_size = 16000000;
static const bool enable_extensions = true;
};
@@ -489,6 +491,36 @@ BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
}
BOOST_AUTO_TEST_CASE( single_frame_message_too_large ) {
processor_setup env(true);
env.p.set_max_message_size(3);
uint8_t frame0[10] = {0x82, 0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01};
// read message that is one byte too large
BOOST_CHECK_EQUAL( env.p.consume(frame0,10,env.ec), 6 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
}
BOOST_AUTO_TEST_CASE( multiple_frame_message_too_large ) {
processor_setup env(true);
env.p.set_max_message_size(4);
uint8_t frame0[8] = {0x02, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
uint8_t frame1[9] = {0x80, 0x83, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
// read first message frame with size under the limit
BOOST_CHECK_EQUAL( env.p.consume(frame0,8,env.ec), 8 );
BOOST_CHECK( !env.ec );
// read second message frame that puts the size over the limit
BOOST_CHECK_EQUAL( env.p.consume(frame1,9,env.ec), 6 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
}
BOOST_AUTO_TEST_CASE( client_handshake_request ) {
processor_setup env(false);

View File

@@ -132,4 +132,4 @@ BOOST_AUTO_TEST_CASE( version_non_numeric ) {
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == -1);
}
}

View File

@@ -215,6 +215,18 @@ struct core {
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.4.0-alpha1
*/
static const size_t max_message_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;

View File

@@ -216,6 +216,18 @@ struct core_client {
*/
static const bool silent_close = false;
/// Default maximum message size
/**
* Default value for the processor's maximum message size. Maximum message size
* determines the point at which the library will fail a connection with the
* message_too_big protocol error.
*
* The default is 32MB
*
* @since 0.4.0-alpha1
*/
static const size_t max_message_size = 32000000;
/// Global flag for enabling/disabling extensions
static const bool enable_extensions = true;

View File

@@ -369,11 +369,25 @@ public:
m_current_msg = &m_control_msg;
} else {
if (!m_data_msg.msg_ptr) {
if (m_bytes_needed > base::m_max_message_size) {
ec = make_error_code(error::message_too_big);
break;
}
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 {
// Fetch the underlying payload buffer from the data message we
// are writing into.
std::string & out = m_data_msg.msg_ptr->get_raw_payload();
if (out.size() + m_bytes_needed > base::m_max_message_size) {
ec = make_error_code(error::message_too_big);
break;
}
// Each frame starts a new masking key. All other state
// remains between frames.
m_data_msg.prepared_key = prepare_masking_key(

View File

@@ -161,13 +161,43 @@ public:
explicit processor(bool secure, bool p_is_server)
: m_secure(secure)
, m_server(p_is_server) {}
, m_server(p_is_server)
, m_max_message_size(config::max_message_size)
{}
virtual ~processor() {}
/// Get the protocol version of this processor
virtual int get_version() const = 0;
/// Get maximum message size
/**
* Get maximum message size. Maximum message size determines the point at which the
* processor will fail a connection with the message_too_big protocol error.
*
* The default is retrieved from the max_message_size value from the template config
*
* @since 0.4.0-alpha1
*/
size_t get_max_message_size() const {
return m_max_message_size;
}
/// Set maximum message size
/**
* Set maximum message size. Maximum message size determines the point at which the
* processor will fail a connection with the message_too_big protocol error.
*
* The default is retrieved from the max_message_size value from the template config
*
* @since 0.4.0-alpha1
*
* @param new_value The value to set as the maximum message size.
*/
void set_max_message_size(size_t new_value) {
m_max_message_size = new_value;
}
/// Returns whether or not the permessage_compress extension is implemented
/**
* Compile time flag that indicates whether this processor has implemented
@@ -358,6 +388,7 @@ public:
protected:
bool const m_secure;
bool const m_server;
size_t m_max_message_size;
};
} // namespace processor