12
12
#include < boost/throw_exception.hpp>
13
13
#include < boost/cstdint.hpp>
14
14
#include < boost/range/algorithm/transform.hpp>
15
+ #include < boost/algorithm/string/trim.hpp>
15
16
#include < boost/network/constants.hpp>
16
17
#include < boost/network/traits/ostream_iterator.hpp>
17
- #include < boost/regex.hpp>
18
+ #include < boost/network/traits/istream.hpp>
19
+ #include < boost/logic/tribool.hpp>
20
+ #include < boost/network/protocol/http/parser/incremental.hpp>
18
21
#include < iterator>
19
22
20
23
namespace boost { namespace network { namespace http { namespace impl {
@@ -209,14 +212,12 @@ namespace boost { namespace network { namespace http { namespace impl {
209
212
210
213
void handle_sent_request (string_type method, boost::system::error_code const & ec, std::size_t bytes_transferred) {
211
214
if (!ec) {
212
- static boost::regex const version_pattern (" HTTP/\\ d+\\ .\\ d+\\ s\\ d{3}\\ s[\\ w\\ s\\ d]+\\ r\\ n" );
213
- boost::asio::async_read_until (
215
+ boost::asio::async_read (
214
216
*socket_,
215
217
response_buffer_,
216
- version_pattern,
217
218
request_strand_->wrap (
218
219
boost::bind (
219
- &http_async_connection<Tag,version_major,version_minor>::handle_received_status ,
220
+ &http_async_connection<Tag,version_major,version_minor>::handle_received_version ,
220
221
http_async_connection<Tag,version_major,version_minor>::shared_from_this (),
221
222
method, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
222
223
} else {
@@ -233,9 +234,44 @@ namespace boost { namespace network { namespace http { namespace impl {
233
234
}
234
235
}
235
236
236
- void handle_received_status (string_type method, boost::system::error_code const & ec, std::size_t bytes_transferred) {
237
+ void handle_received_version (string_type method, boost::system::error_code const & ec, std::size_t bytes_transferred) {
237
238
if (!ec) {
238
- // FIXME -- make it happen
239
+ logic::tribool parsed_ok;
240
+ typename response_parser_type::range_type result_range;
241
+ typename istream<Tag>::type input_stream (&response_buffer_);
242
+ part.append (
243
+ std::istream_iterator<typename char_<Tag>::type>(input_stream)
244
+ , std::istream_iterator<typename char_<Tag>::type>()
245
+ );
246
+ fusion::tie (parsed_ok, result_range) = response_parser.parse_until (
247
+ response_parser_type::http_version_done,
248
+ part);
249
+ if (parsed_ok == true ) {
250
+ string_type version (boost::begin (result_range), boost::end (result_range));
251
+ algorithm::trim (version);
252
+ version_promise.set_value (version);
253
+ typename string_type::const_iterator end = part.end ();
254
+ part.assign (boost::end (result_range), end);
255
+ } else if (parsed_ok == false ) {
256
+ // FIXME create proper errors, use Boost.System errors and categories
257
+ std::runtime_error error (" Invalid Version Part." );
258
+ version_promise.set_exception (boost::copy_exception (error));
259
+ status_promise.set_exception (boost::copy_exception (error));
260
+ status_message_promise.set_exception (boost::copy_exception (error));
261
+ headers_promise.set_exception (boost::copy_exception (error));
262
+ source_promise.set_exception (boost::copy_exception (error));
263
+ destination_promise.set_exception (boost::copy_exception (error));
264
+ body_promise.set_exception (boost::copy_exception (error));
265
+ } else {
266
+ boost::asio::async_read (
267
+ *socket_,
268
+ response_buffer_,
269
+ request_strand_->wrap (
270
+ boost::bind (
271
+ &http_async_connection<Tag,version_major,version_minor>::handle_received_version,
272
+ http_async_connection<Tag,version_major,version_minor>::shared_from_this (),
273
+ method, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
274
+ }
239
275
}
240
276
}
241
277
@@ -247,6 +283,8 @@ namespace boost { namespace network { namespace http { namespace impl {
247
283
// FIXME -- wire the correct parameters
248
284
}
249
285
286
+ typedef response_parser<Tag> response_parser_type;
287
+
250
288
boost::shared_ptr<resolver_type> resolver_;
251
289
resolve_function resolve_;
252
290
bool follow_redirect_;
@@ -261,6 +299,8 @@ namespace boost { namespace network { namespace http { namespace impl {
261
299
boost::promise<string_type> body_promise;
262
300
string_type command_string_;
263
301
boost::asio::streambuf response_buffer_;
302
+ response_parser_type response_parser;
303
+ string_type part;
264
304
};
265
305
266
306
} // namespace impl
0 commit comments