Skip to content

Commit 7cd2381

Browse files
committed
Modified connection interface and implemented the SSL connection.
1 parent fce0312 commit 7cd2381

File tree

11 files changed

+87
-52
lines changed

11 files changed

+87
-52
lines changed

contrib/http_examples/simple_wget.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
//[ simple_wget_main
88
/*`
9-
This is a very basic clone of wget. It's missing a lot of
9+
This is a very basic clone of wget. It's missing a lot of
1010
features, such as content-type detection, but it does the
1111
fundamental things the same.
1212
13-
It demonstrates the use the `uri` and the `http::client`.
13+
It demonstrates the use of the `uri` and the `http::client`.
1414
*/
1515

1616
#include <network/http/client.hpp>

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,11 @@ namespace network {
153153
return;
154154
}
155155

156+
auto host = helper->request_.url().host();
156157
tcp::endpoint endpoint(*endpoint_iterator);
157158
helper->connection_->async_connect(endpoint,
158-
strand_.wrap(
159+
std::string(std::begin(*host), std::end(*host)),
160+
strand_.wrap(
159161
[=] (const boost::system::error_code &ec) {
160162
if (ec && endpoint_iterator != tcp::resolver::iterator()) {
161163
// copy iterator because it is const after the lambda

http/src/network/http/v2/client/connection/async_connection.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ namespace network {
6464
* \param callback A callback handler.
6565
*/
6666
virtual void async_connect(const boost::asio::ip::tcp::endpoint &endpoint,
67+
const std::string &host,
6768
connect_callback callback) = 0;
6869

6970
/**

http/src/network/http/v2/client/connection/normal_connection.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace network {
4040
}
4141

4242
virtual void async_connect(const boost::asio::ip::tcp::endpoint &endpoint,
43+
const std::string &host,
4344
connect_callback callback) {
4445
using boost::asio::ip::tcp;
4546
socket_.reset(new tcp::socket{io_service_});

http/src/network/http/v2/client/connection/ssl_connection.hpp

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@
1818
#include <boost/asio/ssl.hpp>
1919
#include <boost/asio/placeholders.hpp>
2020
#include <network/config.hpp>
21-
#include <network/http/v2/client/connection/connection.hpp>
21+
#include <network/http/v2/client/connection/async_connection.hpp>
2222
#include <network/http/v2/client/client.hpp>
2323

2424
namespace network {
2525
namespace http {
2626
namespace v2 {
2727
namespace client_connection {
28-
class ssl_connection
29-
: public connection, std::enable_shared_from_this<ssl_connection> {
28+
class ssl_connection : public async_connection {
3029

3130
ssl_connection(const ssl_connection &) = delete;
3231
ssl_connection &operator = (const ssl_connection &) = delete;
@@ -44,12 +43,11 @@ namespace network {
4443
}
4544

4645
virtual void async_connect(const boost::asio::ip::tcp::endpoint &endpoint,
46+
const std::string &host,
4747
connect_callback callback) {
4848
context_.reset(new boost::asio::ssl::context(boost::asio::ssl::context::sslv23));
49-
std::vector<std::string> const& certificate_paths =
50-
options_.openssl_certificate_paths();
51-
std::vector<std::string> const& verifier_paths =
52-
options_.openssl_verify_paths();
49+
auto certificate_paths = options_.openssl_certificate_paths();
50+
auto verifier_paths = options_.openssl_verify_paths();
5351
bool use_default_verification = certificate_paths.empty() && verifier_paths.empty();
5452
if (!use_default_verification) {
5553
for (auto path : certificate_paths) {
@@ -59,7 +57,7 @@ namespace network {
5957
context_->add_verify_path(path);
6058
}
6159
context_->set_verify_mode(boost::asio::ssl::context::verify_peer);
62-
//context_->set_verify_callback(boost::asio::ssl::rfc2818_verification(host));
60+
context_->set_verify_callback(boost::asio::ssl::rfc2818_verification(host));
6361
}
6462
else {
6563
context_->set_default_verify_paths();
@@ -69,18 +67,27 @@ namespace network {
6967
boost::asio::ip::tcp::socket>(io_service_, *context_));
7068

7169
using namespace std::placeholders;
72-
socket_->lowest_layer()
73-
.async_connect(endpoint, callback);
70+
socket_->lowest_layer().async_connect(endpoint,
71+
[=] (const boost::system::error_code &ec) {
72+
handle_connected(ec, callback);
73+
});
7474
}
7575

7676
virtual void async_write(boost::asio::streambuf &command_streambuf,
7777
write_callback callback) {
7878
boost::asio::async_write(*socket_, command_streambuf, callback);
7979
}
8080

81-
virtual void async_read_some(const boost::asio::mutable_buffers_1 &read_buffer,
82-
read_callback callback) {
83-
socket_->async_read_some(read_buffer, callback);
81+
virtual void async_read_until(boost::asio::streambuf &command_streambuf,
82+
const std::string &delim,
83+
read_callback callback) {
84+
boost::asio::async_read_until(*socket_, command_streambuf, delim, callback);
85+
}
86+
87+
virtual void async_read(boost::asio::streambuf &command_streambuf,
88+
read_callback callback) {
89+
boost::asio::async_read(*socket_, command_streambuf,
90+
boost::asio::transfer_at_least(1), callback);
8491
}
8592

8693
virtual void cancel() {
@@ -89,6 +96,23 @@ namespace network {
8996

9097
private:
9198

99+
void handle_connected(const boost::system::error_code &ec, connect_callback callback) {
100+
if (!ec) {
101+
auto existing_session = SSL_get1_session(socket_->native_handle());
102+
if (existing_session) {
103+
socket_->async_handshake(boost::asio::ssl::stream_base::client, callback);
104+
}
105+
else {
106+
SSL_set_session(socket_->native_handle(), existing_session);
107+
SSL_connect(socket_->native_handle());
108+
callback(ec);
109+
}
110+
}
111+
else {
112+
callback(ec);
113+
}
114+
}
115+
92116
boost::asio::io_service &io_service_;
93117
client_options options_;
94118
std::unique_ptr<boost::asio::ssl::context> context_;

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

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ namespace network {
173173

174174
/**
175175
* \brief Allows the request to read the data into a local
176-
* copy of it's source string.
176+
* copy of its source string.
177177
*/
178178
virtual size_type read(string_type &source, size_type length) = 0;
179179

@@ -221,6 +221,12 @@ namespace network {
221221
*/
222222
typedef byte_source::string_type string_type;
223223

224+
/**
225+
* \typedef size_type
226+
* \brief The request size type.
227+
*/
228+
typedef byte_source::size_type size_type;
229+
224230
/**
225231
* \typedef headers_type
226232
* \brief The request headers type.
@@ -415,6 +421,13 @@ namespace network {
415421
return *this;
416422
}
417423

424+
template <class Handler>
425+
void body(size_type length, Handler &&handler) {
426+
string_type body;
427+
byte_source_->read(body, length);
428+
handler(body);
429+
}
430+
418431
/**
419432
* \brief Appends a header to the request.
420433
* \param name The header name.
@@ -436,12 +449,20 @@ namespace network {
436449
return boost::optional<string_type>();
437450
}
438451

452+
const_headers_iterator headers_begin() const {
453+
return std::begin(headers_);
454+
}
455+
456+
const_headers_iterator headers_end() const {
457+
return std::end(headers_);
458+
}
459+
439460
/**
440461
* \brief Returns the headers range.
441462
* \returns An iterator range covering all headers.
442463
*/
443464
boost::iterator_range<const_headers_iterator> headers() const {
444-
return boost::make_iterator_range(std::begin(headers_), std::end(headers_));
465+
return boost::make_iterator_range(headers_begin(), headers_end());
445466
}
446467

447468
/**

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,21 @@ namespace network {
170170
headers_.push_back(std::make_pair(name, value));
171171
}
172172

173+
const_headers_iterator headers_begin() const {
174+
return std::begin(headers_);
175+
}
176+
177+
const_headers_iterator headers_end() const {
178+
return std::end(headers_);
179+
}
180+
173181
/**
174182
* \brief Returns the full range of headers.
175183
* \returns An iterator range covering the HTTP response
176184
* headers.
177185
*/
178186
boost::iterator_range<const_headers_iterator> headers() const {
179-
return boost::make_iterator_range(std::begin(headers_), std::end(headers_));
180-
}
181-
182-
void append_body(const char *body, std::size_t length) {
183-
body_.reserve(body_.size() + length);
184-
body_.append(body);
187+
return boost::make_iterator_range(headers_begin(), headers_end());
185188
}
186189

187190
void append_body(string_type body) {

http/test/v2/client/features/CMakeLists.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ set(CPP-NETLIB_CLIENT_TESTS
99
http_client_test
1010
)
1111

12-
#if (OPENSSL_FOUND)
13-
# list(APPEND CPP-NETLIB_CLIENT_TESTS ssl_connection_test)
14-
#endif()
12+
if (OPENSSL_FOUND)
13+
list(APPEND CPP-NETLIB_CLIENT_TESTS ssl_connection_test)
14+
endif()
1515

1616
foreach(test ${CPP-NETLIB_CLIENT_TESTS})
1717
if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
@@ -34,6 +34,6 @@ foreach(test ${CPP-NETLIB_CLIENT_TESTS})
3434

3535
endforeach(test)
3636

37-
#if (OPENSSL_FOUND)
38-
# target_link_libraries(cpp-netlib-http-v2-ssl_connection_test ${OPENSSL_LIBRARIES})
39-
#endif()
37+
if (OPENSSL_FOUND)
38+
target_link_libraries(cpp-netlib-http-v2-ssl_connection_test ${OPENSSL_LIBRARIES})
39+
endif()

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Describe(normal_http_connection) {
3636
// Make sure that the connection is successful.
3737
tcp::endpoint endpoint(it->endpoint());
3838
connection_->async_connect(endpoint,
39+
"www.boost.org",
3940
[&ec] (const boost::system::error_code &ec_) {
4041
ec = ec_;
4142
});

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

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <thread>
88
#include <igloo/igloo_alt.h>
99
#include <boost/asio.hpp>
10-
#include "network/http/v2/client/connection/ssl_connection_delegate.hpp"
10+
#include "network/http/v2/client/connection/ssl_connection.hpp"
1111
#include "network/http/v2/client/request.hpp"
1212

1313
using namespace igloo;
@@ -20,36 +20,17 @@ Describe(https_connection) {
2020
io_service_.reset(new boost::asio::io_service);
2121
resolver_.reset(new tcp::resolver(*io_service_));
2222
options_.reset(new http::client_options);
23-
connection_.reset(new http::ssl_connection_delegate(*io_service_, *options_));
24-
socket_.reset(new tcp::socket(*io_service_));
23+
connection_.reset(new http::client_connection::ssl_connection(*io_service_, *options_));
2524
}
2625

2726
void TearDown() {
28-
socket_->close();
29-
}
3027

31-
It(connects_to_localhost) {
32-
// Resolve the host.
33-
boost::system::error_code ec;
34-
tcp::resolver::query query("127.0.0.1", "80");
35-
auto it = resolver_->resolve(query, ec);
36-
Assert::That(ec, Equals(boost::system::error_code()));
37-
38-
// Make sure that the connection is successful.
39-
tcp::endpoint endpoint(it->endpoint());
40-
connection_->async_connect(endpoint, "127.0.0.1",
41-
[&ec] (const boost::system::error_code &ec_) {
42-
ec = ec_;
43-
});
44-
io_service_->run_one();
45-
Assert::That(ec, Equals(boost::system::error_code()));
4628
}
4729

4830
std::unique_ptr<boost::asio::io_service> io_service_;
4931
std::unique_ptr<tcp::resolver> resolver_;
5032
std::unique_ptr<http::client_options> options_;
51-
std::unique_ptr<http::connection_delegate> connection_;
52-
std::unique_ptr<tcp::socket> socket_;
33+
std::unique_ptr<http::client_connection::async_connection> connection_;
5334

5435
};
5536

0 commit comments

Comments
 (0)