Skip to content

Commit ddd7889

Browse files
committed
Refactoring out resolver policy, using tag dispatching trait to choose correct implementation.
1 parent 7906db1 commit ddd7889

File tree

6 files changed

+168
-86
lines changed

6 files changed

+168
-86
lines changed

boost/network/message.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
// Copyright Dean Michael Berris 2007.
32
// Distributed under the Boost Software License, Version 1.0.
43
// (See accompanying file LICENSE_1_0.txt or copy at

boost/network/protocol/http/client.hpp

Lines changed: 36 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
// Copyright Dean Michael Berris 2007-2008.
2+
// Copyright Dean Michael Berris 2007-2009.
33
// Distributed under the Boost Software License, Version 1.0.
44
// (See accompanying file LICENSE_1_0.txt or copy at
55
// http://www.boost.org/LICENSE_1_0.txt)
@@ -8,13 +8,14 @@
88
#define __NETWORK_PROTOCOL_HTTP_CLIENT_20070908_1_HPP__
99

1010
#ifndef BOOST_NETLIB_VERSION
11-
#define BOOST_NETLIB_VERSION "0.3"
11+
#define BOOST_NETLIB_VERSION "0.5"
1212
#endif
1313

1414
#include <boost/network/traits/ostringstream.hpp>
1515
#include <boost/network/protocol/http/message.hpp>
1616
#include <boost/network/protocol/http/response.hpp>
1717
#include <boost/network/protocol/http/request.hpp>
18+
#include <boost/network/protocol/http/traits/resolver_policy.hpp>
1819
#include <boost/asio.hpp>
1920
#include <boost/lexical_cast.hpp>
2021
#include <boost/algorithm/string/classification.hpp>
@@ -29,71 +30,24 @@
2930

