11#include " server/connection.hpp"
22#include " server/request_handler.hpp"
3- #include " server/request_parser.hpp"
43
54#include < boost/algorithm/string/predicate.hpp>
65#include < boost/bind.hpp>
76#include < boost/iostreams/filter/gzip.hpp>
87#include < boost/iostreams/filtering_stream.hpp>
9-
108#include < vector>
119
1210namespace osrm
@@ -16,12 +14,32 @@ namespace server
1614
1715Connection::Connection (boost::asio::io_context &io_context, RequestHandler &handler)
1816 : strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand),
19- request_handler (handler)
17+ request_handler (handler), http_request_parser(std::make_optional<RequestParser>())
2018{
2119}
2220
2321boost::asio::ip::tcp::socket &Connection::socket () { return TCP_socket; }
2422
23+ namespace
24+ {
25+
26+ http::compression_type select_compression (const boost::beast::http::fields &fields)
27+ {
28+ const auto header_value = fields[boost::beast::http::field::accept_encoding];
29+ /* giving gzip precedence over deflate */
30+ if (boost::icontains (header_value, " deflate" ))
31+ {
32+ return http::deflate_rfc1951;
33+ }
34+ if (boost::icontains (header_value, " gzip" ))
35+ {
36+ return http::gzip_rfc1952;
37+ }
38+ return http::no_compression;
39+ }
40+
41+ } // namespace
42+
2543// / Start the first asynchronous operation for the connection.
2644void Connection::start ()
2745{
@@ -60,20 +78,45 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
6078 timer.expires_from_now (boost::posix_time::seconds (0 ));
6179 }
6280
81+ boost::beast::error_code ec;
82+ http_request_parser->put (boost::asio::buffer (incoming_data_buffer, bytes_transferred), ec);
6383 // no error detected, let's parse the request
6484 http::compression_type compression_type (http::no_compression);
65- RequestParser::RequestStatus result;
66- std::tie (result, compression_type) =
67- request_parser.parse (current_request,
68- incoming_data_buffer.data (),
69- incoming_data_buffer.data () + bytes_transferred);
70-
71- // the request has been parsed
72- if (result == RequestParser::RequestStatus::valid)
85+
86+ if (ec)
87+ {
88+ if (ec == boost::beast::http::error::need_more)
89+ {
90+ // we don't have a result yet, so continue reading
91+ TCP_socket.async_read_some (boost::asio::buffer (incoming_data_buffer),
92+ boost::bind (&Connection::handle_read,
93+ this ->shared_from_this (),
94+ boost::asio::placeholders::error,
95+ boost::asio::placeholders::bytes_transferred));
96+ }
97+ else
98+ {
99+ // request is not parseable
100+ current_reply = http::reply::stock_reply (http::reply::bad_request);
101+
102+ boost::asio::async_write (TCP_socket,
103+ current_reply.to_buffers (),
104+ boost::bind (&Connection::handle_write,
105+ this ->shared_from_this (),
106+ boost::asio::placeholders::error));
107+ }
108+ }
109+ else
73110 {
111+ // the request has been parsed
112+ const auto &message = http_request_parser->get ();
113+ compression_type = select_compression (message);
114+
115+ fill_request (message, current_request);
74116
75117 boost::system::error_code ec;
76118 current_request.endpoint = TCP_socket.remote_endpoint (ec).address ();
119+
77120 if (ec)
78121 {
79122 util::Log (logDEBUG) << " Socket remote endpoint error: " << ec.message ();
@@ -127,25 +170,6 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
127170 this ->shared_from_this (),
128171 boost::asio::placeholders::error));
129172 }
130- else if (result == RequestParser::RequestStatus::invalid)
131- { // request is not parseable
132- current_reply = http::reply::stock_reply (http::reply::bad_request);
133-
134- boost::asio::async_write (TCP_socket,
135- current_reply.to_buffers (),
136- boost::bind (&Connection::handle_write,
137- this ->shared_from_this (),
138- boost::asio::placeholders::error));
139- }
140- else
141- {
142- // we don't have a result yet, so continue reading
143- TCP_socket.async_read_some (boost::asio::buffer (incoming_data_buffer),
144- boost::bind (&Connection::handle_read,
145- this ->shared_from_this (),
146- boost::asio::placeholders::error,
147- boost::asio::placeholders::bytes_transferred));
148- }
149173}
150174
151175// / Handle completion of a write operation.
@@ -158,7 +182,7 @@ void Connection::handle_write(const boost::system::error_code &error)
158182 --processed_requests;
159183 current_request = http::request ();
160184 current_reply = http::reply ();
161- request_parser = RequestParser ();
185+ http_request_parser. emplace ();
162186 incoming_data_buffer = boost::array<char , 8192 >();
163187 output_buffer.clear ();
164188 this ->start ();
@@ -220,5 +244,15 @@ std::vector<char> Connection::compress_buffers(const std::vector<char> &uncompre
220244
221245 return compressed_data;
222246}
247+
248+ void Connection::fill_request (const RequestParser::value_type &http_message,
249+ http::request ¤t_request)
250+ {
251+ current_request.uri = http_message.target ().to_string ();
252+ current_request.agent = http_message[boost::beast::http::field::user_agent].to_string ();
253+ current_request.referrer = http_message[boost::beast::http::field::referer].to_string ();
254+ current_request.connection = http_message[boost::beast::http::field::connection].to_string ();
255+ }
256+
223257} // namespace server
224258} // namespace osrm
0 commit comments