mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-02 08:17:13 +00:00
adds limit to network read buffer (to prevent DoS attacks), refactors client handshake reading to leave non-handshake data in the read buffer
This commit is contained in:
@@ -47,8 +47,9 @@ using websocketpp::client_session;
|
||||
|
||||
client_session::client_session (websocketpp::client_ptr c,
|
||||
boost::asio::io_service& io_service,
|
||||
websocketpp::connection_handler_ptr defc)
|
||||
: session(io_service,defc),m_client(c) {}
|
||||
websocketpp::connection_handler_ptr defc,
|
||||
uint64_t buf_size)
|
||||
: session(io_service,defc,buf_size),m_client(c) {}
|
||||
|
||||
void client_session::on_connect() {
|
||||
// TODO: section 4.1: Figure out if we have another connection to this
|
||||
@@ -124,56 +125,49 @@ void client_session::read_handshake() {
|
||||
void client_session::handle_read_handshake(const boost::system::error_code& e,
|
||||
std::size_t bytes_transferred) {
|
||||
// parse server handshake
|
||||
|
||||
|
||||
// read handshake and set local state (or pass to write_handshake)
|
||||
std::ostringstream line;
|
||||
line << &m_buf;
|
||||
m_raw_server_handshake += line.str();
|
||||
|
||||
m_buf << m_raw_server_handshake.substr(bytes_transferred);
|
||||
|
||||
std::stringstream foo;
|
||||
|
||||
foo << "data size: " << m_raw_server_handshake.size()
|
||||
<< " bytes transferred" << bytes_transferred;
|
||||
|
||||
m_client->access_log(foo.str(), ALOG_HANDSHAKE);
|
||||
m_client->access_log(m_raw_server_handshake,ALOG_HANDSHAKE);
|
||||
m_client->access_log("SPACER",ALOG_HANDSHAKE);
|
||||
|
||||
std::vector<std::string> tokens;
|
||||
std::string::size_type start = 0;
|
||||
std::istream response_stream(&m_buf);
|
||||
std::string header;
|
||||
std::string::size_type end;
|
||||
|
||||
// Get request and parse headers
|
||||
end = m_raw_server_handshake.find("\r\n",start);
|
||||
|
||||
while(end != std::string::npos) {
|
||||
tokens.push_back(m_raw_server_handshake.substr(start, end - start));
|
||||
|
||||
start = end + 2;
|
||||
|
||||
end = m_raw_server_handshake.find("\r\n",start);
|
||||
// get status line
|
||||
std::getline(response_stream, header);
|
||||
if (header[header.size()-1] == '\r') {
|
||||
header.erase(header.end()-1);
|
||||
m_server_http_request = header;
|
||||
m_raw_server_handshake += header+"\n";
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tokens.size(); i++) {
|
||||
if (i == 0) {
|
||||
m_server_http_request = tokens[i];
|
||||
// get headers
|
||||
while (std::getline(response_stream, header) && header != "\r") {
|
||||
if (header[header.size()-1] != '\r') {
|
||||
continue; // ignore malformed header lines?
|
||||
} else {
|
||||
header.erase(header.end()-1);
|
||||
}
|
||||
|
||||
end = tokens[i].find(": ",0);
|
||||
end = header.find(": ",0);
|
||||
|
||||
if (end != std::string::npos) {
|
||||
std::string h = tokens[i].substr(0,end);
|
||||
if (end != std::string::npos) {
|
||||
std::string h = header.substr(0,end);
|
||||
if (get_server_header(h) == "") {
|
||||
m_server_headers[h] = tokens[i].substr(end+2);
|
||||
m_server_headers[h] = header.substr(end+2);
|
||||
} else {
|
||||
m_server_headers[h] += ", " + tokens[i].substr(end+2);
|
||||
m_server_headers[h] += ", " + header.substr(end+2);
|
||||
}
|
||||
}
|
||||
|
||||
m_raw_server_handshake += header+"\n";
|
||||
}
|
||||
|
||||
// temporary debugging
|
||||
if (m_buf.size() > 0) {
|
||||
std::stringstream foo;
|
||||
foo << "bytes left over: " << m_buf.size();
|
||||
access_log(foo.str(), ALOG_HANDSHAKE);
|
||||
}
|
||||
|
||||
m_client->access_log(m_raw_server_handshake,ALOG_HANDSHAKE);
|
||||
|
||||
// handshake error checking
|
||||
try {
|
||||
std::stringstream err;
|
||||
@@ -202,7 +196,7 @@ void client_session::handle_read_handshake(const boost::system::error_code& e,
|
||||
if (h == "") {
|
||||
throw(handshake_error("Required Upgrade header is missing",400));
|
||||
} else if (!boost::iequals(h,"websocket")) {
|
||||
err << "Upgrade header was " << h << " instead of \"websocket\"";
|
||||
err << "Upgrade header was \"" << h << "\" instead of \"websocket\"";
|
||||
throw(handshake_error(err.str(),400));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user