@@ -24,7 +24,7 @@ namespace network {
24
24
25
25
struct request_helper {
26
26
27
- std::unique_ptr <client_connection::async_connection> connection_;
27
+ std::shared_ptr <client_connection::async_connection> connection_;
28
28
29
29
client::request request_;
30
30
client::request_options options_;
@@ -36,23 +36,26 @@ namespace network {
36
36
37
37
// TODO configure deadline timer for timeouts
38
38
39
- request_helper (boost::asio::io_service &io_service ,
39
+ request_helper (std::shared_ptr<client_connection::async_connection> connection ,
40
40
client::request request,
41
41
client::request_options options)
42
- // TODO factory based on HTTP or HTTPS
43
- : connection_(new client_connection::normal_connection(io_service))
42
+ : connection_(connection)
44
43
, request_(request)
45
44
, options_(options) { }
46
45
47
46
};
48
47
49
48
struct client ::impl {
50
49
51
- explicit impl (client_options options);
50
+ explicit impl (client_options options);
51
+
52
+ impl (std::unique_ptr<client_connection::async_resolver> mock_resolver,
53
+ std::unique_ptr<client_connection::async_connection> mock_connection,
54
+ client_options options);
52
55
53
- ~impl () noexcept ;
56
+ ~impl () noexcept ;
54
57
55
- std::future<response> do_request (std::shared_ptr<request_helper> helper);
58
+ std::future<response> execute (std::shared_ptr<request_helper> helper);
56
59
57
60
void connect (const boost::system::error_code &ec,
58
61
tcp::resolver::iterator endpoint_iterator,
@@ -80,30 +83,42 @@ namespace network {
80
83
std::shared_ptr<request_helper> helper,
81
84
std::shared_ptr<response> res);
82
85
83
- client_options options_;
84
- boost::asio::io_service io_service_;
85
- std::unique_ptr<boost::asio::io_service::work> sentinel_;
86
+ client_options options_;
87
+ boost::asio::io_service io_service_;
88
+ std::unique_ptr<boost::asio::io_service::work> sentinel_;
86
89
boost::asio::io_service::strand strand_;
87
90
std::unique_ptr<client_connection::async_resolver> resolver_;
88
- std::thread lifetime_thread_;
91
+ std::shared_ptr<client_connection::async_connection> mock_connection_;
92
+ std::thread lifetime_thread_;
89
93
90
94
};
91
95
92
96
client::impl::impl (client_options options)
93
- : options_(options)
94
- , sentinel_(new boost::asio::io_service::work(io_service_))
97
+ : options_(options)
98
+ , sentinel_(new boost::asio::io_service::work(io_service_))
95
99
, strand_(io_service_)
96
- , resolver_(new client_connection::tcp_resolver(io_service_, options_.cache_resolved()))
97
- , lifetime_thread_([=] () { io_service_.run (); }) {
100
+ , resolver_(new client_connection::tcp_resolver(io_service_, options_.cache_resolved()))
101
+ , lifetime_thread_([=] () { io_service_.run (); }) {
102
+
103
+ }
104
+
105
+ client::impl::impl (std::unique_ptr<client_connection::async_resolver> mock_resolver,
106
+ std::unique_ptr<client_connection::async_connection> mock_connection,
107
+ client_options options)
108
+ : options_(options)
109
+ , sentinel_(new boost::asio::io_service::work(io_service_))
110
+ , strand_(io_service_)
111
+ , resolver_(std::move(mock_resolver))
112
+ , lifetime_thread_([=] () { io_service_.run (); }) {
98
113
99
114
}
100
115
101
116
client::impl::~impl () noexcept {
102
- sentinel_.reset ();
103
- lifetime_thread_.join ();
117
+ sentinel_.reset ();
118
+ lifetime_thread_.join ();
104
119
}
105
120
106
- std::future<client::response> client::impl::do_request (std::shared_ptr<request_helper> helper) {
121
+ std::future<client::response> client::impl::execute (std::shared_ptr<request_helper> helper) {
107
122
std::future<client::response> res = helper->response_promise_ .get_future ();
108
123
109
124
// TODO see linearize.hpp
@@ -131,14 +146,14 @@ namespace network {
131
146
uri::string_type (std::begin (*auth.host ()), std::end (*auth.host ())) : uri::string_type ();
132
147
auto port = auth.port <std::uint16_t >()? *auth.port <std::uint16_t >() : 80 ;
133
148
134
- resolver_->async_resolve (host, port,
149
+ resolver_->async_resolve (host, port,
135
150
strand_.wrap (
136
151
[=](const boost::system::error_code &ec,
137
152
tcp::resolver::iterator endpoint_iterator) {
138
153
connect (ec, endpoint_iterator, helper);
139
154
}));
140
155
141
- return res;
156
+ return res;
142
157
}
143
158
144
159
void client::impl::connect (const boost::system::error_code &ec,
@@ -322,42 +337,61 @@ namespace network {
322
337
}
323
338
324
339
client::client (client_options options)
325
- : pimpl_(new impl(options)) {
340
+ : pimpl_(new impl(options)) {
341
+
342
+ }
343
+
344
+ client::client (std::unique_ptr<client_connection::async_resolver> mock_resolver,
345
+ std::unique_ptr<client_connection::async_connection> mock_connection,
346
+ client_options options)
347
+ : pimpl_(new impl(std::move(mock_resolver), std::move(mock_connection), options)) {
326
348
327
349
}
328
350
329
351
client::~client () noexcept {
330
- delete pimpl_;
352
+ delete pimpl_;
353
+ }
354
+
355
+ std::future<client::response> client::execute (request req, request_options options) {
356
+ std::shared_ptr<client_connection::async_connection> connection;
357
+ if (pimpl_->mock_connection_ ) {
358
+ connection = pimpl_->mock_connection_ ;
359
+ }
360
+ else {
361
+ // TODO factory based on HTTP or HTTPS
362
+ connection = std::make_shared<client_connection::normal_connection>(pimpl_->io_service_ );
363
+ }
364
+ return pimpl_->execute (std::make_shared<request_helper>(connection, req, options));
331
365
}
332
366
333
367
std::future<client::response> client::get (request req, request_options options) {
334
- req.method (method::get);
335
- return pimpl_-> do_request (std::make_shared<request_helper>(pimpl_-> io_service_ , req, options) );
368
+ req.method (method::get);
369
+ return execute ( req, options);
336
370
}
337
371
338
372
std::future<client::response> client::post (request req, request_options options) {
339
- req.method (method::post);
340
- return pimpl_-> do_request (std::make_shared<request_helper>(pimpl_-> io_service_ , req, options) );
373
+ req.method (method::post);
374
+ return execute ( req, options);
341
375
}
342
376
343
377
std::future<client::response> client::put (request req, request_options options) {
344
- req.method (method::put);
345
- return pimpl_-> do_request (std::make_shared<request_helper>(pimpl_-> io_service_ , req, options) );
378
+ req.method (method::put);
379
+ return execute ( req, options);
346
380
}
347
381
348
382
std::future<client::response> client::delete_ (request req, request_options options) {
349
- req.method (method::delete_);
350
- return pimpl_-> do_request (std::make_shared<request_helper>(pimpl_-> io_service_ , req, options) );
383
+ req.method (method::delete_);
384
+ return execute ( req, options);
351
385
}
352
386
353
387
std::future<client::response> client::head (request req, request_options options) {
354
- req.method (method::head);
355
- return pimpl_-> do_request (std::make_shared<request_helper>(pimpl_-> io_service_ , req, options) );
388
+ req.method (method::head);
389
+ return execute ( req, options);
356
390
}
357
391
358
392
std::future<client::response> client::options (request req, request_options options) {
359
- req.method (method::options);
360
- return pimpl_-> do_request (std::make_shared<request_helper>(pimpl_-> io_service_ , req, options) );
393
+ req.method (method::options);
394
+ return execute ( req, options);
361
395
}
362
396
} // namespace v2
363
397
} // namespace http
0 commit comments