Skip to content

Commit 724974c

Browse files
committed
Merge pull request XRPLF#322 from zaphoyd/max-message-size
Adds the ability to specify a max message size
2 parents 47c46a2 + 1622cdd commit 724974c

16 files changed

+266
-52
lines changed

changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ HEAD
1313
the main thread.
1414
- Feature: Adds the ability to specify whether or not to use the `SO_REUSEADDR` TCP socket
1515
option. The default for this value has been changed from `true` to `false`.
16+
- Feature: Adds the ability to specify a maximum message size.
1617
- Improvement: Open, close, and pong timeouts can be disabled entirely by setting their
1718
duration to 0.
1819
- Improvement: Numerous performance improvements. Including: tuned default

test/connection/connection.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,33 @@ BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
192192
BOOST_CHECK_EQUAL(ref, output.str());
193193
}
194194

195+
BOOST_AUTO_TEST_CASE( set_max_message_size ) {
196+
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";
197+
198+
// After the handshake, add a single frame with a message that is too long.
199+
char frame0[10] = {char(0x82), char(0x83), 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
200+
input.append(frame0, 10);
201+
202+
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";
203+
204+
// After the handshake, add a single frame with a close message with message too big
205+
// error code.
206+
char frame1[4] = {char(0x88), 0x19, 0x03, char(0xf1)};
207+
output.append(frame1, 4);
208+
output.append("A message was too large");
209+
210+
server s;
211+
s.set_user_agent("");
212+
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
213+
s.set_max_message_size(2);
214+
215+
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
216+
}
217+
218+
// TODO: set max message size in client endpoint test case
219+
// TODO: set max message size mid connection test case
220+
// TODO: [maybe] set max message size in open handler
221+
195222
/*
196223
197224
BOOST_AUTO_TEST_CASE( user_reject_origin ) {

test/processors/hybi00.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ struct stub_config {
4545
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
4646
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
4747
con_msg_manager_type;
48+
49+
static const size_t max_message_size = 16000000;
4850
};
4951

5052
struct processor_setup {

test/processors/hybi07.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ struct stub_config {
5050

5151
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
5252

53+
static const size_t max_message_size = 16000000;
54+
5355
/// Extension related config
5456
static const bool enable_extensions = false;
5557

test/processors/hybi08.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ struct stub_config {
5050

5151
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
5252

53+
static const size_t max_message_size = 16000000;
54+
5355
/// Extension related config
5456
static const bool enable_extensions = false;
5557

test/processors/hybi13.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct stub_config {
6060
typedef websocketpp::extensions::permessage_deflate::disabled
6161
<permessage_deflate_config> permessage_deflate_type;
6262

63+
static const size_t max_message_size = 16000000;
6364
static const bool enable_extensions = false;
6465
};
6566

@@ -81,6 +82,7 @@ struct stub_config_ext {
8182
typedef websocketpp::extensions::permessage_deflate::enabled
8283
<permessage_deflate_config> permessage_deflate_type;
8384

85+
static const size_t max_message_size = 16000000;
8486
static const bool enable_extensions = true;
8587
};
8688

@@ -489,6 +491,36 @@ BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
489491

490492
}
491493

494+
BOOST_AUTO_TEST_CASE( single_frame_message_too_large ) {
495+
processor_setup env(true);
496+
497+
env.p.set_max_message_size(3);
498+
499+
uint8_t frame0[10] = {0x82, 0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01};
500+
501+
// read message that is one byte too large
502+
BOOST_CHECK_EQUAL( env.p.consume(frame0,10,env.ec), 6 );
503+
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
504+
}
505+
506+
BOOST_AUTO_TEST_CASE( multiple_frame_message_too_large ) {
507+
processor_setup env(true);
508+
509+
env.p.set_max_message_size(4);
510+
511+
uint8_t frame0[8] = {0x02, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
512+
uint8_t frame1[9] = {0x80, 0x83, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
513+
514+
// read first message frame with size under the limit
515+
BOOST_CHECK_EQUAL( env.p.consume(frame0,8,env.ec), 8 );
516+
BOOST_CHECK( !env.ec );
517+
518+
// read second message frame that puts the size over the limit
519+
BOOST_CHECK_EQUAL( env.p.consume(frame1,9,env.ec), 6 );
520+
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
521+
}
522+
523+
492524

493525
BOOST_AUTO_TEST_CASE( client_handshake_request ) {
494526
processor_setup env(false);

test/processors/processor.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,4 @@ BOOST_AUTO_TEST_CASE( version_non_numeric ) {
132132
r.consume(handshake.c_str(),handshake.size());
133133

134134
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == -1);
135-
}
135+
}

websocketpp/config/core.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,18 @@ struct core {
215215
*/
216216
static const bool silent_close = false;
217217

218+
/// Default maximum message size
219+
/**
220+
* Default value for the processor's maximum message size. Maximum message size
221+
* determines the point at which the library will fail a connection with the
222+
* message_too_big protocol error.
223+
*
224+
* The default is 32MB
225+
*
226+
* @since 0.4.0-alpha1
227+
*/
228+
static const size_t max_message_size = 32000000;
229+
218230
/// Global flag for enabling/disabling extensions
219231
static const bool enable_extensions = true;
220232

websocketpp/config/core_client.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ struct core_client {
216216
*/
217217
static const bool silent_close = false;
218218

219+
/// Default maximum message size
220+
/**
221+
* Default value for the processor's maximum message size. Maximum message size
222+
* determines the point at which the library will fail a connection with the
223+
* message_too_big protocol error.
224+
*
225+
* The default is 32MB
226+
*
227+
* @since 0.4.0-alpha1
228+
*/
229+
static const size_t max_message_size = 32000000;
230+
219231
/// Global flag for enabling/disabling extensions
220232
static const bool enable_extensions = true;
221233

websocketpp/config/debug.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ struct debug_core {
216216
*/
217217
static const bool silent_close = false;
218218

219+
/// Default maximum message size
220+
/**
221+
* Default value for the processor's maximum message size. Maximum message size
222+
* determines the point at which the library will fail a connection with the
223+
* message_too_big protocol error.
224+
*
225+
* The default is 32MB
226+
*
227+
* @since 0.4.0-alpha1
228+
*/
229+
static const size_t max_message_size = 32000000;
230+
219231
/// Global flag for enabling/disabling extensions
220232
static const bool enable_extensions = true;
221233

websocketpp/connection.hpp

+37-3
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ class connection
297297
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
298298
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
299299
, m_pong_timeout_dur(config::timeout_pong)
300+
, m_max_message_size(config::max_message_size)
300301
, m_state(session::state::connecting)
301302
, m_internal_state(session::internal_state::USER_INIT)
302303
, m_msg_manager(new con_msg_manager_type())
@@ -456,9 +457,9 @@ class connection
456457
m_message_handler = h;
457458
}
458459

459-
/////////////////////////
460-
// Connection timeouts //
461-
/////////////////////////
460+
//////////////////////////////////////////
461+
// Connection timeouts and other limits //
462+
//////////////////////////////////////////
462463

463464
/// Set open handshake timeout
464465
/**
@@ -529,6 +530,38 @@ class connection
529530
m_pong_timeout_dur = dur;
530531
}
531532

533+
/// Get maximum message size
534+
/**
535+
* Get maximum message size. Maximum message size determines the point at which the
536+
* connection will fail a connection with the message_too_big protocol error.
537+
*
538+
* The default is set by the endpoint that creates the connection.
539+
*
540+
* @since 0.4.0-alpha1
541+
*/
542+
size_t get_max_message_size() const {
543+
return m_max_message_size;
544+
}
545+
546+
/// Set maximum message size
547+
/**
548+
* Set maximum message size. Maximum message size determines the point at which the
549+
* connection will fail a connection with the message_too_big protocol error. This
550+
* value may be changed during the connection.
551+
*
552+
* The default is set by the endpoint that creates the connection.
553+
*
554+
* @since 0.4.0-alpha1
555+
*
556+
* @param new_value The value to set as the maximum message size.
557+
*/
558+
void set_max_message_size(size_t new_value) {
559+
m_max_message_size = new_value;
560+
if (m_processor) {
561+
m_processor->set_max_message_size(new_value);
562+
}
563+
}
564+
532565
//////////////////////////////////
533566
// Uncategorized public methods //
534567
//////////////////////////////////
@@ -1345,6 +1378,7 @@ class connection
13451378
long m_open_handshake_timeout_dur;
13461379
long m_close_handshake_timeout_dur;
13471380
long m_pong_timeout_dur;
1381+
size_t m_max_message_size;
13481382

13491383
/// External connection state
13501384
/**

websocketpp/endpoint.hpp

+35-3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class endpoint : public config::transport_type, public config::endpoint_base {
9494
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
9595
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
9696
, m_pong_timeout_dur(config::timeout_pong)
97+
, m_max_message_size(config::max_message_size)
9798
, m_is_server(p_is_server)
9899
{
99100
m_alog.set_channels(config::alog_level);
@@ -272,9 +273,9 @@ class endpoint : public config::transport_type, public config::endpoint_base {
272273
m_message_handler = h;
273274
}
274275

275-
/////////////////////////
276-
// Connection timeouts //
277-
/////////////////////////
276+
//////////////////////////////////////////
277+
// Connection timeouts and other limits //
278+
//////////////////////////////////////////
278279

279280
/// Set open handshake timeout
280281
/**
@@ -348,6 +349,36 @@ class endpoint : public config::transport_type, public config::endpoint_base {
348349
m_pong_timeout_dur = dur;
349350
}
350351

352+
/// Get default maximum message size
353+
/**
354+
* Get the default maximum message size that will be used for new connections created
355+
* by this endpoint. The maximum message size determines the point at which the
356+
* connection will fail a connection with the message_too_big protocol error.
357+
*
358+
* The default is set by the max_message_size value from the template config
359+
*
360+
* @since 0.4.0-alpha1
361+
*/
362+
size_t get_max_message_size() const {
363+
return m_max_message_size;
364+
}
365+
366+
/// Set default maximum message size
367+
/**
368+
* Set the default maximum message size that will be used for new connections created
369+
* by this endpoint. Maximum message size determines the point at which the connection
370+
* will fail a connection with the message_too_big protocol error.
371+
*
372+
* The default is set by the max_message_size value from the template config
373+
*
374+
* @since 0.4.0-alpha1
375+
*
376+
* @param new_value The value to set as the maximum message size.
377+
*/
378+
void set_max_message_size(size_t new_value) {
379+
m_max_message_size = new_value;
380+
}
381+
351382
/*************************************/
352383
/* Connection pass through functions */
353384
/*************************************/
@@ -534,6 +565,7 @@ class endpoint : public config::transport_type, public config::endpoint_base {
534565
long m_open_handshake_timeout_dur;
535566
long m_close_handshake_timeout_dur;
536567
long m_pong_timeout_dur;
568+
size_t m_max_message_size;
537569

538570
rng_type m_rng;
539571

0 commit comments

Comments
 (0)