Fix bug with large HTTP requests leading to Bad Request in osrm-routed. (#6403)

This commit is contained in:
Siarhei Fedartsou 2022-10-13 16:53:49 +02:00 committed by GitHub
parent 4026ed54c0
commit d143de597d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 12 deletions

View File

@ -1,5 +1,7 @@
# Unreleased # Unreleased
- Changes from 5.27.0 - Changes from 5.27.0
- Misc:
- FIXED: Fix bug with large HTTP requests leading to Bad Request in osrm-routed. [#6403](https://github.com/Project-OSRM/osrm-backend/pull/6403)
- Routing: - Routing:
- CHANGED: Add support for surface=metal,grass_paver,woodchips in bicyle profile. [#6395](https://github.com/Project-OSRM/osrm-backend/pull/6395) - CHANGED: Add support for surface=metal,grass_paver,woodchips in bicyle profile. [#6395](https://github.com/Project-OSRM/osrm-backend/pull/6395)

View File

@ -4,7 +4,7 @@ module.exports = function () {
this.When(/^I request \/(.*)$/, (path, callback) => { this.When(/^I request \/(.*)$/, (path, callback) => {
this.reprocessAndLoadData((e) => { this.reprocessAndLoadData((e) => {
if (e) return callback(e); if (e) return callback(e);
this.requestPath(path, {}, (err, res, body) => { this.requestUrl(path, (err, res, body) => {
this.response = res; this.response = res;
callback(err, res, body); callback(err, res, body);
}); });
@ -23,13 +23,13 @@ module.exports = function () {
this.ShouldBeWellFormed(); this.ShouldBeWellFormed();
}); });
this.Then(/^status code should be (\d+)$/, (code, callback) => { this.Then(/^status code should be (.+)$/, (code, callback) => {
try { try {
this.json = JSON.parse(this.response.body); this.json = JSON.parse(this.response.body);
} catch(e) { } catch(e) {
return callback(e); return callback(e);
} }
assert.equal(this.json.status, parseInt(code)); assert.equal(this.json.code, code);
callback(); callback();
}); });

File diff suppressed because one or more lines are too long

View File

@ -69,7 +69,7 @@ class Connection : public std::enable_shared_from_this<Connection>
boost::asio::deadline_timer timer; boost::asio::deadline_timer timer;
RequestHandler &request_handler; RequestHandler &request_handler;
std::optional<RequestParser> http_request_parser; std::optional<RequestParser> http_request_parser;
boost::array<char, 8192> incoming_data_buffer; std::vector<char> incoming_data_buffer;
http::request current_request; http::request current_request;
http::reply current_reply; http::reply current_reply;
std::vector<char> compressed_output; std::vector<char> compressed_output;

View File

@ -12,10 +12,16 @@ namespace osrm
namespace server namespace server
{ {
namespace
{
const size_t CHUNK_SIZE = 8192;
} // namespace
Connection::Connection(boost::asio::io_context &io_context, RequestHandler &handler) Connection::Connection(boost::asio::io_context &io_context, RequestHandler &handler)
: strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand), : strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand),
request_handler(handler), http_request_parser(std::make_optional<RequestParser>()) request_handler(handler), http_request_parser(std::make_optional<RequestParser>())
{ {
http_request_parser->header_limit(std::numeric_limits<std::uint32_t>::max());
} }
boost::asio::ip::tcp::socket &Connection::socket() { return TCP_socket; } boost::asio::ip::tcp::socket &Connection::socket() { return TCP_socket; }
@ -59,7 +65,8 @@ void Connection::start()
} }
} }
void Connection::handle_read(const boost::system::error_code &error, std::size_t bytes_transferred) void Connection::handle_read(const boost::system::error_code &error,
std::size_t /*bytes_transferred*/)
{ {
if (error) if (error)
{ {
@ -79,7 +86,7 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
} }
boost::beast::error_code ec; boost::beast::error_code ec;
http_request_parser->put(boost::asio::buffer(incoming_data_buffer, bytes_transferred), ec); http_request_parser->put(boost::asio::buffer(incoming_data_buffer), ec);
// no error detected, let's parse the request // no error detected, let's parse the request
http::compression_type compression_type(http::no_compression); http::compression_type compression_type(http::no_compression);
@ -87,12 +94,15 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
{ {
if (ec == boost::beast::http::error::need_more) if (ec == boost::beast::http::error::need_more)
{ {
const auto current_size = incoming_data_buffer.size();
incoming_data_buffer.resize(incoming_data_buffer.size() + CHUNK_SIZE, 0);
// we don't have a result yet, so continue reading // we don't have a result yet, so continue reading
TCP_socket.async_read_some(boost::asio::buffer(incoming_data_buffer), TCP_socket.async_read_some(
boost::bind(&Connection::handle_read, boost::asio::buffer(incoming_data_buffer.data() + current_size, CHUNK_SIZE),
this->shared_from_this(), boost::bind(&Connection::handle_read,
boost::asio::placeholders::error, this->shared_from_this(),
boost::asio::placeholders::bytes_transferred)); boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
} }
else else
{ {
@ -183,7 +193,8 @@ void Connection::handle_write(const boost::system::error_code &error)
current_request = http::request(); current_request = http::request();
current_reply = http::reply(); current_reply = http::reply();
http_request_parser.emplace(); http_request_parser.emplace();
incoming_data_buffer = boost::array<char, 8192>(); http_request_parser->header_limit(std::numeric_limits<std::uint32_t>::max());
incoming_data_buffer.resize(CHUNK_SIZE, 0);
output_buffer.clear(); output_buffer.clear();
this->start(); this->start();
} }