Skip to content

Commit f7679a7

Browse files
author
Dean Michael Berris
committed
Partial integration of incremental response parser into the asynchronous client.
1 parent 094683a commit f7679a7

File tree

4 files changed

+113
-54
lines changed

4 files changed

+113
-54
lines changed

boost/network/protocol/http/impl/http_async_connection.hpp

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
#include <boost/throw_exception.hpp>
1313
#include <boost/cstdint.hpp>
1414
#include <boost/range/algorithm/transform.hpp>
15+
#include <boost/algorithm/string/trim.hpp>
1516
#include <boost/network/constants.hpp>
1617
#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>
1821
#include <iterator>
1922

2023
namespace boost { namespace network { namespace http { namespace impl {
@@ -209,14 +212,12 @@ namespace boost { namespace network { namespace http { namespace impl {
209212

210213
void handle_sent_request(string_type method, boost::system::error_code const & ec, std::size_t bytes_transferred) {
211214
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(
214216
*socket_,
215217
response_buffer_,
216-
version_pattern,
217218
request_strand_->wrap(
218219
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,
220221
http_async_connection<Tag,version_major,version_minor>::shared_from_this(),
221222
method, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
222223
} else {
@@ -233,9 +234,44 @@ namespace boost { namespace network { namespace http { namespace impl {
233234
}
234235
}
235236

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) {
237238
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+
}
239275
}
240276
}
241277

@@ -247,6 +283,8 @@ namespace boost { namespace network { namespace http { namespace impl {
247283
//FIXME -- wire the correct parameters
248284
}
249285

286+
typedef response_parser<Tag> response_parser_type;
287+
250288
boost::shared_ptr<resolver_type> resolver_;
251289
resolve_function resolve_;
252290
bool follow_redirect_;
@@ -261,6 +299,8 @@ namespace boost { namespace network { namespace http { namespace impl {
261299
boost::promise<string_type> body_promise;
262300
string_type command_string_;
263301
boost::asio::streambuf response_buffer_;
302+
response_parser_type response_parser;
303+
string_type part;
264304
};
265305

266306
} // namespace impl

boost/network/traits/char.hpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,27 @@
77
#define BOOST_NETWORK_TRAITS_CHAR_HPP
88

99
#include <boost/network/tags.hpp>
10+
#include <boost/network/support/is_default_string.hpp>
11+
#include <boost/network/support/is_default_wstring.hpp>
12+
#include <boost/mpl/if.hpp>
1013

1114
namespace boost { namespace network {
1215

1316
template <class Tag>
1417
struct unsupported_tag;
1518

1619
template <class Tag>
17-
struct char_ {
18-
typedef unsupported_tag<Tag> type;
19-
};
20-
21-
template <>
22-
struct char_<tags::http_default_8bit_tcp_resolve> {
23-
typedef char type;
24-
};
25-
26-
template <>
27-
struct char_<tags::http_default_8bit_udp_resolve> {
28-
typedef char type;
29-
};
20+
struct char_ :
21+
mpl::if_<
22+
is_default_string<Tag>,
23+
char,
24+
typename mpl::if_<
25+
is_default_wstring<Tag>,
26+
wchar_t,
27+
unsupported_tag<Tag>
28+
>::type
29+
>
30+
{};
3031

3132
} // namespace network
3233

boost/network/traits/istream.hpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
#ifndef BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924
3+
#define BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924
4+
5+
// Copyright 2010 (C) Dean Michael Berris
6+
// Distributed under the Boost Software License, Version 1.0.
7+
// (See accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
10+
#include <boost/network/support/is_default_string.hpp>
11+
#include <boost/network/support/is_default_wstring.hpp>
12+
#include <boost/network/traits/char.hpp>
13+
#include <boost/mpl/if.hpp>
14+
#include <istream>
15+
16+
namespace boost { namespace network {
17+
18+
template <class Tag>
19+
struct unsupported_tag;
20+
21+
template <class Tag>
22+
struct istream :
23+
mpl::if_<
24+
is_default_string<Tag>,
25+
std::istream,
26+
typename mpl::if_<
27+
is_default_wstring<Tag>,
28+
std::wistream,
29+
unsupported_tag<Tag>
30+
>::type
31+
>
32+
{};
33+
34+
} /* network */
35+
36+
} /* boost */
37+
38+
#endif /* BOOST_NETWORK_TRAITS_ISTREAM_HPP_20100924 */

boost/network/traits/istringstream.hpp

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,27 @@
99

1010
# include <sstream>
1111
# include <boost/network/tags.hpp>
12+
#include <boost/network/support/is_default_string.hpp>
13+
#include <boost/network/support/is_default_wstring.hpp>
14+
#include <boost/mpl/if.hpp>
1215

1316
namespace boost { namespace network {
1417

1518
template <class Tag>
1619
struct unsupported_tag;
1720

1821
template <class Tag>
19-
struct istringstream {
20-
typedef unsupported_tag<Tag> type;
21-
};
22-
23-
template <>
24-
struct istringstream<tags::default_string> {
25-
typedef std::istringstream type;
26-
};
27-
28-
29-
template <>
30-
struct istringstream<tags::default_wstring> {
31-
typedef std::wistringstream type;
32-
};
33-
34-
template <>
35-
struct istringstream<tags::http_default_8bit_tcp_resolve> {
36-
typedef std::istringstream type;
37-
};
38-
39-
template <>
40-
struct istringstream<tags::http_default_8bit_udp_resolve> {
41-
typedef std::istringstream type;
42-
};
43-
44-
template <>
45-
struct istringstream<tags::http_keepalive_8bit_tcp_resolve> {
46-
typedef std::istringstream type;
47-
};
48-
49-
template <>
50-
struct istringstream<tags::http_keepalive_8bit_udp_resolve> {
51-
typedef std::istringstream type;
52-
};
22+
struct istringstream :
23+
mpl::if_<
24+
is_default_string<Tag>,
25+
std::istringstream,
26+
typename mpl::if_<
27+
is_default_wstring<Tag>,
28+
std::basic_istringstream<wchar_t>,
29+
unsupported_tag<Tag>
30+
>::type
31+
>
32+
{};
5333

5434
} // namespace network
5535

0 commit comments

Comments
 (0)