1313
1414namespace boost {namespace network {namespace http {namespace impl {
1515template <class Tag ,unsigned version_major,unsigned version_minor>
16- struct sync_connection_base ;
17-
18- template <class Tag ,unsigned version_major,unsigned version_minor>
19- struct https_sync_connection :public virtual sync_connection_base<Tag,version_major,version_minor>, detail::connection_helper<Tag, version_major, version_minor> {
20- typedef typename resolver_policy<Tag>::type resolver_base;
21- typedef typename resolver_base::resolver_type resolver_type;
22- typedef typename string<Tag>::type string_type;
23- typedef function<typename resolver_base::resolver_iterator_pair (resolver_type&, string_typeconst &, string_typeconst &)> resolver_function_type;
24-
25- https_sync_connection (resolver_type & resolver, resolver_function_type resolve)
26- : resolver_(resolver), resolve_(resolve), context_(resolver.io_service(), boost::asio::ssl::context::sslv23_client), socket_(resolver.io_service(), context_) { }
27-
28- void init_socket (string_typeconst & hostname, string_typeconst & port) {}
29- void send_request_impl (string_typeconst & method, basic_request<Tag>const & request_) {}
30- void read_status (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
31- void read_headers (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
32- void read_body (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
33- bool is_open () {return socket_.lowest_layer ().is_open (); }
34- void close_socket () {if (is_open ()) { socket_.lowest_layer ().close (); } }
35- ~https_sync_connection () {}
36- private:
37- resolver_type & resolver_;
38- resolver_function_type resolve_;
39- boost::asio::ssl::context context_;
40- boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
41-
42- };
43-
44- template <class Tag ,unsigned version_major,unsigned version_minor>
45- struct http_sync_connection :public virtual sync_connection_base<Tag, version_major, version_minor>, detail::connection_helper<Tag, version_major, version_minor> {
16+ struct connection_base_impl {
17+ protected:
4618typedef typename resolver_policy<Tag>::type resolver_base;
4719typedef typename resolver_base::resolver_type resolver_type;
4820typedef typename string<Tag>::type string_type;
4921typedef function<typename resolver_base::resolver_iterator_pair (resolver_type&, string_typeconst &, string_typeconst &)> resolver_function_type;
5022
51- http_sync_connection (resolver_type & resolver, resolver_function_type resolve)
52- : resolver_(resolver), resolve_(resolve), socket_(resolver.io_service()) { }
53-
54- ~http_sync_connection () {}
55-
56- void init_socket (string_typeconst & hostname, string_typeconst & port) {
23+ template <class Socket >
24+ void init_socket (Socket & socket_, resolver_type & resolver_, string_typeconst & hostname, string_typeconst & port, resolver_function_type resolve_) {
5725using boost::asio::ip::tcp;
5826 boost::system::error_code error = boost::asio::error::host_not_found;
5927typename resolver_type::iterator endpoint_iterator, end;
@@ -74,13 +42,8 @@ namespace boost { namespace network { namespace http { namespace impl {
7442throw boost::system::system_error (error);
7543 }
7644
77- void send_request_impl (string_typeconst & method, basic_request<Tag>const & request_) {
78- boost::asio::streambuf request_buffer;
79- create_request (request_buffer, method, request_);
80- write (socket_, request_buffer);
81- }
82-
83- void read_status (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
45+ template <class Socket >
46+ void read_status (Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
8447boost::asio::read_until (socket_, response_buffer," \r\n " );
8548 std::istreamresponse_stream (&response_buffer);
8649 string_type http_version;
@@ -100,7 +63,8 @@ namespace boost { namespace network { namespace http { namespace impl {
10063 response_.status_message () = status_message;
10164 }
10265
103- void read_headers (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
66+ template <class Socket >
67+ void read_headers (Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
10468boost::asio::read_until (socket_, response_buffer," \r\n\r\n " );
10569 std::istreamresponse_stream (&response_buffer);
10670 string_type header_line, name;
@@ -124,7 +88,13 @@ namespace boost { namespace network { namespace http { namespace impl {
12488 };
12589 }
12690
127- void read_body (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
91+ template <class Socket >
92+ void send_request_impl (Socket & socket_, string_typeconst & method, boost::asio::streambuf & request_buffer) {
93+ write (socket_, request_buffer);
94+ }
95+
96+ template <class Socket >
97+ void read_body (Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
12898typename ostringstream<Tag>::type body_stream;
12999
130100if (response_buffer.size () >0 )
@@ -159,6 +129,108 @@ namespace boost { namespace network { namespace http { namespace impl {
159129 response_ <<body (body_stream.str ());
160130 }
161131
132+
133+ };
134+
135+ template <class Tag ,unsigned version_major,unsigned version_minor>
136+ struct sync_connection_base ;
137+
138+ template <class Tag ,unsigned version_major,unsigned version_minor>
139+ struct https_sync_connection :public virtual sync_connection_base<Tag,version_major,version_minor>, detail::connection_helper<Tag, version_major, version_minor>, connection_base_impl<Tag, version_major, version_minor> {
140+ typedef typename resolver_policy<Tag>::type resolver_base;
141+ typedef typename resolver_base::resolver_type resolver_type;
142+ typedef typename string<Tag>::type string_type;
143+ typedef function<typename resolver_base::resolver_iterator_pair (resolver_type&, string_typeconst &, string_typeconst &)> resolver_function_type;
144+ typedef connection_base_impl<Tag,version_major,version_minor> connection_base;
145+
146+ https_sync_connection (resolver_type & resolver, resolver_function_type resolve, optional<string_type>const & certificate_filename = optional<string_type>())
147+ : connection_base(), resolver_(resolver), resolve_(resolve), context_(resolver.io_service(), boost::asio::ssl::context::sslv23_client), socket_(resolver.io_service(), context_) {
148+ if (certificate_filename) {
149+ context_.set_verify_mode (boost::asio::ssl::context::verify_peer);
150+ context_.load_verify_file (*certificate_filename);
151+ }else {
152+ context_.set_verify_mode (boost::asio::ssl::context::verify_none);
153+ }
154+ }
155+
156+ void init_socket (string_typeconst & hostname, string_typeconst & port) {
157+ connection_base::init_socket (socket_.lowest_layer (), resolver_, hostname, port, resolve_);
158+ socket_.handshake (boost::asio::ssl::stream_base::client);
159+ }
160+
161+ void send_request_impl (string_typeconst & method, basic_request<Tag>const & request_) {
162+ boost::asio::streambuf request_buffer;
163+ create_request (request_buffer, method, request_);
164+ connection_base::send_request_impl (socket_, method, request_buffer);
165+ }
166+
167+ void read_status (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
168+ connection_base::read_status (socket_, response_, response_buffer);
169+ }
170+
171+ void read_headers (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
172+ connection_base::read_headers (socket_, response_, response_buffer);
173+ }
174+
175+ void read_body (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
176+ connection_base::read_body (socket_, response_, response_buffer);
177+ }
178+
179+ bool is_open () {
180+ return socket_.lowest_layer ().is_open ();
181+ }
182+
183+ void close_socket () {
184+ if (is_open ()) {
185+ socket_.lowest_layer ().close ();
186+ }
187+ }
188+
189+ ~https_sync_connection () {}
190+
191+ private:
192+ resolver_type & resolver_;
193+ resolver_function_type resolve_;
194+ boost::asio::ssl::context context_;
195+ boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
196+
197+ };
198+
199+ template <class Tag ,unsigned version_major,unsigned version_minor>
200+ struct http_sync_connection :public virtual sync_connection_base<Tag, version_major, version_minor>, detail::connection_helper<Tag, version_major, version_minor>, connection_base_impl<Tag, version_major, version_minor> {
201+ typedef typename resolver_policy<Tag>::type resolver_base;
202+ typedef typename resolver_base::resolver_type resolver_type;
203+ typedef typename string<Tag>::type string_type;
204+ typedef function<typename resolver_base::resolver_iterator_pair (resolver_type&, string_typeconst &, string_typeconst &)> resolver_function_type;
205+ typedef connection_base_impl<Tag,version_major,version_minor> connection_base;
206+
207+ http_sync_connection (resolver_type & resolver, resolver_function_type resolve)
208+ : connection_base(), resolver_(resolver), resolve_(resolve), socket_(resolver.io_service()) { }
209+
210+ ~http_sync_connection () {}
211+
212+ void init_socket (string_typeconst & hostname, string_typeconst & port) {
213+ connection_base::init_socket (socket_, resolver_, hostname, port, resolve_);
214+ }
215+
216+ void send_request_impl (string_typeconst & method, basic_request<Tag>const & request_) {
217+ boost::asio::streambuf request_buffer;
218+ create_request (request_buffer, method, request_);
219+ connection_base::send_request_impl (socket_, method, request_buffer);
220+ }
221+
222+ void read_status (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
223+ connection_base::read_status (socket_, response_, response_buffer);
224+ }
225+
226+ void read_headers (basic_response<Tag> & response, boost::asio::streambuf & response_buffer) {
227+ connection_base::read_headers (socket_, response, response_buffer);
228+ }
229+
230+ void read_body (basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
231+ connection_base::read_body (socket_, response_, response_buffer);
232+ }
233+
162234bool is_open () {return socket_.is_open (); }
163235
164236void close_socket () {if (is_open ()) { socket_.close (); } }