From e310b49353dc4d4a34f40b662195b3c3d36e3b59 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 16 Mar 2013 00:21:44 -0700 Subject: [PATCH] Fix parsing of split headers. --- src/cpp/websocketpp/src/roles/server.hpp | 45 ++++++++++++++++-------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/cpp/websocketpp/src/roles/server.hpp b/src/cpp/websocketpp/src/roles/server.hpp index 7042792bde..f77397d55b 100644 --- a/src/cpp/websocketpp/src/roles/server.hpp +++ b/src/cpp/websocketpp/src/roles/server.hpp @@ -55,33 +55,41 @@ namespace websocketpp { typedef boost::asio::buffers_iterator bufIterator; -static std::pair match_header(bufIterator begin, bufIterator end) +static std::pair match_header(boost::shared_ptr string, + bufIterator nBegin, bufIterator nEnd) { + if (nBegin == nEnd) + return std::make_pair(nEnd, false); + + (*string) += std::string(nBegin, nEnd); + std::string::const_iterator begin = string->begin(); + std::string::const_iterator end = string->end(); + static const std::string eol_match = "\n"; - static const std::string header_match = "\n\r\n"; - static const std::string alt_header_match = "\n\n"; + static const std::string header_match = "\r\n\r\n"; static const std::string flash_match = ""; // Do we have a complete HTTP request - bufIterator it = std::search(begin, end, header_match.begin(), header_match.end()); + std::string::const_iterator it = std::search(begin, end, header_match.begin(), header_match.end()); if (it != end) - return std::make_pair(it + header_match.size(), true); - it = std::search(begin, end, alt_header_match.begin(), alt_header_match.end()); - if (it != end) - return std::make_pair(it + alt_header_match.size(), true); + { + int leftOver = (end - (it + header_match.size())); + return std::make_pair(nEnd - leftOver, true); + } // If we don't have a flash policy request, we're done it = std::search(begin, end, flash_match.begin(), flash_match.end()); if (it == end) // No match - return std::make_pair(end, false); + return std::make_pair(nEnd, false); // If we have a line ending before the flash policy request, treat as http - bufIterator it2 = std::search(begin, end, eol_match.begin(), eol_match.end()); + std::string::const_iterator it2 = std::search(begin, end, eol_match.begin(), eol_match.end()); if ((it2 != end) && (it2 < it)) - return std::make_pair(end, false); + return std::make_pair(nEnd, false); // Treat as flash policy request - return std::make_pair(it + flash_match.size(), true); + int leftOver = (end - (it + flash_match.size())); + return std::make_pair(nEnd - leftOver, true); } // Forward declarations @@ -170,7 +178,7 @@ public: // initializes the websocket connection void async_init(); - void handle_read_request(const boost::system::error_code& error, + void handle_read_request(boost::shared_ptr, const boost::system::error_code& error, std::size_t bytes_transferred); void handle_short_key3(const boost::system::error_code& error, std::size_t bytes_transferred); @@ -543,12 +551,14 @@ void server::connection::async_init() { m_connection.register_timeout(5000,fail::status::TIMEOUT_WS, "Timeout on WebSocket handshake"); + boost::shared_ptr stringPtr = boost::make_shared(); m_connection.get_socket().async_read_until( m_connection.buffer(), - match_header, + boost::bind(&match_header, stringPtr, _1, _2), m_connection.get_strand().wrap(boost::bind( &type::handle_read_request, m_connection.shared_from_this(), + stringPtr, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred )) @@ -562,6 +572,7 @@ void server::connection::async_init() { template template void server::connection::handle_read_request( + boost::shared_ptr header, const boost::system::error_code& error, std::size_t /*bytes_transferred*/) { if (error) { @@ -571,9 +582,11 @@ void server::connection::handle_read_request( m_connection.terminate(false); return; } + + m_connection.buffer().consume(header->size()); try { - std::istream request(&m_connection.buffer()); + std::istringstream request(*header); if (!m_request.parse_complete(request)) { // not a valid HTTP request/response @@ -607,6 +620,8 @@ void server::connection::handle_read_request( //m_endpoint.m_alog.at(log::alevel::DEBUG_HANDSHAKE) << m_request.raw() << log::endl; std::string h = m_request.header("Upgrade"); + if (h.empty()) + h = m_request.header("upgrade"); if (boost::ifind_first(h,"websocket")) { // Version is stored in the Sec-WebSocket-Version header for all // versions after draft Hybi 00/Hixie 76. The absense of a version