1
1
#include " server/connection.hpp"
2
2
#include " server/request_handler.hpp"
3
+ #include " server/request_parser.hpp"
3
4
4
5
#include < boost/algorithm/string/predicate.hpp>
5
6
#include < boost/bind.hpp>
6
7
#include < boost/iostreams/filter/gzip.hpp>
7
8
#include < boost/iostreams/filtering_stream.hpp>
9
+
8
10
#include < vector>
9
11
10
12
namespace osrm
@@ -14,32 +16,12 @@ namespace server
14
16
15
17
Connection::Connection (boost::asio::io_context &io_context, RequestHandler &handler)
16
18
: strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand),
17
- request_handler (handler), http_request_parser(std::make_optional<RequestParser>())
19
+ request_handler (handler)
18
20
{
19
21
}
20
22
21
23
boost::asio::ip::tcp::socket &Connection::socket () { return TCP_socket; }
22
24
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
-
43
25
// / Start the first asynchronous operation for the connection.
44
26
void Connection::start ()
45
27
{
@@ -78,45 +60,20 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
78
60
timer.expires_from_now (boost::posix_time::seconds (0 ));
79
61
}
80
62
81
- boost::beast::error_code ec;
82
- http_request_parser->put (boost::asio::buffer (incoming_data_buffer, bytes_transferred), ec);
83
63
// no error detected, let's parse the request
84
64
http::compression_type compression_type (http::no_compression);
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
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)
110
73
{
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);
116
74
117
75
boost::system::error_code ec;
118
76
current_request.endpoint = TCP_socket.remote_endpoint (ec).address ();
119
-
120
77
if (ec)
121
78
{
122
79
util::Log (logDEBUG) << " Socket remote endpoint error: " << ec.message ();
@@ -170,6 +127,25 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
170
127
this ->shared_from_this (),
171
128
boost::asio::placeholders::error));
172
129
}
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
+ }
173
149
}
174
150
175
151
// / Handle completion of a write operation.
@@ -182,7 +158,7 @@ void Connection::handle_write(const boost::system::error_code &error)
182
158
--processed_requests;
183
159
current_request = http::request ();
184
160
current_reply = http::reply ();
185
- http_request_parser. emplace ();
161
+ request_parser = RequestParser ();
186
162
incoming_data_buffer = boost::array<char , 8192 >();
187
163
output_buffer.clear ();
188
164
this ->start ();
@@ -244,15 +220,5 @@ std::vector<char> Connection::compress_buffers(const std::vector<char> &uncompre
244
220
245
221
return compressed_data;
246
222
}
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
-
257
223
} // namespace server
258
224
} // namespace osrm
0 commit comments