3031
namespace boost { namespace network { namespace http {
3132

32-
template <class tag, unsigned version_major, unsigned version_minor>
33-
class basic_client {
33+
template <class Tag, unsigned version_major, unsigned version_minor>
34+
class basic_client : resolver_policy<Tag>::type {
3435

3536
private:
37+
typedef typename resolver_policy<Tag>::type resolver_base;
3638
boost::asio::io_service service_;
37-
boost::asio::ip::tcp::resolver resolver_;
38-
bool cache_resolved_;
39+
typename resolver_base::resolver_type resolver_;
3940
bool follow_redirect_;
4041

41-
typedef std::pair<
42-
boost::asio::ip::tcp::resolver::iterator,
43-
boost::asio::ip::tcp::resolver::iterator
44-
> resolver_iterator_pair;
45-
46-
typedef typename string<tag>::type string_type;
47-
48-
typedef std::map<string_type, resolver_iterator_pair> resolved_cache;
49-
resolved_cache endpoint_cache_;
50-
51-
resolver_iterator_pair resolve(string_type const & hostname, string_type const & port) {
52-
if (cache_resolved_) {
53-
typename resolved_cache::iterator cached_iterator =
54-
endpoint_cache_.find(hostname);
55-
if (cached_iterator == endpoint_cache_.end()) {
56-
bool inserted = false;
57-
boost::tie(cached_iterator, inserted) =
58-
endpoint_cache_.insert(
59-
std::make_pair(
60-
hostname,
61-
std::make_pair(
62-
resolver_.resolve(
63-
boost::asio::ip::tcp::resolver::query(
64-
hostname,
65-
port,
66-
boost::asio::ip::tcp::resolver_query::numeric_service
67-
)
68-
)
69-
, boost::asio::ip::tcp::resolver::iterator()
70-
)
71-
)
72-
);
73-
};
74-
return cached_iterator->second;
75-
};
76-
77-
return std::make_pair(
78-
resolver_.resolve(
79-
boost::asio::ip::tcp::resolver::query(
80-
hostname,
81-
port,
82-
boost::asio::ip::tcp::resolver_query::numeric_service
83-
)
84-
)
85-
,
86-
boost::asio::ip::tcp::resolver::iterator()
87-
);
88-
};
42+
typedef typename string<Tag>::type string_type;
8943

9044
void init_socket(boost::asio::ip::tcp::socket & socket_, string_type const & hostname, string_type const & port) {
9145
using boost::asio::ip::tcp;
9246

9347
boost::system::error_code error = boost::asio::error::host_not_found;
9448

9549
tcp::resolver::iterator endpoint_iterator, end;
96-
boost::tie(endpoint_iterator, end) = resolve(hostname, port);
50+
boost::tie(endpoint_iterator, end) = resolve(resolver_, hostname, port);
9751

9852
while (error && endpoint_iterator != end) {
9953
socket_.close();
@@ -104,7 +58,7 @@ namespace boost { namespace network { namespace http {
10458
throw boost::system::system_error(error);
10559
};
10660

107-
void create_request(boost::asio::streambuf & request_buffer, string_type const & method, basic_request<tag> request_) const {
61+
void create_request(boost::asio::streambuf & request_buffer, string_type const & method, basic_request<Tag> request_) const {
10862
std::ostream request_stream(&request_buffer);
10963

11064
request_stream
@@ -139,8 +93,7 @@ namespace boost { namespace network { namespace http {
13993
};
14094

14195
range = headers(request_)["user-agent"];
142-
if (begin(range) == end(range))
143-
request_stream << "User-Agent: cpp-netlib/" << BOOST_NETLIB_VERSION << "\r\n";
96+
if (begin(range) == end(range)) request_stream << "User-Agent: cpp-netlib/" << BOOST_NETLIB_VERSION << "\r\n";
14497

14598
request_stream
14699
<< "Connection: close\r\n\r\n";
@@ -150,13 +103,13 @@ namespace boost { namespace network { namespace http {
150103
request_stream << body_;
151104
};
152105

153-
void send_request(boost::asio::ip::tcp::socket & socket, string_type const & method, basic_request<tag> const & request_) const {
106+
void send_request(boost::asio::ip::tcp::socket & socket, string_type const & method, basic_request<Tag> const & request_) const {
154107
boost::asio::streambuf request_buffer;
155108
create_request(request_buffer, method, request_);
156109
write(socket, request_buffer);
157110
};
158111

159-
void read_status(basic_response<tag> & response_, boost::asio::ip::tcp::socket & socket, boost::asio::streambuf & response_buffer) const {
112+
void read_status(basic_response<Tag> & response_, boost::asio::ip::tcp::socket & socket, boost::asio::streambuf & response_buffer) const {
160113
boost::asio::read_until(socket, response_buffer, "\r\n");
161114
std::istream response_stream(&response_buffer);
162115
string_type http_version;
@@ -176,7 +129,7 @@ namespace boost { namespace network { namespace http {
176129
response_.status_message() = status_message;
177130
};
178131

179-
void read_headers(basic_response<tag> & response_, boost::asio::ip::tcp::socket & socket, boost::asio::streambuf & response_buffer) const {
132+
void read_headers(basic_response<Tag> & response_, boost::asio::ip::tcp::socket & socket, boost::asio::streambuf & response_buffer) const {
180133
boost::asio::read_until(socket, response_buffer, "\r\n\r\n");
181134
std::istream response_stream(&response_buffer);
182135
string_type header_line, name;
@@ -200,8 +153,8 @@ namespace boost { namespace network { namespace http {
200153
};
201154
};
202155

203-
void read_body(basic_response<tag> & response_, boost::asio::ip::tcp::socket & socket, boost::asio::streambuf & response_buffer) const {
204-
typename ostringstream<tag>::type body_stream;
156+
void read_body(basic_response<Tag> & response_, boost::asio::ip::tcp::socket & socket, boost::asio::streambuf & response_buffer) const {
157+
typename ostringstream<Tag>::type body_stream;
205158

206159
if (response_buffer.size() > 0)
207160
body_stream << &response_buffer;
@@ -216,17 +169,17 @@ namespace boost { namespace network { namespace http {
216169
response_ << body(body_stream.str());
217170
};
218171

219-
response const sync_request_skeleton(basic_request<tag> const & request_, string_type method, bool get_body) {
172+
response const sync_request_skeleton(basic_request<Tag> const & request_, string_type method, bool get_body) {
220173
using boost::asio::ip::tcp;
221174

222-
basic_request<tag> request_copy(request_);
223-
basic_response<tag> response_;
175+
basic_request<Tag> request_copy(request_);
176+
basic_response<Tag> response_;
224177
do {
225178
tcp::socket socket(service_);
226179
init_socket(socket, request_copy.host(), boost::lexical_cast<string_type>(request_copy.port()));
227180
send_request(socket, method, request_copy);
228181

229-
response_ = basic_response<tag>();
182+
response_ = basic_response<Tag>();
230183
response_ << source(request_copy.host());
231184

232185
boost::asio::streambuf response_buffer;
@@ -269,66 +222,66 @@ namespace boost { namespace network { namespace http {
269222
};
270223

271224
basic_client()
272-
: service_(), resolver_(service_), cache_resolved_(false), follow_redirect_(false)
225+
: resolver_base(false), service_(), resolver_(service_), follow_redirect_(false)
273226
{};
274227

275228
explicit basic_client(cache_resolved_type (*)())
276-
: service_(), resolver_(service_), cache_resolved_(true), follow_redirect_(false)
229+
: resolver_base(true), service_(), resolver_(service_), follow_redirect_(false)
277230
{};
278231

279232
explicit basic_client(follow_redirect_type (*)())
280-
: service_(), resolver_(service_), cache_resolved_(false), follow_redirect_(true)
233+
: resolver_base(false), service_(), resolver_(service_), follow_redirect_(true)
281234
{};
282235

283236
basic_client(cache_resolved_type (*)(), follow_redirect_type (*)())
284-
: service_(), resolver_(service_), cache_resolved_(true), follow_redirect_(true)
237+
: resolver_base(false), service_(), resolver_(service_), follow_redirect_(true)
285238
{};
286239

287240
void clear_resolved_cache() {
288-
endpoint_cache_.clear();
241+
resolver_base::endpoint_cache_.clear();
289242
}
290243

291-
response const head (basic_request<tag> const & request_) {
244+
response const head (basic_request<Tag> const & request_) {
292245
return sync_request_skeleton(request_, "HEAD", false);
293246
};
294247

295-
response const get (basic_request<tag> const & request_) {
248+
response const get (basic_request<Tag> const & request_) {
296249
return sync_request_skeleton(request_, "GET", true);
297250
};
298251

299-
response const post (basic_request<tag> const & request_) {
252+
response const post (basic_request<Tag> const & request_) {
300253
return sync_request_skeleton(request_, "POST", true);
301254
};
302255

303-
response const post (basic_request<tag> const & request_, string_type const & content_type, string_type const & body_) {
304-
basic_request<tag> request_copy = request_;
256+
response const post (basic_request<Tag> const & request_, string_type const & content_type, string_type const & body_) {
257+
basic_request<Tag> request_copy = request_;
305258
request_copy << body(body_)
306259
<< header("Content-Type", content_type)
307260
<< header("Content-Length", boost::lexical_cast<string_type>(body_.size()));
308261
return post(request_copy);
309262
};
310263

311-
response const post (basic_request<tag> const & request_, string_type const & body_) {
264+
response const post (basic_request<Tag> const & request_, string_type const & body_) {
312265
return post(request_, "x-application/octet-stream", body_);
313266
};
314267

315-
response const put (basic_request<tag> const & request_) {
268+
response const put (basic_request<Tag> const & request_) {
316269
return sync_request_skeleton(request_, "PUT", true);
317270
};
318271

319-
response const put (basic_request<tag> const & request_, string_type const & body_) {
272+
response const put (basic_request<Tag> const & request_, string_type const & body_) {
320273
return put(request_, "x-application/octet-stream", body_);
321274
};
322275

323-
response const put (basic_request<tag> const & request_, string_type const & content_type, string_type const & body_) {
324-
basic_request<tag> request_copy = request_;
276+
response const put (basic_request<Tag> const & request_, string_type const & content_type, string_type const & body_) {
277+
basic_request<Tag> request_copy = request_;
325278
request_copy << body(body_)
326279
<< header("Content-Type", content_type)
327280
<< header("Content-Length", boost::lexical_cast<string_type>(body_.size()));
328281
return put(request_copy);
329282
};
330283

331-
response const delete_ (basic_request<tag> const & request_) {
284+
response const delete_ (basic_request<Tag> const & request_) {
332285
return sync_request_skeleton(request_, "DELETE", true);
333286
};
334287

boost/network/protocol/http/client_fwd.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
#define __NETWORK_PROTOCOL_HTTP_CLIENT_20080923_1_HPP__
99

1010
#ifndef BOOST_NETLIB_VERSION
11-
#define BOOST_NETLIB_VERSION "0.3"
11+
#define BOOST_NETLIB_VERSION "0.5"
1212
#endif
1313

1414
#include <boost/network/tags.hpp>
1515

1616
namespace boost { namespace network { namespace http {
1717

1818
//! Forward declaration of basic_client template.
19-
template <class tag, unsigned version_major, unsigned version_minor>
19+
template <class Tag, unsigned version_major, unsigned version_minor>
2020
class basic_client;
2121

2222
typedef basic_client<tags::http, 1, 0> client;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_CLIENT_IPP
2+
#define BOOST_NETWORK_PROTOCOL_HTTP_IMPL_CLIENT_IPP
3+
4+
namespace boost { namespace network { namespace http {
5+
6+
7+
} // namespace http
8+
9+
} // namespace network
10+
11+
} // namespace boost
12+
13+
#endif // BOOST_NETWORK_PROTOCOL_HTTP_IMPL_CLIENT_IPP
14+
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214
2+
#define BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214
3+
4+
// Copyright Dean Michael Berris 2009.
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// (See accompanying file LICENSE_1_0.txt or copy at
7+
// http://www.boost.org/LICENSE_1_0.txt)
8+
9+
#include <utility>
10+
#include <boost/asio.hpp>
11+
12+
namespace boost { namespace network { namespace http { namespace policies {
13+
14+
template <class Tag>
15+
struct sync_resolver {
16+
17+
typedef boost::asio::ip::tcp::resolver resolver_type;
18+
19+
protected:
20+
21+
typedef std::pair<
22+
boost::asio::ip::tcp::resolver::iterator,
23+
boost::asio::ip::tcp::resolver::iterator
24+
> resolver_iterator_pair;
25+
typedef typename string<Tag>::type string_type;
26+
typedef std::map<string_type, resolver_iterator_pair> resolved_cache;
27+
resolved_cache endpoint_cache_;
28+
bool cache_resolved_;
29+
30+
sync_resolver(bool cache_resolved) : cache_resolved_(cache_resolved) {}
31+
32+
resolver_iterator_pair resolve(resolver_type & resolver_, string_type const & hostname, string_type const & port) {
33+
if (cache_resolved_) {
34+
typename resolved_cache::iterator cached_iterator =
35+
endpoint_cache_.find(hostname);
36+
if (cached_iterator == endpoint_cache_.end()) {
37+
bool inserted = false;
38+
boost::fusion::tie(cached_iterator, inserted) =
39+
endpoint_cache_.insert(
40+
std::make_pair(
41+
hostname,
42+
std::make_pair(
43+
resolver_.resolve(
44+
boost::asio::ip::tcp::resolver::query(
45+
hostname,
46+
port,
47+
boost::asio::ip::tcp::resolver_query::numeric_service
48+
)
49+
)
50+
, boost::asio::ip::tcp::resolver::iterator()
51+
)
52+
)
53+
);
54+
};
55+
return cached_iterator->second;
56+
};
57+
58+
return std::make_pair(
59+
resolver_.resolve(
60+
boost::asio::ip::tcp::resolver::query(
61+
hostname,
62+
port,
63+
boost::asio::ip::tcp::resolver_query::numeric_service
64+
)
65+
)
66+
,
67+
boost::asio::ip::tcp::resolver::iterator()
68+
);
69+
};
70+
71+
};
72+
73+
} // namespace policies
74+
75+
} // namespace http
76+
77+
} // namespace network
78+
79+
} // namespace boost
80+
81+
#endif // BOOST_NETWORK_PROTOCOL_HTTP_POLICIES_SYNC_RESOLVER_20091214
82+

0 commit comments

Comments
 (0)