Skip to content

Request sni hostname #787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions boost/network/protocol/http/client/connection/async_normal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ struct http_async_connection
string_type host_ = host(request);
std::uint16_t source_port = request.source_port();

auto sni_hostname = request.sni_hostname();

auto self = this->shared_from_this();
resolve_(resolver_, host_, port_,
request_strand_.wrap(
[=] (boost::system::error_code const &ec,
resolver_iterator_pair endpoint_range) {
self->handle_resolved(host_, port_, source_port, get_body,
self->handle_resolved(host_, port_, source_port, sni_hostname, get_body,
callback, generator, ec, endpoint_range);
}));
if (timeout_ > 0) {
Expand Down Expand Up @@ -139,7 +141,7 @@ struct http_async_connection
}

void handle_resolved(string_type host, std::uint16_t port,
std::uint16_t source_port, bool get_body,
std::uint16_t source_port, optional<string_type> sni_hostname, bool get_body,
body_callback_function_type callback,
body_generator_function_type generator,
boost::system::error_code const& ec,
Expand All @@ -151,10 +153,10 @@ struct http_async_connection
boost::asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port);
auto self = this->shared_from_this();
delegate_->connect(
endpoint, host, source_port,
endpoint, host, source_port, sni_hostname,
request_strand_.wrap([=] (boost::system::error_code const &ec) {
auto iter_copy = iter;
self->handle_connected(host, port, source_port, get_body, callback,
self->handle_connected(host, port, source_port, sni_hostname, get_body, callback,
generator, std::make_pair(++iter_copy, resolver_iterator()), ec);
}));
} else {
Expand All @@ -163,7 +165,7 @@ struct http_async_connection
}

void handle_connected(string_type host, std::uint16_t port,
std::uint16_t source_port, bool get_body,
std::uint16_t source_port, optional<string_type> sni_hostname, bool get_body,
body_callback_function_type callback,
body_generator_function_type generator,
resolver_iterator_pair endpoint_range,
Expand All @@ -186,10 +188,10 @@ struct http_async_connection
boost::asio::ip::tcp::endpoint endpoint(iter->endpoint().address(), port);
auto self = this->shared_from_this();
delegate_->connect(
endpoint, host, source_port,
endpoint, host, source_port, sni_hostname,
request_strand_.wrap([=] (boost::system::error_code const &ec) {
auto iter_copy = iter;
self->handle_connected(host, port, source_port, get_body, callback,
self->handle_connected(host, port, source_port, sni_hostname, get_body, callback,
generator, std::make_pair(++iter_copy, resolver_iterator()),
ec);
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <functional>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/optional.hpp>

namespace boost {
namespace network {
Expand All @@ -19,7 +20,7 @@ namespace impl {

struct connection_delegate {
virtual void connect(boost::asio::ip::tcp::endpoint &endpoint, std::string host,
std::uint16_t source_port,
std::uint16_t source_port, optional<std::string> sni_hostname,
std::function<void(boost::system::error_code const &)> handler) = 0;
virtual void write(
boost::asio::streambuf &command_streambuf,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct normal_delegate : connection_delegate {
explicit normal_delegate(boost::asio::io_service &service);

void connect(boost::asio::ip::tcp::endpoint &endpoint, std::string host,
std::uint16_t source_port,
std::uint16_t source_port, optional<std::string> sni_hostname,
std::function<void(boost::system::error_code const &)> handler) override;
void write(boost::asio::streambuf &command_streambuf,
std::function<void(boost::system::error_code const &, size_t)> handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ boost::network::http::impl::normal_delegate::normal_delegate(

void boost::network::http::impl::normal_delegate::connect(
boost::asio::ip::tcp::endpoint &endpoint, std::string host,
std::uint16_t source_port,
std::uint16_t source_port, optional<std::string> sni_hostname,
std::function<void(boost::system::error_code const &)> handler) {

// TODO(dberris): review parameter necessity.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct ssl_delegate : public connection_delegate,
optional<std::string> sni_hostname, long ssl_options);

void connect(boost::asio::ip::tcp::endpoint &endpoint, std::string host,
std::uint16_t source_port,
std::uint16_t source_port, optional<std::string> sni_hostname,
std::function<void(boost::system::error_code const &)> handler) override;
void write(
boost::asio::streambuf &command_streambuf,
Expand Down
10 changes: 8 additions & 2 deletions boost/network/protocol/http/client/connection/ssl_delegate.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ boost::network::http::impl::ssl_delegate::ssl_delegate(

void boost::network::http::impl::ssl_delegate::connect(
boost::asio::ip::tcp::endpoint &endpoint, std::string host,
std::uint16_t source_port,
std::uint16_t source_port, optional<std::string> sni_hostname,
std::function<void(boost::system::error_code const &)> handler) {

context_.reset(
new boost::asio::ssl::context(boost::asio::ssl::context::method::sslv23_client));
if (ciphers_) {
Expand Down Expand Up @@ -71,8 +72,13 @@ void boost::network::http::impl::ssl_delegate::connect(
socket_.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket &>(
*(tcp_socket_.get()), *context_));

if (sni_hostname_)
if (sni_hostname) { // at request level
SSL_set_tlsext_host_name(socket_->native_handle(), sni_hostname->c_str());
} else if (sni_hostname_) { // at client level
SSL_set_tlsext_host_name(socket_->native_handle(), sni_hostname_->c_str());
}


if (always_verify_peer_)
socket_->set_verify_callback(boost::asio::ssl::rfc2818_verification(host));
auto self = this->shared_from_this();
Expand Down
24 changes: 16 additions & 8 deletions boost/network/protocol/http/impl/request.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,32 @@ namespace http {
*/
template <class Tag>
struct basic_request : public basic_message<Tag> {
mutable boost::network::uri::uri uri_;
std::uint16_t source_port_;
typedef basic_message<Tag> base_type;

public:
typedef Tag tag;
typedef typename string<tag>::type string_type;
typedef std::uint16_t port_type;

private:
mutable boost::network::uri::uri uri_;
std::uint16_t source_port_;
optional<string_type> sni_hostname_;
typedef basic_message<Tag> base_type;

public:
explicit basic_request(string_type const& uri_)
: uri_(uri_), source_port_(0) {}
: uri_(uri_), source_port_(0), sni_hostname_() {}

explicit basic_request(boost::network::uri::uri const& uri_)
: uri_(uri_), source_port_(0) {}
: uri_(uri_), source_port_(0), sni_hostname_() {}

void uri(string_type const& new_uri) { uri_ = new_uri; }

void uri(boost::network::uri::uri const& new_uri) { uri_ = new_uri; }

basic_request() : base_type(), source_port_(0) {}
basic_request() : base_type(), source_port_(0), sni_hostname_() {}

basic_request(basic_request const& other)
: base_type(other), uri_(other.uri_), source_port_(other.source_port_) {}
: base_type(other), uri_(other.uri_), source_port_(other.source_port_), sni_hostname_(other.sni_hostname_) {}

basic_request& operator=(basic_request rhs) {
rhs.swap(*this);
Expand All @@ -85,6 +88,7 @@ struct basic_request : public basic_message<Tag> {
base_ref.swap(this_ref);
boost::swap(other.uri_, this->uri_);
boost::swap(other.source_port_, this->source_port_);
boost::swap(other.sni_hostname_, this->sni_hostname_);
}

string_type const host() const { return uri_.host(); }
Expand Down Expand Up @@ -114,6 +118,10 @@ struct basic_request : public basic_message<Tag> {
void source_port(const std::uint16_t port) { source_port_ = port; }

std::uint16_t source_port() const { return source_port_; }

void sni_hostname(string_type const &sni_hostname) { sni_hostname_ = sni_hostname; }

const optional<string_type> &sni_hostname() const { return sni_hostname_; }
};

/** This is the implementation of a POD request type
Expand Down
25 changes: 25 additions & 0 deletions libs/network/test/http/client_get_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,31 @@ TYPED_TEST(HTTPClientTest, GetHTTPSTest) {
}
}

TYPED_TEST(HTTPClientTest, GetRequestSNI) {
using client = TypeParam;
// need sni_hostname to be set
typename client::request request("https://www.guide-du-chien.com/wp-content/uploads/2016/10/Beagle.jpg");
typename client::response response;

// trying without setting sni_hostname
ASSERT_NO_THROW(response = client().get(request));
// raise "tlsv1 alert internal error"
ASSERT_THROW(response.status(), std::exception_ptr);

// setting sni_hostname
request.sni_hostname(request.host());
ASSERT_NO_THROW(response = client().get(request));
EXPECT_EQ(200u, response.status());

try {
auto data = body(response);
std::cout << "Body size: " << data.size() << std::endl;
} catch (...) {
FAIL() << "Caught exception while retrieving body from GET request";
}

}

#endif

TYPED_TEST(HTTPClientTest, TemporaryClientObjectTest) {
Expand Down