Skip to content

Commit 9d492c3

Browse files
committed
Introducing client_options and request_options.
This commit makes changes to the API that moves the options setting to a different type to keep the client API relatively stable even across version releases supporting newer options. The intention is to keep the ABI stable as well as we add more supported features in the form of options in two levels: the client, and the request. The client_options type is meant to define options that affect the behavior of the constructed client and the connections it creates internally. The request_options on the other hand define per-request options pertaining to the HTTP implementation. This paves the way for supporting more optional modes and extensions that can and will be easily testable and turned on/off in a programmatic manner.
1 parent 19f108e commit 9d492c3

17 files changed

+112
-178
lines changed

boost/network/protocol/http/client/base.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,29 @@
1010
#include <boost/function.hpp>
1111
#include <boost/range/iterator_range.hpp>
1212
#include <boost/asio/io_service.hpp>
13-
#include <boost/network/protocol/http/client/connection_manager.hpp>
1413
#include <boost/network/protocol/http/response.hpp>
1514
#include <boost/network/protocol/http/request.hpp>
1615

1716
namespace boost { namespace network { namespace http {
1817

1918
struct client_base_pimpl;
2019

20+
class request_options;
21+
22+
class client_options;
23+
2124
struct client_base {
2225
typedef
2326
function<void(boost::iterator_range<char const *> const &, system::error_code const &)>
2427
body_callback_function_type;
2528

26-
client_base(shared_ptr<connection_manager> connection_manager_);
27-
client_base(asio::io_service & service,
28-
shared_ptr<connection_manager> connection_manager_);
29+
explicit client_base(client_options const &options);
2930
~client_base();
3031
response const request_skeleton(request const & request_,
3132
std::string const & method,
3233
bool get_body,
33-
body_callback_function_type callback);
34+
body_callback_function_type callback,
35+
request_options const &options);
3436
void clear_resolved_cache();
3537
private:
3638
client_base_pimpl * pimpl;

boost/network/protocol/http/client/base.ipp

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// http://www.boost.org/LICENSE_1_0.txt)
99

1010
#include <boost/network/protocol/http/client/base.hpp>
11+
#include <boost/network/protocol/http/client/options.hpp>
1112
#include <boost/asio/io_service.hpp>
1213
#include <boost/asio/strand.hpp>
1314
#include <boost/thread/thread.hpp>
@@ -21,67 +22,52 @@ struct client_base_pimpl {
2122
typedef
2223
function<void(boost::iterator_range<char const *> const &, system::error_code const &)>
2324
body_callback_function_type;
24-
client_base_pimpl(shared_ptr<connection_manager> connection_manager_);
25-
client_base_pimpl(asio::io_service & service, shared_ptr<connection_manager> connection_manager_);
25+
client_base_pimpl(client_options const &options);
2626
response const request_skeleton(request const & request_,
2727
std::string const & method,
2828
bool get_body,
29-
body_callback_function_type callback);
29+
body_callback_function_type callback,
30+
request_options const &options);
3031
~client_base_pimpl();
3132
private:
33+
client_options options_;
3234
boost::asio::io_service * service_ptr;
33-
boost::asio::io_service & service_;
3435
boost::shared_ptr<boost::asio::io_service::work> sentinel_;
3536
boost::shared_ptr<boost::thread> lifetime_thread_;
3637
shared_ptr<connection_manager> connection_manager_;
3738
};
3839

39-
client_base::client_base(shared_ptr<connection_manager> connection_manager_)
40-
: pimpl(new (std::nothrow) client_base_pimpl(connection_manager_))
41-
{}
42-
43-
client_base::client_base(asio::io_service & service,
44-
shared_ptr<connection_manager> connection_manager_)
45-
: pimpl(new (std::nothrow) client_base_pimpl(service, connection_manager_))
40+
client_base::client_base(client_options const &options)
41+
: pimpl(new (std::nothrow) client_base_pimpl(options))
4642
{}
4743

4844
response const client_base::request_skeleton(request const & request_,
4945
std::string const & method,
5046
bool get_body,
51-
body_callback_function_type callback) {
52-
return pimpl->request_skeleton(request_, method, get_body, callback);
47+
body_callback_function_type callback,
48+
request_options const &options) {
49+
return pimpl->request_skeleton(request_, method, get_body, callback, options);
5350
}
5451

5552
client_base::~client_base() {
5653
delete pimpl;
5754
}
5855

59-
client_base_pimpl::client_base_pimpl(shared_ptr<connection_manager> connection_manager)
60-
: service_ptr(new (std::nothrow) boost::asio::io_service),
61-
service_(*service_ptr),
62-
sentinel_(new (std::nothrow) boost::asio::io_service::work(service_)),
63-
connection_manager_(connection_manager)
56+
client_base_pimpl::client_base_pimpl(client_options const &options)
57+
: options_(options),
58+
service_ptr(options.io_service()),
59+
sentinel_(new (std::nothrow) boost::asio::io_service::work(*service_ptr)),
60+
connection_manager_(options.connection_manager())
6461
{
6562
lifetime_thread_.reset(new (std::nothrow) boost::thread(
6663
boost::bind(
6764
&boost::asio::io_service::run,
68-
&service_
65+
service_ptr
6966
)));
7067
if (!lifetime_thread_.get())
7168
BOOST_THROW_EXCEPTION(std::runtime_error("Cannot allocate client lifetime thread; not enough memory."));
7269
}
7370

74-
client_base_pimpl::client_base_pimpl(boost::asio::io_service & service,
75-
shared_ptr<connection_manager> connection_manager)
76-
: service_ptr(0),
77-
service_(service),
78-
sentinel_(new (std::nothrow) boost::asio::io_service::work(service_)),
79-
connection_manager_(connection_manager)
80-
{
81-
if (!sentinel_.get())
82-
BOOST_THROW_EXCEPTION(std::runtime_error("Cannot allocate sentinel; not enough memory."));
83-
}
84-
8571
client_base_pimpl::~client_base_pimpl()
8672
{
8773
sentinel_.reset();
@@ -97,12 +83,13 @@ response const client_base_pimpl::request_skeleton(
9783
request const & request_,
9884
std::string const & method,
9985
bool get_body,
100-
body_callback_function_type callback
86+
body_callback_function_type callback,
87+
request_options const &options
10188
)
10289
{
10390
shared_ptr<client_connection> connection_;
104-
connection_ = connection_manager_->get_connection(service_, request_);
105-
return connection_->send_request(method, request_, get_body, callback);
91+
connection_ = connection_manager_->get_connection(*service_ptr, request_, options_);
92+
return connection_->send_request(method, request_, get_body, callback, options);
10693
}
10794

10895
} // namespace http

boost/network/protocol/http/client/client_connection.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515

1616
namespace boost { namespace network { namespace http {
1717

18+
class request_options;
19+
1820
struct client_connection {
1921
typedef function<void(iterator_range<char const *> const &,
2022
system::error_code const &)>
2123
callback_type;
2224
virtual response send_request(std::string const & method,
2325
request const & request,
2426
bool get_body,
25-
callback_type callback) = 0;
27+
callback_type callback,
28+
request_options const &options) = 0;
2629
virtual client_connection * clone() const = 0;
2730
virtual void reset() = 0;
2831
virtual ~client_connection() = 0;

boost/network/protocol/http/client/connection/async_normal.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ struct http_async_connection : client_connection
3131
virtual response send_request(std::string const & method,
3232
request const & request,
3333
bool get_body,
34-
callback_type callback); // override
34+
callback_type callback,
35+
request_options const &options); // override
3536
virtual void reset(); // override
3637
virtual ~http_async_connection();
3738
private:

boost/network/protocol/http/client/connection/async_normal.ipp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
4343
response start(request const & request,
4444
std::string const & method,
4545
bool get_body,
46-
body_callback_function_type callback) {
46+
body_callback_function_type callback,
47+
request_options const &options) {
4748
response response_;
4849
this->init_response(response_);
4950
// Use HTTP/1.1 -- at some point we might want to implement a different
@@ -757,8 +758,9 @@ http_async_connection * http_async_connection::clone() const {
757758
response http_async_connection::send_request(std::string const & method,
758759
request const & request,
759760
bool get_body,
760-
callback_type callback) {
761-
return pimpl->start(request, method, get_body, callback);
761+
callback_type callback,
762+
request_options const &options) {
763+
return pimpl->start(request, method, get_body, callback, options);
762764
}
763765

764766
void http_async_connection::reset() {

boost/network/protocol/http/client/connection/connection_delegate_factory.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@
1212

1313
namespace boost { namespace network { namespace http {
1414

15+
class client_options;
16+
1517
struct connection_delegate_factory {
1618
typedef shared_ptr<connection_delegate> connection_delegate_ptr;
1719

1820
connection_delegate_factory();
1921

2022
// This is the factory method that actually returns the delegate instance.
21-
// TODO Support passing in proxy settings when crafting connections.
2223
virtual connection_delegate_ptr create_connection_delegate(
2324
asio::io_service & service,
2425
bool https,
25-
optional<std::string> certificate_filename,
26-
optional<std::string> verify_path);
26+
client_options const &options);
2727

2828
virtual ~connection_delegate_factory();
2929

boost/network/protocol/http/client/connection/connection_delegate_factory.ipp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#endif /* BOOST_NETWORK_ENABLE_HTTPS */
1414

1515
#include <boost/network/protocol/http/client/connection/connection_delegate_factory.hpp>
16+
#include <boost/network/protocol/http/client/options.hpp>
1617

1718
namespace boost { namespace network { namespace http {
1819

@@ -22,14 +23,12 @@ connection_delegate_factory::connection_delegate_ptr
2223
connection_delegate_factory::create_connection_delegate(
2324
asio::io_service & service,
2425
bool https,
25-
optional<std::string> certificate_filename,
26-
optional<std::string> verify_path) {
26+
client_options const &options) {
2727
connection_delegate_ptr delegate;
2828
if (https) {
2929
#ifdef BOOST_NETWORK_ENABLE_HTTPS
3030
delegate.reset(new ssl_delegate(service,
31-
certificate_filename,
32-
verify_path));
31+
options));
3332
#else
3433
BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported."));
3534
#endif /* BOOST_NETWORK_ENABLE_HTTPS */

boost/network/protocol/http/client/connection/connection_factory.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313

1414
namespace boost { namespace network { namespace http {
1515

16+
class client_options;
17+
18+
struct client_connection;
19+
1620
struct connection_factory {
17-
virtual shared_ptr<client_connection> create_connection(asio::io_service & service,
21+
virtual shared_ptr<client_connection> create_connection(asio::io_service &service,
1822
request_base const & request,
19-
bool cache_resolved,
20-
bool follow_redirects,
21-
optional<std::string> openssl_certificate,
22-
optional<std::string> openssl_verify_path) = 0;
23+
client_options const &options) = 0;
2324
virtual ~connection_factory() = 0; // pure virtual, interface only.
2425
};
2526

boost/network/protocol/http/client/connection/simple_connection_factory.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ struct simple_connection_factory : connection_factory {
2323
shared_ptr<resolver_delegate_factory> res_delegate_factory);
2424
virtual shared_ptr<client_connection> create_connection(asio::io_service & service,
2525
request_base const & request,
26-
bool cache_resolved,
27-
bool follow_redirects,
28-
optional<std::string> openssl_certificate,
29-
optional<std::string> openssl_verify_path); // override
26+
client_options const & options); // override
3027
virtual ~simple_connection_factory();
3128
private:
3229
scoped_ptr<simple_connection_factory_pimpl> pimpl;

boost/network/protocol/http/client/connection/simple_connection_factory.ipp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <boost/network/protocol/http/client/connection/resolver_delegate_factory.hpp>
1212
#include <boost/network/protocol/http/client/connection/connection_delegate_factory.hpp>
1313
#include <boost/network/protocol/http/client/connection/async_normal.hpp>
14+
#include <boost/network/protocol/http/client/options.hpp>
1415

1516
namespace boost { namespace network { namespace http {
1617

@@ -24,19 +25,15 @@ struct simple_connection_factory_pimpl {
2425
shared_ptr<client_connection> create_connection(
2526
asio::io_service & service,
2627
request_base const & request,
27-
bool cache_resolved,
28-
bool follow_redirects,
29-
optional<std::string> openssl_certificate,
30-
optional<std::string> openssl_verify_path) {
28+
client_options const & options) {
3129
::boost::network::uri::uri uri_(destination(request));
3230
bool https = to_lower_copy(scheme(uri_)) == "https";
3331
shared_ptr<client_connection> conn_;
3432
conn_.reset(new (std::nothrow) http_async_connection(
35-
res_delegate_factory_->create_resolver_delegate(service, cache_resolved),
36-
conn_delegate_factory_->create_connection_delegate(
37-
service, https, openssl_certificate, openssl_verify_path),
33+
res_delegate_factory_->create_resolver_delegate(service, options.cache_resolved()),
34+
conn_delegate_factory_->create_connection_delegate(service, https, options),
3835
service,
39-
follow_redirects));
36+
options.follow_redirects()));
4037
return conn_;
4138
}
4239

@@ -62,12 +59,8 @@ simple_connection_factory::simple_connection_factory(shared_ptr<connection_deleg
6259
shared_ptr<client_connection>
6360
simple_connection_factory::create_connection(asio::io_service & service,
6461
request_base const & request,
65-
bool cache_resolved,
66-
bool follow_redirects,
67-
optional<std::string> openssl_certificate,
68-
optional<std::string> openssl_verify_path) {
69-
return pimpl->create_connection(service, request, cache_resolved, follow_redirects,
70-
openssl_certificate, openssl_verify_path);
62+
client_options const &options) {
63+
return pimpl->create_connection(service, request, options);
7164
}
7265

7366
simple_connection_factory::~simple_connection_factory() {

0 commit comments

Comments
 (0)