@@ -22,33 +22,50 @@ namespace network {
22
22
namespace v2 {
23
23
using boost::asio::ip::tcp;
24
24
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
+
25
36
struct client ::impl {
26
37
27
38
explicit impl (client_options options);
28
39
29
40
~impl () noexcept ;
30
41
31
42
void 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);
33
45
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);
35
48
36
49
void 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);
38
52
39
53
void read_response_status (const boost::system::error_code &ec,
40
54
std::size_t bytes_written,
55
+ std::shared_ptr<request_helper> helper,
41
56
std::shared_ptr<response> res);
42
57
43
58
void read_response_headers (const boost::system::error_code &ec,
44
59
std::size_t bytes_read,
60
+ std::shared_ptr<request_helper> helper,
45
61
std::shared_ptr<response> res);
46
62
47
63
void read_response_body (const boost::system::error_code &ec,
48
64
std::size_t bytes_read,
65
+ std::shared_ptr<request_helper> helper,
49
66
std::shared_ptr<response> res);
50
67
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 );
52
69
53
70
client_options options_;
54
71
boost::asio::io_service io_service_;
@@ -59,11 +76,8 @@ namespace network {
59
76
std::thread lifetime_thread_;
60
77
61
78
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_;
67
81
68
82
};
69
83
@@ -83,7 +97,8 @@ namespace network {
83
97
}
84
98
85
99
void 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) {
87
102
if (ec) {
88
103
if (endpoint_iterator == tcp::resolver::iterator ()) {
89
104
response_promise_.set_exception (std::make_exception_ptr (
@@ -100,52 +115,55 @@ namespace network {
100
115
connection_->async_connect (endpoint,
101
116
strand_.wrap (
102
117
[=] (const boost::system::error_code &ec) {
103
- write_request (ec);
118
+ write_request (ec, helper );
104
119
}));
105
120
}
106
121
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) {
108
124
if (ec) {
109
125
response_promise_.set_exception (std::make_exception_ptr (
110
126
std::system_error (ec.value (), std::system_category ())));
111
127
return ;
112
128
}
113
129
114
- connection_->async_write (request_ ,
130
+ connection_->async_write (request_buffer_ ,
115
131
strand_.wrap (
116
132
[=] (const boost::system::error_code &ec,
117
133
std::size_t bytes_written) {
118
- read_response (ec, bytes_written);
134
+ read_response (ec, bytes_written, helper );
119
135
}));
120
136
}
121
137
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) {
123
140
if (ec) {
124
141
response_promise_.set_exception (std::make_exception_ptr (
125
142
std::system_error (ec.value (), std::system_category ())));
126
143
return ;
127
144
}
128
145
129
146
std::shared_ptr<response> res (new response{});
130
- connection_->async_read_until (response_ ,
147
+ connection_->async_read_until (response_buffer_ ,
131
148
" \r\n " ,
132
149
strand_.wrap (
133
150
[=] (const boost::system::error_code &ec,
134
151
std::size_t bytes_read) {
135
- read_response_status (ec, bytes_read, res);
152
+ read_response_status (ec, bytes_read, helper, res);
136
153
}));
137
154
}
138
155
139
156
void client::impl::read_response_status (const boost::system::error_code &ec,
140
157
std::size_t ,
158
+ std::shared_ptr<request_helper> helper,
141
159
std::shared_ptr<response> res) {
142
160
if (ec) {
143
161
response_promise_.set_exception (std::make_exception_ptr (
144
162
std::system_error (ec.value (), std::system_category ())));
145
163
return ;
146
164
}
147
165
148
- std::istream is (&response_ );
166
+ std::istream is (&response_buffer_ );
149
167
string_type version;
150
168
is >> version;
151
169
unsigned int status;
@@ -157,17 +175,18 @@ namespace network {
157
175
res->set_status (network::http::v2::status::code (status));
158
176
res->set_status_message (boost::trim_copy (message));
159
177
160
- connection_->async_read_until (response_ ,
178
+ connection_->async_read_until (response_buffer_ ,
161
179
" \r\n\r\n " ,
162
180
strand_.wrap (
163
181
[=] (const boost::system::error_code &ec,
164
182
std::size_t bytes_read) {
165
- read_response_headers (ec, bytes_read, res);
183
+ read_response_headers (ec, bytes_read, helper, res);
166
184
}));
167
185
}
168
186
169
187
void client::impl::read_response_headers (const boost::system::error_code &ec,
170
188
std::size_t ,
189
+ std::shared_ptr<request_helper> helper,
171
190
std::shared_ptr<response> res) {
172
191
if (ec) {
173
192
response_promise_.set_exception (std::make_exception_ptr (
@@ -176,7 +195,7 @@ namespace network {
176
195
}
177
196
178
197
// fill headers
179
- std::istream is (&response_ );
198
+ std::istream is (&response_buffer_ );
180
199
string_type header;
181
200
while (std::getline (is, header) && (header != " \r " )) {
182
201
auto delim = boost::find_first_of (header, " :" );
@@ -186,11 +205,11 @@ namespace network {
186
205
res->add_header (key, value);
187
206
}
188
207
189
- connection_->async_read (response_ ,
208
+ connection_->async_read (response_buffer_ ,
190
209
strand_.wrap (
191
210
[=] (const boost::system::error_code &ec,
192
211
std::size_t bytes_read) {
193
- read_response_body (ec, bytes_read, res);
212
+ read_response_body (ec, bytes_read, helper, res);
194
213
}));
195
214
}
196
215
@@ -218,45 +237,46 @@ namespace network {
218
237
219
238
void client::impl::read_response_body (const boost::system::error_code &ec,
220
239
std::size_t bytes_read,
240
+ std::shared_ptr<request_helper> helper,
221
241
std::shared_ptr<response> res) {
222
242
if (bytes_read == 0 ) {
223
243
response_promise_.set_value (*res);
224
244
return ;
225
245
}
226
246
227
- std::istream is (&response_ );
247
+ std::istream is (&response_buffer_ );
228
248
string_type line;
229
249
while (!getline_with_newline (is, line).eof ()) {
230
250
res->append_body (line);
231
251
}
232
252
233
- connection_->async_read (response_ ,
253
+ connection_->async_read (response_buffer_ ,
234
254
strand_.wrap (
235
255
[=] (const boost::system::error_code &ec,
236
256
std::size_t bytes_read) {
237
- read_response_body (ec, bytes_read, res);
257
+ read_response_body (ec, bytes_read, helper, res);
238
258
}));
239
259
}
240
260
241
261
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 ();
245
264
246
- req .method (met);
247
- std::ostream request_stream (&request_ );
248
- request_stream << req ;
265
+ helper-> request_ .method (met);
266
+ std::ostream request_stream (&request_buffer_ );
267
+ request_stream << helper-> request_ ;
249
268
if (!request_stream) {
250
269
response_promise_.set_exception (std::make_exception_ptr (
251
270
client_exception (client_error::invalid_request)));
252
271
}
253
272
254
273
// 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 ()),
256
276
[] (const std::pair<uri::string_type, uri::string_type> &header) {
257
277
return (boost::iequals (header.first , " host" ));
258
278
});
259
- if (it == std::end (req .headers ())) {
279
+ if (it == std::end (helper-> request_ .headers ())) {
260
280
// set error
261
281
response_promise_.set_value (response ());
262
282
return res;
@@ -276,7 +296,7 @@ namespace network {
276
296
strand_.wrap (
277
297
[=](const boost::system::error_code &ec,
278
298
tcp::resolver::iterator endpoint_iterator) {
279
- connect (ec, endpoint_iterator);
299
+ connect (ec, endpoint_iterator, helper );
280
300
}));
281
301
282
302
return res;
@@ -292,27 +312,27 @@ namespace network {
292
312
}
293
313
294
314
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) );
296
316
}
297
317
298
318
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) );
300
320
}
301
321
302
322
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) );
304
324
}
305
325
306
326
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) );
308
328
}
309
329
310
330
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) );
312
332
}
313
333
314
334
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) );
316
336
}
317
337
} // namespace v2
318
338
} // namespace http
0 commit comments