Fixes an issue where some frame data was counted against the max header size limit

End result was that connections that included a lot of frame data
immediately after the initial handshake would erroneously fail due to
hitting the max header size limit.
This commit is contained in:
Peter Thorson
2015-02-27 09:48:00 -05:00
parent f20b2e573f
commit 9efb12e59b
4 changed files with 105 additions and 18 deletions
+82 -1
View File
@@ -559,6 +559,30 @@ BOOST_AUTO_TEST_CASE( trailing_body_characters ) {
BOOST_CHECK( r.get_header("Host") == "www.example.com" );
}
BOOST_AUTO_TEST_CASE( trailing_body_characters_beyond_max_lenth ) {
websocketpp::http::parser::request r;
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
raw.append(websocketpp::http::max_header_size,'*');
bool exception = false;
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
}
BOOST_CHECK( exception == false );
BOOST_CHECK( pos == 41 );
BOOST_CHECK( r.ready() == true );
BOOST_CHECK( r.get_version() == "HTTP/1.1" );
BOOST_CHECK( r.get_method() == "GET" );
BOOST_CHECK( r.get_uri() == "/" );
BOOST_CHECK( r.get_header("Host") == "www.example.com" );
}
BOOST_AUTO_TEST_CASE( basic_split1 ) {
websocketpp::http::parser::request r;
@@ -614,7 +638,8 @@ BOOST_AUTO_TEST_CASE( basic_split2 ) {
BOOST_AUTO_TEST_CASE( max_header_len ) {
websocketpp::http::parser::request r;
std::string raw(websocketpp::http::max_header_size+1,'*');
std::string raw(websocketpp::http::max_header_size-1,'*');
raw += "\r\n";
bool exception = false;
size_t pos = 0;
@@ -922,6 +947,62 @@ BOOST_AUTO_TEST_CASE( wikipedia_example_response ) {
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
}
BOOST_AUTO_TEST_CASE( wikipedia_example_response_trailing ) {
websocketpp::http::parser::response r;
std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
raw += "a";
bool exception = false;
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
BOOST_CHECK_EQUAL( pos, 159 );
BOOST_CHECK( r.headers_ready() == true );
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
}
BOOST_AUTO_TEST_CASE( wikipedia_example_response_trailing_large ) {
websocketpp::http::parser::response r;
std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
raw.append(websocketpp::http::max_header_size,'*');
bool exception = false;
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
BOOST_CHECK_EQUAL( pos, 159 );
BOOST_CHECK( r.headers_ready() == true );
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
}
BOOST_AUTO_TEST_CASE( response_with_non_standard_lws ) {
websocketpp::http::parser::response r;
+9 -9
View File
@@ -51,12 +51,6 @@ inline size_t request::consume(char const * buf, size_t len) {
return bytes_processed;
}
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);
@@ -72,15 +66,21 @@ inline size_t request::consume(char const * buf, size_t len) {
header_delimiter,
header_delimiter+sizeof(header_delimiter)-1
);
//std::cout << "mark5: " << end-begin << std::endl;
//std::cout << "mark6: " << sizeof(header_delimiter) << std::endl;
m_header_bytes += (end-begin+sizeof(header_delimiter));
if (m_header_bytes > max_header_size) {
// exceeded max header size
throw exception("Maximum header size exceeded.",
status_code::request_header_fields_too_large);
}
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<std::string::size_type>(end-begin));
m_header_bytes -= m_buf->size();
return len;
}
+10 -7
View File
@@ -46,12 +46,6 @@ inline size_t response::consume(char const * buf, size_t len) {
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);
@@ -69,13 +63,22 @@ inline size_t response::consume(char const * buf, size_t len) {
header_delimiter + sizeof(header_delimiter) - 1
);
m_header_bytes += (end-begin+sizeof(header_delimiter));
if (m_header_bytes > max_header_size) {
// exceeded max header size
throw exception("Maximum header size exceeded.",
status_code::request_header_fields_too_large);
}
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<std::string::size_type>(end-begin));
m_read +=len;
m_read += len;
m_header_bytes -= m_buf->size();
return len;
}
+4 -1
View File
@@ -394,7 +394,8 @@ inline std::string strip_lws(std::string const & input) {
class parser {
public:
parser()
: m_body_bytes_needed(0)
: m_header_bytes(0)
, m_body_bytes_needed(0)
, m_body_bytes_max(max_body_size)
, m_body_encoding(body_encoding::unknown) {}
@@ -597,6 +598,8 @@ protected:
std::string m_version;
header_list m_headers;
size_t m_header_bytes;
std::string m_body;
size_t m_body_bytes_needed;
size_t m_body_bytes_max;