@@ -22,33 +22,50 @@ namespace network {
2222namespace v2 {
2323using boost::asio::ip::tcp;
2424
25+ struct request_helper {
26+
27+ client::request request_;
28+ client::request_options options_;
29+
30+ request_helper (client::request request, client::request_options options)
31+ : request_(request)
32+ , options_(options) { }
33+
34+ };
35+
2536struct client ::impl {
2637
2738explicit impl (client_options options);
2839
2940~impl ()noexcept ;
3041
3142void connect (const boost::system::error_code &ec,
32- tcp::resolver::iterator endpoint_iterator);
43+ tcp::resolver::iterator endpoint_iterator,
44+ std::shared_ptr<request_helper> helper);
3345
34- void write_request (const boost::system::error_code &ec);
46+ void write_request (const boost::system::error_code &ec,
47+ std::shared_ptr<request_helper> helper);
3548
3649void read_response (const boost::system::error_code &ec,
37- std::size_t bytes_written);
50+ std::size_t bytes_written,
51+ std::shared_ptr<request_helper> helper);
3852
3953void read_response_status (const boost::system::error_code &ec,
4054 std::size_t bytes_written,
55+ std::shared_ptr<request_helper> helper,
4156 std::shared_ptr<response> res);
4257
4358void read_response_headers (const boost::system::error_code &ec,
4459 std::size_t bytes_read,
60+ std::shared_ptr<request_helper> helper,
4561 std::shared_ptr<response> res);
4662
4763void read_response_body (const boost::system::error_code &ec,
4864 std::size_t bytes_read,
65+ std::shared_ptr<request_helper> helper,
4966 std::shared_ptr<response> res);
5067
51- std::future<response>do_request (method method_,request request_, request_options options );
68+ std::future<response>do_request (method method_,std::shared_ptr<request_helper> helper );
5269
5370client_options options_;
5471boost::asio::io_service io_service_;
@@ -59,11 +76,8 @@ namespace network {
5976std::thread lifetime_thread_;
6077
6178 std::promise<response> response_promise_;
62- boost::asio::streambuf request_;
63- boost::asio::streambuf response_;
64-
65- // promise
66- // future response
79+ boost::asio::streambuf request_buffer_;
80+ boost::asio::streambuf response_buffer_;
6781
6882 };
6983
@@ -83,7 +97,8 @@ namespace network {
8397 }
8498
8599void client::impl::connect (const boost::system::error_code &ec,
86- tcp::resolver::iterator endpoint_iterator) {
100+ tcp::resolver::iterator endpoint_iterator,
101+ std::shared_ptr<request_helper> helper) {
87102if (ec) {
88103if (endpoint_iterator ==tcp::resolver::iterator ()) {
89104 response_promise_.set_exception (std::make_exception_ptr (
@@ -100,52 +115,55 @@ namespace network {
100115 connection_->async_connect (endpoint,
101116 strand_.wrap (
102117 [=] (const boost::system::error_code &ec) {
103- write_request (ec);
118+ write_request (ec, helper );
104119 }));
105120 }
106121
107- void client::impl::write_request (const boost::system::error_code &ec) {
122+ void client::impl::write_request (const boost::system::error_code &ec,
123+ std::shared_ptr<request_helper> helper) {
108124if (ec) {
109125 response_promise_.set_exception (std::make_exception_ptr (
110126std::system_error (ec.value (),std::system_category ())));
111127return ;
112128 }
113129
114- connection_->async_write (request_ ,
130+ connection_->async_write (request_buffer_ ,
115131 strand_.wrap (
116132 [=] (const boost::system::error_code &ec,
117133 std::size_t bytes_written) {
118- read_response (ec, bytes_written);
134+ read_response (ec, bytes_written, helper );
119135 }));
120136 }
121137
122- void client::impl::read_response (const boost::system::error_code &ec, std::size_t ) {
138+ void client::impl::read_response (const boost::system::error_code &ec, std::size_t ,
139+ std::shared_ptr<request_helper> helper) {
123140if (ec) {
124141 response_promise_.set_exception (std::make_exception_ptr (
125142std::system_error (ec.value (),std::system_category ())));
126143return ;
127144 }
128145
129146 std::shared_ptr<response>res (new response{});
130- connection_->async_read_until (response_ ,
147+ connection_->async_read_until (response_buffer_ ,
131148" \r\n " ,
132149 strand_.wrap (
133150 [=] (const boost::system::error_code &ec,
134151 std::size_t bytes_read) {
135- read_response_status (ec, bytes_read, res);
152+ read_response_status (ec, bytes_read,helper, res);
136153 }));
137154 }
138155
139156void client::impl::read_response_status (const boost::system::error_code &ec,
140157 std::size_t ,
158+ std::shared_ptr<request_helper> helper,
141159 std::shared_ptr<response> res) {
142160if (ec) {
143161 response_promise_.set_exception (std::make_exception_ptr (
144162std::system_error (ec.value (),std::system_category ())));
145163return ;
146164 }
147165
148- std::istreamis (&response_ );
166+ std::istreamis (&response_buffer_ );
149167 string_type version;
150168 is >> version;
151169unsigned int status;
@@ -157,17 +175,18 @@ namespace network {
157175 res->set_status (network::http::v2::status::code (status));
158176 res->set_status_message (boost::trim_copy (message));
159177
160- connection_->async_read_until (response_ ,
178+ connection_->async_read_until (response_buffer_ ,
161179" \r\n\r\n " ,
162180 strand_.wrap (
163181 [=] (const boost::system::error_code &ec,
164182 std::size_t bytes_read) {
165- read_response_headers (ec, bytes_read, res);
183+ read_response_headers (ec, bytes_read,helper, res);
166184 }));
167185 }
168186
169187void client::impl::read_response_headers (const boost::system::error_code &ec,
170188 std::size_t ,
189+ std::shared_ptr<request_helper> helper,
171190 std::shared_ptr<response> res) {
172191if (ec) {
173192 response_promise_.set_exception (std::make_exception_ptr (
@@ -176,7 +195,7 @@ namespace network {
176195 }
177196
178197// fill headers
179- std::istreamis (&response_ );
198+ std::istreamis (&response_buffer_ );
180199 string_type header;
181200while (std::getline (is, header) && (header !=" \r " )) {
182201auto delim =boost::find_first_of (header," :" );
@@ -186,11 +205,11 @@ namespace network {
186205 res->add_header (key, value);
187206 }
188207
189- connection_->async_read (response_ ,
208+ connection_->async_read (response_buffer_ ,
190209 strand_.wrap (
191210 [=] (const boost::system::error_code &ec,
192211 std::size_t bytes_read) {
193- read_response_body (ec, bytes_read, res);
212+ read_response_body (ec, bytes_read,helper, res);
194213 }));
195214 }
196215
@@ -218,45 +237,46 @@ namespace network {
218237
219238void client::impl::read_response_body (const boost::system::error_code &ec,
220239 std::size_t bytes_read,
240+ std::shared_ptr<request_helper> helper,
221241 std::shared_ptr<response> res) {
222242if (bytes_read ==0 ) {
223243 response_promise_.set_value (*res);
224244return ;
225245 }
226246
227- std::istreamis (&response_ );
247+ std::istreamis (&response_buffer_ );
228248 string_type line;
229249while (!getline_with_newline (is, line).eof ()) {
230250 res->append_body (line);
231251 }
232252
233- connection_->async_read (response_ ,
253+ connection_->async_read (response_buffer_ ,
234254 strand_.wrap (
235255 [=] (const boost::system::error_code &ec,
236256 std::size_t bytes_read) {
237- read_response_body (ec, bytes_read, res);
257+ read_response_body (ec, bytes_read,helper, res);
238258 }));
239259 }
240260
241261 std::future<client::response>client::impl::do_request (method met,
242- request req,
243- request_options options) {
244- std::future<response> res = response_promise_.get_future ();
262+ std::shared_ptr<request_helper> helper) {
263+ std::future<client::response> res = response_promise_.get_future ();
245264
246- req .method (met);
247- std::ostreamrequest_stream (&request_ );
248- request_stream <<req ;
265+ helper-> request_ .method (met);
266+ std::ostreamrequest_stream (&request_buffer_ );
267+ request_stream <<helper-> request_ ;
249268if (!request_stream) {
250269 response_promise_.set_exception (std::make_exception_ptr (
251270client_exception (client_error::invalid_request)));
252271 }
253272
254273// HTTP 1.1
255- auto it =std::find_if (std::begin (req.headers ()),std::end (req.headers ()),
274+ auto it =std::find_if (std::begin (helper->request_ .headers ()),
275+ std::end (helper->request_ .headers ()),
256276 [] (const std::pair<uri::string_type, uri::string_type> &header) {
257277return (boost::iequals (header.first ," host" ));
258278 });
259- if (it ==std::end (req .headers ())) {
279+ if (it ==std::end (helper-> request_ .headers ())) {
260280// set error
261281 response_promise_.set_value (response ());
262282return res;
@@ -276,7 +296,7 @@ namespace network {
276296 strand_.wrap (
277297 [=](const boost::system::error_code &ec,
278298 tcp::resolver::iterator endpoint_iterator) {
279- connect (ec, endpoint_iterator);
299+ connect (ec, endpoint_iterator, helper );
280300 }));
281301
282302return res;
@@ -292,27 +312,27 @@ namespace network {
292312 }
293313
294314 std::future<client::response>client::get (request req, request_options options) {
295- return pimpl_->do_request (method::GET, req, options);
315+ return pimpl_->do_request (method::GET,std::make_shared<request_helper>( req, options) );
296316 }
297317
298318 std::future<client::response>client::post (request req, request_options options) {
299- return pimpl_->do_request (method::POST, req, options);
319+ return pimpl_->do_request (method::POST,std::make_shared<request_helper>( req, options) );
300320 }
301321
302322 std::future<client::response>client::put (request req, request_options options) {
303- return pimpl_->do_request (method::PUT, req, options);
323+ return pimpl_->do_request (method::PUT,std::make_shared<request_helper>( req, options) );
304324 }
305325
306326 std::future<client::response>client::delete_ (request req, request_options options) {
307- return pimpl_->do_request (method::DELETE, req, options);
327+ return pimpl_->do_request (method::DELETE,std::make_shared<request_helper>( req, options) );
308328 }
309329
310330 std::future<client::response>client::head (request req, request_options options) {
311- return pimpl_->do_request (method::HEAD, req, options);
331+ return pimpl_->do_request (method::HEAD,std::make_shared<request_helper>( req, options) );
312332 }
313333
314334 std::future<client::response>client::options (request req, request_options options) {
315- return pimpl_->do_request (method::OPTIONS, req, options);
335+ return pimpl_->do_request (method::OPTIONS,std::make_shared<request_helper>( req, options) );
316336 }
317337 }// namespace v2
318338 }// namespace http