Skip to content

Commit e70b277

Browse files
committed
Checking in implementation of HTTPS server and client tests; HTTPS localhost is still broken.
1 parent afe6866 commit e70b277

11 files changed

+561
-54
lines changed

boost/network/protocol/http/impl/sync_connection_base.hpp

+117-45
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,15 @@
1313

1414
namespace boost { namespace network { namespace http { namespace impl {
1515
template <class Tag, unsigned version_major, unsigned version_minor>
16-
struct sync_connection_base;
17-
18-
template <class Tag, unsigned version_major, unsigned version_minor>
19-
struct https_sync_connection : public virtual sync_connection_base<Tag,version_major,version_minor>, detail::connection_helper<Tag, version_major, version_minor> {
20-
typedef typename resolver_policy<Tag>::type resolver_base;
21-
typedef typename resolver_base::resolver_type resolver_type;
22-
typedef typename string<Tag>::type string_type;
23-
typedef function<typename resolver_base::resolver_iterator_pair(resolver_type&, string_type const &, string_type const &)> resolver_function_type;
24-
25-
https_sync_connection(resolver_type & resolver, resolver_function_type resolve)
26-
: resolver_(resolver), resolve_(resolve), context_(resolver.io_service(), boost::asio::ssl::context::sslv23_client), socket_(resolver.io_service(), context_) { }
27-
28-
void init_socket(string_type const & hostname, string_type const & port) {}
29-
void send_request_impl(string_type const & method, basic_request<Tag> const & request_) {}
30-
void read_status(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
31-
void read_headers(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
32-
void read_body(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {}
33-
bool is_open() { return socket_.lowest_layer().is_open(); }
34-
void close_socket() { if (is_open()) { socket_.lowest_layer().close(); } }
35-
~https_sync_connection() {}
36-
private:
37-
resolver_type & resolver_;
38-
resolver_function_type resolve_;
39-
boost::asio::ssl::context context_;
40-
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
41-
42-
};
43-
44-
template <class Tag, unsigned version_major, unsigned version_minor>
45-
struct http_sync_connection : public virtual sync_connection_base<Tag, version_major, version_minor>, detail::connection_helper<Tag, version_major, version_minor> {
16+
struct connection_base_impl {
17+
protected:
4618
typedef typename resolver_policy<Tag>::type resolver_base;
4719
typedef typename resolver_base::resolver_type resolver_type;
4820
typedef typename string<Tag>::type string_type;
4921
typedef function<typename resolver_base::resolver_iterator_pair(resolver_type&, string_type const &, string_type const &)> resolver_function_type;
5022

51-
http_sync_connection(resolver_type & resolver, resolver_function_type resolve)
52-
: resolver_(resolver), resolve_(resolve), socket_(resolver.io_service()) { }
53-
54-
~http_sync_connection() {}
55-
56-
void init_socket(string_type const & hostname, string_type const & port) {
23+
template <class Socket>
24+
void init_socket(Socket & socket_, resolver_type & resolver_, string_type const & hostname, string_type const & port, resolver_function_type resolve_) {
5725
using boost::asio::ip::tcp;
5826
boost::system::error_code error = boost::asio::error::host_not_found;
5927
typename resolver_type::iterator endpoint_iterator, end;
@@ -74,13 +42,8 @@ namespace boost { namespace network { namespace http { namespace impl {
7442
throw boost::system::system_error(error);
7543
}
7644

77-
void send_request_impl(string_type const & method, basic_request<Tag> const & request_) {
78-
boost::asio::streambuf request_buffer;
79-
create_request(request_buffer, method, request_);
80-
write(socket_, request_buffer);
81-
}
82-
83-
void read_status(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
45+
template <class Socket>
46+
void read_status(Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
8447
boost::asio::read_until(socket_, response_buffer, "\r\n");
8548
std::istream response_stream(&response_buffer);
8649
string_type http_version;
@@ -100,7 +63,8 @@ namespace boost { namespace network { namespace http { namespace impl {
10063
response_.status_message() = status_message;
10164
}
10265

103-
void read_headers(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
66+
template <class Socket>
67+
void read_headers(Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
10468
boost::asio::read_until(socket_, response_buffer, "\r\n\r\n");
10569
std::istream response_stream(&response_buffer);
10670
string_type header_line, name;
@@ -124,7 +88,13 @@ namespace boost { namespace network { namespace http { namespace impl {
12488
};
12589
}
12690

127-
void read_body(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
91+
template <class Socket>
92+
void send_request_impl(Socket & socket_, string_type const & method, boost::asio::streambuf & request_buffer) {
93+
write(socket_, request_buffer);
94+
}
95+
96+
template <class Socket>
97+
void read_body(Socket & socket_, basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
12898
typename ostringstream<Tag>::type body_stream;
12999

130100
if (response_buffer.size() > 0)
@@ -159,6 +129,108 @@ namespace boost { namespace network { namespace http { namespace impl {
159129
response_ << body(body_stream.str());
160130
}
161131

132+
133+
};
134+
135+
template <class Tag, unsigned version_major, unsigned version_minor>
136+
struct sync_connection_base;
137+
138+
template <class Tag, unsigned version_major, unsigned version_minor>
139+
struct https_sync_connection : public virtual sync_connection_base<Tag,version_major,version_minor>, detail::connection_helper<Tag, version_major, version_minor>, connection_base_impl<Tag, version_major, version_minor> {
140+
typedef typename resolver_policy<Tag>::type resolver_base;
141+
typedef typename resolver_base::resolver_type resolver_type;
142+
typedef typename string<Tag>::type string_type;
143+
typedef function<typename resolver_base::resolver_iterator_pair(resolver_type&, string_type const &, string_type const &)> resolver_function_type;
144+
typedef connection_base_impl<Tag,version_major,version_minor> connection_base;
145+
146+
https_sync_connection(resolver_type & resolver, resolver_function_type resolve, optional<string_type> const & certificate_filename = optional<string_type>())
147+
: connection_base(), resolver_(resolver), resolve_(resolve), context_(resolver.io_service(), boost::asio::ssl::context::sslv23_client), socket_(resolver.io_service(), context_) {
148+
if (certificate_filename) {
149+
context_.set_verify_mode(boost::asio::ssl::context::verify_peer);
150+
context_.load_verify_file(*certificate_filename);
151+
} else {
152+
context_.set_verify_mode(boost::asio::ssl::context::verify_none);
153+
}
154+
}
155+
156+
void init_socket(string_type const & hostname, string_type const & port) {
157+
connection_base::init_socket(socket_.lowest_layer(), resolver_, hostname, port, resolve_);
158+
socket_.handshake(boost::asio::ssl::stream_base::client);
159+
}
160+
161+
void send_request_impl(string_type const & method, basic_request<Tag> const & request_) {
162+
boost::asio::streambuf request_buffer;
163+
create_request(request_buffer, method, request_);
164+
connection_base::send_request_impl(socket_, method, request_buffer);
165+
}
166+
167+
void read_status(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
168+
connection_base::read_status(socket_, response_, response_buffer);
169+
}
170+
171+
void read_headers(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
172+
connection_base::read_headers(socket_, response_, response_buffer);
173+
}
174+
175+
void read_body(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
176+
connection_base::read_body(socket_, response_, response_buffer);
177+
}
178+
179+
bool is_open() {
180+
return socket_.lowest_layer().is_open();
181+
}
182+
183+
void close_socket() {
184+
if (is_open()) {
185+
socket_.lowest_layer().close();
186+
}
187+
}
188+
189+
~https_sync_connection() {}
190+
191+
private:
192+
resolver_type & resolver_;
193+
resolver_function_type resolve_;
194+
boost::asio::ssl::context context_;
195+
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
196+
197+
};
198+
199+
template <class Tag, unsigned version_major, unsigned version_minor>
200+
struct http_sync_connection : public virtual sync_connection_base<Tag, version_major, version_minor>, detail::connection_helper<Tag, version_major, version_minor>, connection_base_impl<Tag, version_major, version_minor> {
201+
typedef typename resolver_policy<Tag>::type resolver_base;
202+
typedef typename resolver_base::resolver_type resolver_type;
203+
typedef typename string<Tag>::type string_type;
204+
typedef function<typename resolver_base::resolver_iterator_pair(resolver_type&, string_type const &, string_type const &)> resolver_function_type;
205+
typedef connection_base_impl<Tag,version_major,version_minor> connection_base;
206+
207+
http_sync_connection(resolver_type & resolver, resolver_function_type resolve)
208+
: connection_base(), resolver_(resolver), resolve_(resolve), socket_(resolver.io_service()) { }
209+
210+
~http_sync_connection() {}
211+
212+
void init_socket(string_type const & hostname, string_type const & port) {
213+
connection_base::init_socket(socket_, resolver_, hostname, port, resolve_);
214+
}
215+
216+
void send_request_impl(string_type const & method, basic_request<Tag> const & request_) {
217+
boost::asio::streambuf request_buffer;
218+
create_request(request_buffer, method, request_);
219+
connection_base::send_request_impl(socket_, method, request_buffer);
220+
}
221+
222+
void read_status(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
223+
connection_base::read_status(socket_, response_, response_buffer);
224+
}
225+
226+
void read_headers(basic_response<Tag> & response, boost::asio::streambuf & response_buffer) {
227+
connection_base::read_headers(socket_, response, response_buffer);
228+
}
229+
230+
void read_body(basic_response<Tag> & response_, boost::asio::streambuf & response_buffer) {
231+
connection_base::read_body(socket_, response_, response_buffer);
232+
}
233+
162234
bool is_open() { return socket_.is_open(); }
163235

164236
void close_socket() { if (is_open()) { socket_.close(); } }

boost/network/uri/http/uri.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <boost/network/uri/http/detail/parse_specific.hpp>
1515
#include <boost/network/uri/http/detail/uri_parts.hpp>
1616
#include <boost/network/uri/http/uri_concept.hpp>
17+
#include <boost/algorithm/string/predicate.hpp>
1718

1819
namespace boost { namespace network { namespace uri {
1920

@@ -31,8 +32,8 @@ namespace boost { namespace network { namespace uri {
3132
}
3233

3334
uint32_t port() const {
34-
return parts_.port ? *parts_.port :
35-
(parts_.scheme == "https" ? 443u : 80u);
35+
return parts_.port ? *(parts_.port) :
36+
(boost::iequals(parts_.scheme, string_type("https")) ? 443u : 80u);
3637
}
3738

3839
string_type path() const {

libs/network/test/CMakeLists.txt

+7-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ if (Boost_FOUND)
77
add_executable(cpp-netlib-hello_world hello_world.cpp)
88
add_executable(cpp-netlib-http_1_0_test http_1_0_test.cpp)
99
add_executable(cpp-netlib-http_1_1_test http_1_1_test.cpp)
10-
add_executable(cpp-netlib-localhost_tests localhost_tests.cpp)
10+
add_executable(cpp-netlib-http_localhost_tests http_localhost_tests.cpp)
11+
add_executable(cpp-netlib-https_localhost_tests https_localhost_tests.cpp)
1112
add_executable(cpp-netlib-message_test message_test.cpp)
1213
add_executable(cpp-netlib-http_message_test http_message_test.cpp)
1314
add_executable(cpp-netlib-message_transform_test message_transform_test.cpp)
@@ -18,13 +19,15 @@ if (Boost_FOUND)
1819
target_link_libraries(cpp-netlib-http_message_test ${Boost_LIBRARIES} pthread ssl)
1920
target_link_libraries(cpp-netlib-message_test ${Boost_LIBRARIES} pthread ssl)
2021
target_link_libraries(cpp-netlib-message_transform_test ${Boost_LIBRARIES} pthread ssl)
21-
target_link_libraries(cpp-netlib-localhost_tests ${Boost_LIBRARIES} pthread ssl)
22+
target_link_libraries(cpp-netlib-http_localhost_tests ${Boost_LIBRARIES} pthread ssl)
23+
target_link_libraries(cpp-netlib-https_localhost_tests ${Boost_LIBRARIES} pthread ssl)
2224
target_link_libraries(cpp-netlib-url_test ${Boost_LIBRARIES} pthread ssl)
23-
set_target_properties(cpp-netlib-hello_world cpp-netlib-http_1_0_test cpp-netlib-http_1_1_test cpp-netlib-message_test cpp-netlib-http_message_test cpp-netlib-message_transform_test cpp-netlib-localhost_tests cpp-netlib-url_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests)
25+
set_target_properties(cpp-netlib-hello_world cpp-netlib-http_1_0_test cpp-netlib-http_1_1_test cpp-netlib-message_test cpp-netlib-http_message_test cpp-netlib-message_transform_test cpp-netlib-http_localhost_tests cpp-netlib-https_localhost_tests cpp-netlib-url_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../../../build/tests)
2426
add_test(cpp-netlib-hello_world python httplib_acceptance.py ../../../build/tests/cpp-netlib-hello_world ../../../build/tests/cpp-netlib-hello_world.passed)
2527
add_test(cpp-netlib-http_1_0_test ../../../build/tests/cpp-netlib-http_1_0_test)
2628
add_test(cpp-netlib-http_1_1_test ../../../build/tests/cpp-netlib-http_1_1_test)
27-
add_test(cpp-netlib-localhost_tests ../../../build/tests/cpp-netlib-localhost_tests)
29+
add_test(cpp-netlib-http_localhost_tests ../../../build/tests/cpp-netlib-http_localhost_tests)
30+
add_test(cpp-netlib-https_localhost_tests ../../../build/tests/cpp-netlib-https_localhost_tests)
2831
add_test(cpp-netlib-message_test ../../../build/tests/cpp-netlib-message_test)
2932
add_test(cpp-netlib-http_message_test ../../../build/tests/cpp-netlib-http_message_test)
3033
add_test(cpp-netlib-url_test ../../../build/tests/cpp-netlib-url_test)

libs/network/test/Jamfile.v2

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ project network_test :
3434
<link>static
3535
;
3636

37-
unit-test localhost_tests : localhost_tests.cpp ;
37+
unit-test http_localhost_tests : http_localhost_tests.cpp ;
38+
39+
unit-test https_localhost_tests : https_localhost_tests.cpp ;
3840

3941
unit-test message_test : message_test.cpp ;
4042

0 commit comments

Comments
 (0)