1
1
2
- // Copyright Dean Michael Berris 2007-2008 .
2
+ // Copyright Dean Michael Berris 2007-2009 .
3
3
// Distributed under the Boost Software License, Version 1.0.
4
4
// (See accompanying file LICENSE_1_0.txt or copy at
5
5
// http://www.boost.org/LICENSE_1_0.txt)
8
8
#define __NETWORK_PROTOCOL_HTTP_CLIENT_20070908_1_HPP__
9
9
10
10
#ifndef BOOST_NETLIB_VERSION
11
- #define BOOST_NETLIB_VERSION " 0.3 "
11
+ #define BOOST_NETLIB_VERSION " 0.5 "
12
12
#endif
13
13
14
14
#include < boost/network/traits/ostringstream.hpp>
15
15
#include < boost/network/protocol/http/message.hpp>
16
16
#include < boost/network/protocol/http/response.hpp>
17
17
#include < boost/network/protocol/http/request.hpp>
18
+ #include < boost/network/protocol/http/traits/resolver_policy.hpp>
18
19
#include < boost/asio.hpp>
19
20
#include < boost/lexical_cast.hpp>
20
21
#include < boost/algorithm/string/classification.hpp>
29
30
30
31
namespace boost { namespace network { namespace http {
31
32
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 {
34
35
35
36
private:
37
+ typedef typename resolver_policy<Tag>::type resolver_base;
36
38
boost::asio::io_service service_;
37
- boost::asio::ip::tcp::resolver resolver_;
38
- bool cache_resolved_;
39
+ typename resolver_base::resolver_type resolver_;
39
40
bool follow_redirect_;
40
41
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;
89
43
90
44
void init_socket (boost::asio::ip::tcp::socket & socket_, string_type const & hostname, string_type const & port) {
91
45
using boost::asio::ip::tcp;
92
46
93
47
boost::system::error_code error = boost::asio::error::host_not_found;
94
48
95
49
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);
97
51
98
52
while (error && endpoint_iterator != end) {
99
53
socket_.close ();
@@ -104,7 +58,7 @@ namespace boost { namespace network { namespace http {
104
58
throw boost::system::system_error (error);
105
59
};
106
60
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 {
108
62
std::ostream request_stream (&request_buffer);
109
63
110
64
request_stream
@@ -139,8 +93,7 @@ namespace boost { namespace network { namespace http {
139
93
};
140
94
141
95
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 " ;
144
97
145
98
request_stream
146
99
<< " Connection: close\r\n\r\n " ;
@@ -150,13 +103,13 @@ namespace boost { namespace network { namespace http {
150
103
request_stream << body_;
151
104
};
152
105
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 {
154
107
boost::asio::streambuf request_buffer;
155
108
create_request (request_buffer, method, request_);
156
109
write (socket, request_buffer);
157
110
};
158
111
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 {
160
113
boost::asio::read_until (socket, response_buffer, " \r\n " );
161
114
std::istream response_stream (&response_buffer);
162
115
string_type http_version;
@@ -176,7 +129,7 @@ namespace boost { namespace network { namespace http {
176
129
response_.status_message () = status_message;
177
130
};
178
131
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 {
180
133
boost::asio::read_until (socket, response_buffer, " \r\n\r\n " );
181
134
std::istream response_stream (&response_buffer);
182
135
string_type header_line, name;
@@ -200,8 +153,8 @@ namespace boost { namespace network { namespace http {
200
153
};
201
154
};
202
155
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;
205
158
206
159
if (response_buffer.size () > 0 )
207
160
body_stream << &response_buffer;
@@ -216,17 +169,17 @@ namespace boost { namespace network { namespace http {
216
169
response_ << body (body_stream.str ());
217
170
};
218
171
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) {
220
173
using boost::asio::ip::tcp;
221
174
222
- basic_request<tag > request_copy (request_);
223
- basic_response<tag > response_;
175
+ basic_request<Tag > request_copy (request_);
176
+ basic_response<Tag > response_;
224
177
do {
225
178
tcp::socket socket (service_);
226
179
init_socket (socket, request_copy.host (), boost::lexical_cast<string_type>(request_copy.port ()));
227
180
send_request (socket, method, request_copy);
228
181
229
- response_ = basic_response<tag >();
182
+ response_ = basic_response<Tag >();
230
183
response_ << source (request_copy.host ());
231
184
232
185
boost::asio::streambuf response_buffer;
@@ -269,66 +222,66 @@ namespace boost { namespace network { namespace http {
269
222
};
270
223
271
224
basic_client ()
272
- : service_( ), resolver_( service_), cache_resolved_( false ), follow_redirect_(false )
225
+ : resolver_base( false ), service_( ), resolver_(service_ ), follow_redirect_(false )
273
226
{};
274
227
275
228
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 )
277
230
{};
278
231
279
232
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 )
281
234
{};
282
235
283
236
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 )
285
238
{};
286
239
287
240
void clear_resolved_cache () {
288
- endpoint_cache_.clear ();
241
+ resolver_base:: endpoint_cache_.clear ();
289
242
}
290
243
291
- response const head (basic_request<tag > const & request_) {
244
+ response const head (basic_request<Tag > const & request_) {
292
245
return sync_request_skeleton (request_, " HEAD" , false );
293
246
};
294
247
295
- response const get (basic_request<tag > const & request_) {
248
+ response const get (basic_request<Tag > const & request_) {
296
249
return sync_request_skeleton (request_, " GET" , true );
297
250
};
298
251
299
- response const post (basic_request<tag > const & request_) {
252
+ response const post (basic_request<Tag > const & request_) {
300
253
return sync_request_skeleton (request_, " POST" , true );
301
254
};
302
255
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_;
305
258
request_copy << body (body_)
306
259
<< header (" Content-Type" , content_type)
307
260
<< header (" Content-Length" , boost::lexical_cast<string_type>(body_.size ()));
308
261
return post (request_copy);
309
262
};
310
263
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_) {
312
265
return post (request_, " x-application/octet-stream" , body_);
313
266
};
314
267
315
- response const put (basic_request<tag > const & request_) {
268
+ response const put (basic_request<Tag > const & request_) {
316
269
return sync_request_skeleton (request_, " PUT" , true );
317
270
};
318
271
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_) {
320
273
return put (request_, " x-application/octet-stream" , body_);
321
274
};
322
275
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_;
325
278
request_copy << body (body_)
326
279
<< header (" Content-Type" , content_type)
327
280
<< header (" Content-Length" , boost::lexical_cast<string_type>(body_.size ()));
328
281
return put (request_copy);
329
282
};
330
283
331
- response const delete_ (basic_request<tag > const & request_) {
284
+ response const delete_ (basic_request<Tag > const & request_) {
332
285
return sync_request_skeleton (request_, " DELETE" , true );
333
286
};
334
287
0 commit comments