@@ -24,7 +24,7 @@ namespace network {
2424
2525struct request_helper {
2626
27- std::unique_ptr <client_connection::async_connection> connection_;
27+ std::shared_ptr <client_connection::async_connection> connection_;
2828
2929 client::request request_;
3030 client::request_options options_;
@@ -36,23 +36,26 @@ namespace network {
3636
3737// TODO configure deadline timer for timeouts
3838
39- request_helper (boost::asio::io_service &io_service ,
39+ request_helper (std::shared_ptr<client_connection::async_connection> connection ,
4040 client::request request,
4141 client::request_options options)
42- // TODO factory based on HTTP or HTTPS
43- : connection_(new client_connection::normal_connection(io_service))
42+ : connection_(connection)
4443 , request_(request)
4544 , options_(options) { }
4645
4746 };
4847
4948struct client ::impl {
5049
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);
5255
53- ~impl ()noexcept ;
56+ ~impl ()noexcept ;
5457
55- std::future<response>do_request (std::shared_ptr<request_helper> helper);
58+ std::future<response>execute (std::shared_ptr<request_helper> helper);
5659
5760void connect (const boost::system::error_code &ec,
5861 tcp::resolver::iterator endpoint_iterator,
@@ -80,30 +83,42 @@ namespace network {
8083 std::shared_ptr<request_helper> helper,
8184 std::shared_ptr<response> res);
8285
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_;
8689 boost::asio::io_service::strand strand_;
8790 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_;
8993
9094 };
9195
9296client::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_))
9599 , 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 (); }) {
98113
99114 }
100115
101116client::impl::~impl ()noexcept {
102- sentinel_.reset ();
103- lifetime_thread_.join ();
117+ sentinel_.reset ();
118+ lifetime_thread_.join ();
104119 }
105120
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) {
107122 std::future<client::response> res = helper->response_promise_ .get_future ();
108123
109124// TODO see linearize.hpp
@@ -131,14 +146,14 @@ namespace network {
131146uri::string_type (std::begin (*auth.host ()),std::end (*auth.host ())) :uri::string_type ();
132147auto port = auth.port <std::uint16_t >()? *auth.port <std::uint16_t >() :80 ;
133148
134- resolver_->async_resolve (host, port,
149+ resolver_->async_resolve (host, port,
135150 strand_.wrap (
136151 [=](const boost::system::error_code &ec,
137152 tcp::resolver::iterator endpoint_iterator) {
138153connect (ec, endpoint_iterator, helper);
139154 }));
140155
141- return res;
156+ return res;
142157 }
143158
144159void client::impl::connect (const boost::system::error_code &ec,
@@ -322,42 +337,61 @@ namespace network {
322337 }
323338
324339client::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)) {
326348
327349 }
328350
329351client::~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));
331365 }
332366
333367 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);
336370 }
337371
338372 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);
341375 }
342376
343377 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);
346380 }
347381
348382 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);
351385 }
352386
353387 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);
356390 }
357391
358392 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);
361395 }
362396 }// namespace v2
363397 }// namespace http