Skip to content

Commit 6ff897f

Browse files
committed
Continued to refactor the HTTP client; made the method enum class lower case for consistency.
1 parent 6830eba commit 6ff897f

File tree

7 files changed

+107
-71
lines changed

7 files changed

+107
-71
lines changed

http/src/http/v2/client/client.cpp

+59-44
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,24 @@ namespace network {
2424

2525
struct request_helper {
2626

27+
std::unique_ptr<client_connection::async_connection> connection_;
28+
2729
client::request request_;
2830
client::request_options options_;
2931

30-
request_helper(client::request request, client::request_options options)
31-
: request_(request)
32+
std::promise<client::response> response_promise_;
33+
34+
boost::asio::streambuf request_buffer_;
35+
boost::asio::streambuf response_buffer_;
36+
37+
// TODO configure deadline timer for timeouts
38+
39+
request_helper(boost::asio::io_service &io_service,
40+
client::request request,
41+
client::request_options options)
42+
// TODO factory based on HTTP or HTTPS
43+
: connection_(new client_connection::normal_connection(io_service))
44+
, request_(request)
3245
, options_(options) { }
3346

3447
};
@@ -69,24 +82,18 @@ namespace network {
6982

7083
client_options options_;
7184
boost::asio::io_service io_service_;
85+
std::unique_ptr<boost::asio::io_service::work> sentinel_;
7286
boost::asio::io_service::strand strand_;
7387
std::unique_ptr<client_connection::async_resolver> resolver_;
74-
std::unique_ptr<client_connection::async_connection> connection_;
75-
std::unique_ptr<boost::asio::io_service::work> sentinel_;
7688
std::thread lifetime_thread_;
7789

78-
std::promise<response> response_promise_;
79-
boost::asio::streambuf request_buffer_;
80-
boost::asio::streambuf response_buffer_;
81-
8290
};
8391

8492
client::impl::impl(client_options options)
8593
: options_(options)
86-
, strand_(io_service_)
87-
, resolver_(new client_connection::tcp_resolver(io_service_, options.cache_resolved()))
88-
, connection_(new client_connection::normal_connection(io_service_))
8994
, sentinel_(new boost::asio::io_service::work(io_service_))
95+
, strand_(io_service_)
96+
, resolver_(new client_connection::tcp_resolver(io_service_, options_.cache_resolved()))
9097
, lifetime_thread_([=] () { io_service_.run(); }) {
9198

9299
}
@@ -101,18 +108,18 @@ namespace network {
101108
std::shared_ptr<request_helper> helper) {
102109
if (ec) {
103110
if (endpoint_iterator == tcp::resolver::iterator()) {
104-
response_promise_.set_exception(std::make_exception_ptr(
105-
client_exception(client_error::host_not_found)));
111+
helper->response_promise_.set_exception(
112+
std::make_exception_ptr(client_exception(client_error::host_not_found)));
106113
return;
107114
}
108115

109-
response_promise_.set_exception(std::make_exception_ptr(
110-
std::system_error(ec.value(), std::system_category())));
116+
helper->response_promise_.set_exception(
117+
std::make_exception_ptr(std::system_error(ec.value(), std::system_category())));
111118
return;
112119
}
113120

114121
tcp::endpoint endpoint(*endpoint_iterator);
115-
connection_->async_connect(endpoint,
122+
helper->connection_->async_connect(endpoint,
116123
strand_.wrap(
117124
[=] (const boost::system::error_code &ec) {
118125
write_request(ec, helper);
@@ -122,12 +129,12 @@ namespace network {
122129
void client::impl::write_request(const boost::system::error_code &ec,
123130
std::shared_ptr<request_helper> helper) {
124131
if (ec) {
125-
response_promise_.set_exception(std::make_exception_ptr(
126-
std::system_error(ec.value(), std::system_category())));
132+
helper->response_promise_.set_exception(
133+
std::make_exception_ptr(std::system_error(ec.value(), std::system_category())));
127134
return;
128135
}
129136

130-
connection_->async_write(request_buffer_,
137+
helper->connection_->async_write(helper->request_buffer_,
131138
strand_.wrap(
132139
[=] (const boost::system::error_code &ec,
133140
std::size_t bytes_written) {
@@ -138,13 +145,13 @@ namespace network {
138145
void client::impl::read_response(const boost::system::error_code &ec, std::size_t,
139146
std::shared_ptr<request_helper> helper) {
140147
if (ec) {
141-
response_promise_.set_exception(std::make_exception_ptr(
142-
std::system_error(ec.value(), std::system_category())));
148+
helper->response_promise_.set_exception(
149+
std::make_exception_ptr(std::system_error(ec.value(), std::system_category())));
143150
return;
144151
}
145152

146153
std::shared_ptr<response> res(new response{});
147-
connection_->async_read_until(response_buffer_,
154+
helper->connection_->async_read_until(helper->response_buffer_,
148155
"\r\n",
149156
strand_.wrap(
150157
[=] (const boost::system::error_code &ec,
@@ -158,12 +165,12 @@ namespace network {
158165
std::shared_ptr<request_helper> helper,
159166
std::shared_ptr<response> res) {
160167
if (ec) {
161-
response_promise_.set_exception(std::make_exception_ptr(
162-
std::system_error(ec.value(), std::system_category())));
168+
helper->response_promise_.set_exception(
169+
std::make_exception_ptr(std::system_error(ec.value(), std::system_category())));
163170
return;
164171
}
165172

166-
std::istream is(&response_buffer_);
173+
std::istream is(&helper->response_buffer_);
167174
string_type version;
168175
is >> version;
169176
unsigned int status;
@@ -175,7 +182,7 @@ namespace network {
175182
res->set_status(network::http::v2::status::code(status));
176183
res->set_status_message(boost::trim_copy(message));
177184

178-
connection_->async_read_until(response_buffer_,
185+
helper->connection_->async_read_until(helper->response_buffer_,
179186
"\r\n\r\n",
180187
strand_.wrap(
181188
[=] (const boost::system::error_code &ec,
@@ -189,13 +196,13 @@ namespace network {
189196
std::shared_ptr<request_helper> helper,
190197
std::shared_ptr<response> res) {
191198
if (ec) {
192-
response_promise_.set_exception(std::make_exception_ptr(
193-
std::system_error(ec.value(), std::system_category())));
199+
helper->response_promise_.set_exception(
200+
std::make_exception_ptr(std::system_error(ec.value(), std::system_category())));
194201
return;
195202
}
196203

197204
// fill headers
198-
std::istream is(&response_buffer_);
205+
std::istream is(&helper->response_buffer_);
199206
string_type header;
200207
while (std::getline(is, header) && (header != "\r")) {
201208
auto delim = boost::find_first_of(header, ":");
@@ -205,7 +212,7 @@ namespace network {
205212
res->add_header(key, value);
206213
}
207214

208-
connection_->async_read(response_buffer_,
215+
helper->connection_->async_read(helper->response_buffer_,
209216
strand_.wrap(
210217
[=] (const boost::system::error_code &ec,
211218
std::size_t bytes_read) {
@@ -240,17 +247,17 @@ namespace network {
240247
std::shared_ptr<request_helper> helper,
241248
std::shared_ptr<response> res) {
242249
if (bytes_read == 0) {
243-
response_promise_.set_value(*res);
250+
helper->response_promise_.set_value(*res);
244251
return;
245252
}
246253

247-
std::istream is(&response_buffer_);
254+
std::istream is(&helper->response_buffer_);
248255
string_type line;
249256
while (!getline_with_newline(is, line).eof()) {
250257
res->append_body(line);
251258
}
252259

253-
connection_->async_read(response_buffer_,
260+
helper->connection_->async_read(helper->response_buffer_,
254261
strand_.wrap(
255262
[=] (const boost::system::error_code &ec,
256263
std::size_t bytes_read) {
@@ -260,16 +267,18 @@ namespace network {
260267

261268
std::future<client::response> client::impl::do_request(method met,
262269
std::shared_ptr<request_helper> helper) {
263-
std::future<client::response> res = response_promise_.get_future();
270+
std::future<client::response> res = helper->response_promise_.get_future();
264271

265272
helper->request_.method(met);
266-
std::ostream request_stream(&request_buffer_);
273+
std::ostream request_stream(&helper->request_buffer_);
267274
request_stream << helper->request_;
268275
if (!request_stream) {
269-
response_promise_.set_exception(std::make_exception_ptr(
270-
client_exception(client_error::invalid_request)));
276+
helper->response_promise_.set_exception(
277+
std::make_exception_ptr(client_exception(client_error::invalid_request)));
271278
}
272279

280+
// TODO write payload to request_buffer_
281+
273282
// HTTP 1.1
274283
auto it = std::find_if(std::begin(helper->request_.headers()),
275284
std::end(helper->request_.headers()),
@@ -278,7 +287,7 @@ namespace network {
278287
});
279288
if (it == std::end(helper->request_.headers())) {
280289
// set error
281-
response_promise_.set_value(response());
290+
helper->response_promise_.set_value(response());
282291
return res;
283292
}
284293

@@ -312,27 +321,33 @@ namespace network {
312321
}
313322

314323
std::future<client::response> client::get(request req, request_options options) {
315-
return pimpl_->do_request(method::GET, std::make_shared<request_helper>(req, options));
324+
return pimpl_->do_request(method::get,
325+
std::make_shared<request_helper>(pimpl_->io_service_, req, options));
316326
}
317327

318328
std::future<client::response> client::post(request req, request_options options) {
319-
return pimpl_->do_request(method::POST, std::make_shared<request_helper>(req, options));
329+
return pimpl_->do_request(method::post,
330+
std::make_shared<request_helper>(pimpl_->io_service_, req, options));
320331
}
321332

322333
std::future<client::response> client::put(request req, request_options options) {
323-
return pimpl_->do_request(method::PUT, std::make_shared<request_helper>(req, options));
334+
return pimpl_->do_request(method::put,
335+
std::make_shared<request_helper>(pimpl_->io_service_, req, options));
324336
}
325337

326338
std::future<client::response> client::delete_(request req, request_options options) {
327-
return pimpl_->do_request(method::DELETE, std::make_shared<request_helper>(req, options));
339+
return pimpl_->do_request(method::delete_,
340+
std::make_shared<request_helper>(pimpl_->io_service_, req, options));
328341
}
329342

330343
std::future<client::response> client::head(request req, request_options options) {
331-
return pimpl_->do_request(method::HEAD, std::make_shared<request_helper>(req, options));
344+
return pimpl_->do_request(method::head,
345+
std::make_shared<request_helper>(pimpl_->io_service_, req, options));
332346
}
333347

334348
std::future<client::response> client::options(request req, request_options options) {
335-
return pimpl_->do_request(method::OPTIONS, std::make_shared<request_helper>(req, options));
349+
return pimpl_->do_request(method::options,
350+
std::make_shared<request_helper>(pimpl_->io_service_, req, options));
336351
}
337352
} // namespace v2
338353
} // namespace http

http/src/network/http/v2/client/request.hpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,21 @@ namespace network {
233233
* \brief Constructor.
234234
*/
235235
request()
236-
: byte_source_(nullptr) { }
236+
: is_https_(false),
237+
byte_source_(nullptr) { }
237238

238239
/**
239240
* \brief Constructor.
240241
*/
241-
explicit request(uri url) {
242+
explicit request(uri url)
243+
: is_https_(false) {
242244
if (auto scheme = url.scheme()) {
243245
if ((!boost::equal(*scheme, boost::as_literal("http"))) &&
244246
(!boost::equal(*scheme, boost::as_literal("https")))) {
245247
throw invalid_url();
246248
}
247249

250+
is_https_ = boost::equal(*scheme, boost::as_literal("https"));
248251
path_.assign(std::begin(*url.path()), std::end(*url.path()));
249252

250253
std::ostringstream oss;
@@ -266,7 +269,8 @@ namespace network {
266269
* \brief Copy constructor.
267270
*/
268271
request(const request &other)
269-
: method_(other.method_)
272+
: is_https_(other.is_https_)
273+
, method_(other.method_)
270274
, path_(other.path_)
271275
, version_(other.version_)
272276
, headers_(other.headers_)
@@ -276,7 +280,8 @@ namespace network {
276280
* \brief Move constructor.
277281
*/
278282
request(request &&other) noexcept
279-
: method_(std::move(other.method_))
283+
: is_https_(std::move(other.is_https_))
284+
, method_(std::move(other.method_))
280285
, path_(std::move(other.path_))
281286
, version_(std::move(other.version_))
282287
, headers_(std::move(other.headers_))
@@ -302,13 +307,18 @@ namespace network {
302307
*/
303308
void swap(request &other) noexcept {
304309
using std::swap;
310+
swap(is_https_, other.is_https_);
305311
swap(method_, other.method_);
306312
swap(path_, other.path_);
307313
swap(version_, other.version_);
308314
swap(headers_, other.headers_);
309315
swap(byte_source_, other.byte_source_);
310316
}
311317

318+
bool is_https() const {
319+
return is_https_;
320+
}
321+
312322
/**
313323
* \brief Sets the HTTP request method.
314324
* \param method The HTTP request method.
@@ -410,6 +420,7 @@ namespace network {
410420

411421
private:
412422

423+
bool is_https_;
413424
network::http::v2::method method_;
414425
string_type path_;
415426
string_type version_;

http/src/network/http/v2/method.hpp

+11-11
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,30 @@
1717
namespace network {
1818
namespace http {
1919
namespace v2 {
20-
enum class method { GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT, MERGE, PATCH, };
20+
enum class method { get, post, put, delete_, head, options, trace, connect, merge, patch, };
2121

2222
inline
2323
std::ostream &operator << (std::ostream &os, method m) {
2424
switch (m) {
25-
case method::GET:
25+
case method::get:
2626
return os << "GET";
27-
case method::POST:
27+
case method::post:
2828
return os << "POST";
29-
case method::PUT:
29+
case method::put:
3030
return os << "PUT";
31-
case method::DELETE:
31+
case method::delete_:
3232
return os << "DELETE";
33-
case method::HEAD:
33+
case method::head:
3434
return os << "HEAD";
35-
case method::OPTIONS:
35+
case method::options:
3636
return os << "OPTIONS";
37-
case method::TRACE:
37+
case method::trace:
3838
return os << "TRACE";
39-
case method::CONNECT:
39+
case method::connect:
4040
return os << "CONNECT";
41-
case method::MERGE:
41+
case method::merge:
4242
return os << "MERGE";
43-
case method::PATCH:
43+
case method::patch:
4444
return os << "PATCH";
4545
}
4646
return os;

http/test/v2/features/client/client_test.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Describe(http_client) {
2222
It(gets_a_header_response) {
2323
http::client::request request;
2424
request
25-
.method(http::method::GET)
25+
.method(http::method::get)
2626
.path("/LICENSE_1_0.txt")
2727
.version("1.1")
2828
.append_header("Host", "www.boost.org")

http/test/v2/features/client/normal_connection_test.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Describe(normal_http_connection) {
4646
// Create an HTTP request.
4747
http_cm::request request;
4848
request
49-
.method(http::method::GET)
49+
.method(http::method::get)
5050
.path("/LICENSE_1_0.txt")
5151
.version("1.0")
5252
.append_header("Host", "www.boost.org")

0 commit comments

Comments
 (0)