Skip to content

Commit

Permalink
Merge pull request XRPLF#322 from zaphoyd/max-message-size
Browse files Browse the repository at this point in the history
Adds the ability to specify a max message size
  • Loading branch information
zaphoyd committed Feb 11, 2014
2 parents 47c46a2 + 1622cdd commit 724974c
Show file tree
Hide file tree
Showing 16 changed files with 266 additions and 52 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ HEAD
the main thread.
- Feature: Adds the ability to specify whether or not to use the `SO_REUSEADDR` TCP socket
option. The default for this value has been changed from `true` to `false`.
- Feature: Adds the ability to specify a maximum message size.
- Improvement: Open, close, and pong timeouts can be disabled entirely by setting their
duration to 0.
- Improvement: Numerous performance improvements. Including: tuned default
Expand Down
27 changes: 27 additions & 0 deletions test/connection/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,33 @@ BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
BOOST_CHECK_EQUAL(ref, output.str());
}

BOOST_AUTO_TEST_CASE( set_max_message_size ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";

// After the handshake, add a single frame with a message that is too long.
char frame0[10] = {char(0x82), char(0x83), 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
input.append(frame0, 10);

std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";

// After the handshake, add a single frame with a close message with message too big
// error code.
char frame1[4] = {char(0x88), 0x19, 0x03, char(0xf1)};
output.append(frame1, 4);
output.append("A message was too large");

server s;
s.set_user_agent("");
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
s.set_max_message_size(2);

BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}

// TODO: set max message size in client endpoint test case
// TODO: set max message size mid connection test case
// TODO: [maybe] set max message size in open handler

/*
BOOST_AUTO_TEST_CASE( user_reject_origin ) {
Expand Down
2 changes: 2 additions & 0 deletions test/processors/hybi00.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions test/processors/hybi07.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions test/processors/hybi08.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
32 changes: 32 additions & 0 deletions test/processors/hybi13.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand All @@ -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;
};

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion test/processors/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
12 changes: 12 additions & 0 deletions websocketpp/config/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
12 changes: 12 additions & 0 deletions websocketpp/config/core_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
12 changes: 12 additions & 0 deletions websocketpp/config/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,18 @@ struct debug_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;

Expand Down
40 changes: 37 additions & 3 deletions websocketpp/connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ class connection
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
, m_pong_timeout_dur(config::timeout_pong)
, m_max_message_size(config::max_message_size)
, m_state(session::state::connecting)
, m_internal_state(session::internal_state::USER_INIT)
, m_msg_manager(new con_msg_manager_type())
Expand Down Expand Up @@ -456,9 +457,9 @@ class connection
m_message_handler = h;
}

/////////////////////////
// Connection timeouts //
/////////////////////////
//////////////////////////////////////////
// Connection timeouts and other limits //
//////////////////////////////////////////

/// Set open handshake timeout
/**
Expand Down Expand Up @@ -529,6 +530,38 @@ class connection
m_pong_timeout_dur = dur;
}

/// Get maximum message size
/**
* Get maximum message size. Maximum message size determines the point at which the
* connection will fail a connection with the message_too_big protocol error.
*
* The default is set by the endpoint that creates the connection.
*
* @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
* connection will fail a connection with the message_too_big protocol error. This
* value may be changed during the connection.
*
* The default is set by the endpoint that creates the connection.
*
* @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;
if (m_processor) {
m_processor->set_max_message_size(new_value);
}
}

//////////////////////////////////
// Uncategorized public methods //
//////////////////////////////////
Expand Down Expand Up @@ -1345,6 +1378,7 @@ class connection
long m_open_handshake_timeout_dur;
long m_close_handshake_timeout_dur;
long m_pong_timeout_dur;
size_t m_max_message_size;

/// External connection state
/**
Expand Down
38 changes: 35 additions & 3 deletions websocketpp/endpoint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class endpoint : public config::transport_type, public config::endpoint_base {
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
, m_pong_timeout_dur(config::timeout_pong)
, m_max_message_size(config::max_message_size)
, m_is_server(p_is_server)
{
m_alog.set_channels(config::alog_level);
Expand Down Expand Up @@ -272,9 +273,9 @@ class endpoint : public config::transport_type, public config::endpoint_base {
m_message_handler = h;
}

/////////////////////////
// Connection timeouts //
/////////////////////////
//////////////////////////////////////////
// Connection timeouts and other limits //
//////////////////////////////////////////

/// Set open handshake timeout
/**
Expand Down Expand Up @@ -348,6 +349,36 @@ class endpoint : public config::transport_type, public config::endpoint_base {
m_pong_timeout_dur = dur;
}

/// Get default maximum message size
/**
* Get the default maximum message size that will be used for new connections created
* by this endpoint. The maximum message size determines the point at which the
* connection will fail a connection with the message_too_big protocol error.
*
* The default is set by 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 default maximum message size
/**
* Set the default maximum message size that will be used for new connections created
* by this endpoint. Maximum message size determines the point at which the connection
* will fail a connection with the message_too_big protocol error.
*
* The default is set by 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;
}

/*************************************/
/* Connection pass through functions */
/*************************************/
Expand Down Expand Up @@ -534,6 +565,7 @@ class endpoint : public config::transport_type, public config::endpoint_base {
long m_open_handshake_timeout_dur;
long m_close_handshake_timeout_dur;
long m_pong_timeout_dur;
size_t m_max_message_size;

rng_type m_rng;

Expand Down
Loading

0 comments on commit 724974c

Please sign in to comment.