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)
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>
2930
3031namespace 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
0 commit comments