Skip to content

Commit a70cc61

Browse files
JoelKatzvinniefalco
authored andcommitted
Fix parsing of split headers.
1 parent 8f14773 commit a70cc61

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

src/roles/server.hpp

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,33 +55,41 @@ namespace websocketpp {
5555

5656
typedef boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type> bufIterator;
5757

58-
static std::pair<bufIterator, bool> match_header(bufIterator begin, bufIterator end)
58+
static std::pair<bufIterator, bool> match_header(boost::shared_ptr<std::string> string,
59+
bufIterator nBegin, bufIterator nEnd)
5960
{
61+
if (nBegin == nEnd)
62+
return std::make_pair(nEnd, false);
63+
64+
(*string) += std::string(nBegin, nEnd);
65+
std::string::const_iterator begin = string->begin();
66+
std::string::const_iterator end = string->end();
67+
6068
static const std::string eol_match = "\n";
61-
static const std::string header_match = "\n\r\n";
62-
static const std::string alt_header_match = "\n\n";
69+
static const std::string header_match = "\r\n\r\n";
6370
static const std::string flash_match = "<policy-file-request/>";
6471

6572
// Do we have a complete HTTP request
66-
bufIterator it = std::search(begin, end, header_match.begin(), header_match.end());
67-
if (it != end)
68-
return std::make_pair(it + header_match.size(), true);
69-
it = std::search(begin, end, alt_header_match.begin(), alt_header_match.end());
73+
std::string::const_iterator it = std::search(begin, end, header_match.begin(), header_match.end());
7074
if (it != end)
71-
return std::make_pair(it + alt_header_match.size(), true);
75+
{
76+
int leftOver = (end - (it + header_match.size()));
77+
return std::make_pair(nEnd - leftOver, true);
78+
}
7279

7380
// If we don't have a flash policy request, we're done
7481
it = std::search(begin, end, flash_match.begin(), flash_match.end());
7582
if (it == end) // No match
76-
return std::make_pair(end, false);
83+
return std::make_pair(nEnd, false);
7784

7885
// If we have a line ending before the flash policy request, treat as http
79-
bufIterator it2 = std::search(begin, end, eol_match.begin(), eol_match.end());
86+
std::string::const_iterator it2 = std::search(begin, end, eol_match.begin(), eol_match.end());
8087
if ((it2 != end) && (it2 < it))
81-
return std::make_pair(end, false);
88+
return std::make_pair(nEnd, false);
8289

8390
// Treat as flash policy request
84-
return std::make_pair(it + flash_match.size(), true);
91+
int leftOver = (end - (it + flash_match.size()));
92+
return std::make_pair(nEnd - leftOver, true);
8593
}
8694

8795
// Forward declarations
@@ -170,7 +178,7 @@ class server {
170178

171179
// initializes the websocket connection
172180
void async_init();
173-
void handle_read_request(const boost::system::error_code& error,
181+
void handle_read_request(boost::shared_ptr<std::string>, const boost::system::error_code& error,
174182
std::size_t bytes_transferred);
175183
void handle_short_key3(const boost::system::error_code& error,
176184
std::size_t bytes_transferred);
@@ -543,12 +551,14 @@ void server<endpoint>::connection<connection_type>::async_init() {
543551
m_connection.register_timeout(5000,fail::status::TIMEOUT_WS,
544552
"Timeout on WebSocket handshake");
545553

554+
boost::shared_ptr<std::string> stringPtr = boost::make_shared<std::string>();
546555
m_connection.get_socket().async_read_until(
547556
m_connection.buffer(),
548-
match_header,
557+
boost::bind(&match_header, stringPtr, _1, _2),
549558
m_connection.get_strand().wrap(boost::bind(
550559
&type::handle_read_request,
551560
m_connection.shared_from_this(),
561+
stringPtr,
552562
boost::asio::placeholders::error,
553563
boost::asio::placeholders::bytes_transferred
554564
))
@@ -562,6 +572,7 @@ void server<endpoint>::connection<connection_type>::async_init() {
562572
template <class endpoint>
563573
template <class connection_type>
564574
void server<endpoint>::connection<connection_type>::handle_read_request(
575+
boost::shared_ptr<std::string> header,
565576
const boost::system::error_code& error, std::size_t /*bytes_transferred*/)
566577
{
567578
if (error) {
@@ -571,9 +582,11 @@ void server<endpoint>::connection<connection_type>::handle_read_request(
571582
m_connection.terminate(false);
572583
return;
573584
}
585+
586+
m_connection.buffer().consume(header->size());
574587

575588
try {
576-
std::istream request(&m_connection.buffer());
589+
std::istringstream request(*header);
577590

578591
if (!m_request.parse_complete(request)) {
579592
// not a valid HTTP request/response
@@ -607,6 +620,8 @@ void server<endpoint>::connection<connection_type>::handle_read_request(
607620
//m_endpoint.m_alog.at(log::alevel::DEBUG_HANDSHAKE) << m_request.raw() << log::endl;
608621

609622
std::string h = m_request.header("Upgrade");
623+
if (h.empty())
624+
h = m_request.header("upgrade");
610625
if (boost::ifind_first(h,"websocket")) {
611626
// Version is stored in the Sec-WebSocket-Version header for all
612627
// versions after draft Hybi 00/Hixie 76. The absense of a version

0 commit comments

Comments
 (0)