Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[#600] Add TLS SNI hostname to client options#602

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
deanberris merged 1 commit intocpp-netlib:masterfromtheopolis:master
Feb 18, 2016
Merged
Show file tree
Hide file tree
Changes fromall 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
[#600] Add TLS SNI hostname to client options
  • Loading branch information
Teddy Reed committedFeb 18, 2016
commit1e18406f6e06815a7aabe414b5e312c8e156a81d
17 changes: 10 additions & 7 deletionsboost/network/protocol/http/client/async_impl.hpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,8 @@ struct async_client
typedef typename string<Tag>::type string_type;

typedef std::function<void(boost::iterator_range<char const*> const&,
std::error_code const&)> body_callback_function_type;
std::error_code const&)>
body_callback_function_type;

typedef std::function<bool(string_type&)> body_generator_function_type;

Expand All@@ -43,11 +44,11 @@ struct async_client
optional<string_type> verify_path,
optional<string_type> certificate_file,
optional<string_type> private_key_file,
optional<string_type> ciphers, long ssl_options)
optional<string_type> ciphers,
optional<string_type> sni_hostname, long ssl_options)
: connection_base(cache_resolved, follow_redirect, timeout),
service_ptr(service.get()
? service
: std::make_shared<asio::io_service>()),
service_ptr(service.get() ? service
: std::make_shared<asio::io_service>()),
service_(*service_ptr),
resolver_(service_),
sentinel_(new asio::io_service::work(service_)),
Expand All@@ -56,12 +57,13 @@ struct async_client
certificate_file_(std::move(certificate_file)),
private_key_file_(std::move(private_key_file)),
ciphers_(std::move(ciphers)),
sni_hostname_(std::move(sni_hostname)),
ssl_options_(ssl_options),
always_verify_peer_(always_verify_peer) {
connection_base::resolver_strand_.reset(
new asio::io_service::strand(service_));
if (!service)
lifetime_thread_.reset(new std::thread([this]() { service_.run(); }));
lifetime_thread_.reset(new std::thread([this]() { service_.run(); }));
}

~async_client() throw() = default;
Expand All@@ -82,7 +84,7 @@ struct async_client
connection_ = connection_base::get_connection(
resolver_, request_, always_verify_peer_, certificate_filename_,
verify_path_, certificate_file_, private_key_file_, ciphers_,
ssl_options_);
sni_hostname_,ssl_options_);
return connection_->send_request(method, request_, get_body, callback,
generator);
}
Expand All@@ -97,6 +99,7 @@ struct async_client
optional<string_type> certificate_file_;
optional<string_type> private_key_file_;
optional<string_type> ciphers_;
optional<string_type> sni_hostname_;
long ssl_options_;
bool always_verify_peer_;
};
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,14 +46,15 @@ struct async_connection_base {
optional<string_type> certificate_file = optional<string_type>(),
optional<string_type> private_key_file = optional<string_type>(),
optional<string_type> ciphers = optional<string_type>(),
optional<string_type> sni_hostname = optional<string_type>(),
long ssl_options = 0) {
typedef http_async_connection<Tag, version_major, version_minor>
async_connection;
typedeftypename delegate_factory<Tag>::type delegate_factory_type;
auto delegate =delegate_factory_type::new_connection_delegate(
resolver.get_io_service(), https, always_verify_peer,
certificate_filename, verify_path, certificate_file, private_key_file,
ciphers, ssl_options);
ciphers,sni_hostname,ssl_options);
auto temp = std::make_shared<async_connection>(
resolver, resolve, follow_redirect, timeout,std::move(delegate));
BOOST_ASSERT(temp !=nullptr);
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -38,13 +38,14 @@ struct connection_delegate_factory {
optional<string_type> certificate_filename,
optional<string_type> verify_path, optional<string_type> certificate_file,
optional<string_type> private_key_file, optional<string_type> ciphers,
long ssl_options) {
optional<string_type> sni_hostname,long ssl_options) {
connection_delegate_ptr delegate;
if (https) {
#ifdef BOOST_NETWORK_ENABLE_HTTPS
delegate = std::make_shared<ssl_delegate>(
service, always_verify_peer, certificate_filename, verify_path,
certificate_file, private_key_file, ciphers, ssl_options);
certificate_file, private_key_file, ciphers, sni_hostname,
ssl_options);
#else
BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported."));
#endif/* BOOST_NETWORK_ENABLE_HTTPS*/
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,7 +29,8 @@ struct ssl_delegate : public connection_delegate,
optional<std::string> verify_path,
optional<std::string> certificate_file,
optional<std::string> private_key_file,
optional<std::string> ciphers,long ssl_options);
optional<std::string> ciphers,
optional<std::string> sni_hostname,long ssl_options);

voidconnect(asio::ip::tcp::endpoint &endpoint, std::string host,
std::uint16_t source_port,
Expand All@@ -50,6 +51,7 @@ struct ssl_delegate : public connection_delegate,
optional<std::string> certificate_file_;
optional<std::string> private_key_file_;
optional<std::string> ciphers_;
optional<std::string> sni_hostname_;
long ssl_options_;
std::unique_ptr<asio::ssl::context> context_;
std::unique_ptr<asio::ip::tcp::socket> tcp_socket_;
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,13 +17,14 @@ boost::network::http::impl::ssl_delegate::ssl_delegate(
optional<std::string> certificate_filename,
optional<std::string> verify_path, optional<std::string> certificate_file,
optional<std::string> private_key_file, optional<std::string> ciphers,
long ssl_options)
optional<std::string> sni_hostname,long ssl_options)
: service_(service),
certificate_filename_(std::move(certificate_filename)),
verify_path_(std::move(verify_path)),
certificate_file_(std::move(certificate_file)),
private_key_file_(std::move(private_key_file)),
ciphers_(std::move(ciphers)),
sni_hostname_(std::move(sni_hostname)),
ssl_options_(ssl_options),
always_verify_peer_(always_verify_peer) {}

Expand DownExpand Up@@ -58,25 +59,23 @@ void boost::network::http::impl::ssl_delegate::connect(
}
}
if (certificate_file_)
context_->use_certificate_file(*certificate_file_,
asio::ssl::context::pem);
context_->use_certificate_file(*certificate_file_, asio::ssl::context::pem);
if (private_key_file_)
context_->use_private_key_file(*private_key_file_,
asio::ssl::context::pem);
context_->use_private_key_file(*private_key_file_, asio::ssl::context::pem);

tcp_socket_.reset(new asio::ip::tcp::socket(
service_, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), source_port)));
socket_.reset(new asio::ssl::stream<asio::ip::tcp::socket &>(
*(tcp_socket_.get()), *context_));

if (sni_hostname_)
SSL_set_tlsext_host_name(socket_->native_handle(), sni_hostname_->c_str());
if (always_verify_peer_)
socket_->set_verify_callback(asio::ssl::rfc2818_verification(host));
auto self = this->shared_from_this();
socket_->lowest_layer().async_connect(
endpoint,
[=] (std::error_code const &ec) {
self->handle_connected(ec, handler);
});
[=](std::error_code const &ec) { self->handle_connected(ec, handler); });
}

void boost::network::http::impl::ssl_delegate::handle_connected(
Expand DownExpand Up@@ -104,8 +103,8 @@ void boost::network::http::impl::ssl_delegate::read_some(
void boost::network::http::impl::ssl_delegate::disconnect() {
if (socket_.get() && socket_->lowest_layer().is_open()) {
std::error_code ignored;
socket_->lowest_layer().shutdown(
asio::ip::tcp::socket::shutdown_both, ignored);
socket_->lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both,
ignored);
if (!ignored) {
socket_->lowest_layer().close(ignored);
}
Expand Down
32 changes: 16 additions & 16 deletionsboost/network/protocol/http/client/connection/sync_base.hpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,8 +39,8 @@ struct sync_connection_base_impl {

template <class Socket>
void init_socket(Socket& socket_, resolver_type& resolver_,
string_type/*unused*/const& hostname, string_typeconst&port,
resolver_function_type resolve_) {
string_type /*unused*/const&hostname,
string_type const& port,resolver_function_type resolve_) {
using asio::ip::tcp;
std::error_code error = asio::error::host_not_found;
typename resolver_type::iterator endpoint_iterator, end;
Expand DownExpand Up@@ -100,7 +100,7 @@ struct sync_connection_base_impl {
}

template <class Socket>
void send_request_impl(Socket& socket_, string_type/*unused*/const& method,
void send_request_impl(Socket& socket_, string_type /*unused*/const& method,
asio::streambuf& request_buffer) {
// TODO(dberris): review parameter necessity.
(void)method;
Expand All@@ -118,8 +118,8 @@ struct sync_connection_base_impl {
std::error_code error;
if (response_buffer.size() > 0) body_stream << &response_buffer;

while (asio::read(socket_, response_buffer,
asio::transfer_at_least(1),error)) {
while (asio::read(socket_, response_buffer, asio::transfer_at_least(1),
error)) {
body_stream << &response_buffer;
}
}
Expand DownExpand Up@@ -171,8 +171,7 @@ struct sync_connection_base_impl {
read(socket_, response_buffer,
asio::transfer_at_least(bytes_to_read), error);
if (chunk_bytes_read == 0) {
if (error != asio::error::eof)
throw std::system_error(error);
if (error != asio::error::eof) throw std::system_error(error);
stopping_inner = true;
}
}
Expand All@@ -195,14 +194,14 @@ struct sync_connection_base_impl {
} else {
size_t already_read = response_buffer.size();
if (already_read) body_stream << &response_buffer;
size_t length = std::stoul(std::begin(content_length_range)->second) -
already_read;
if (length == 0) { return;
}
size_t length =
std::stoul(std::begin(content_length_range)->second) - already_read;
if (length == 0) {
return;
}
size_t bytes_read = 0;
while ((bytes_read = asio::read(socket_, response_buffer,
asio::transfer_at_least(1),
error))) {
asio::transfer_at_least(1), error))) {
body_stream << &response_buffer;
length -= bytes_read;
if ((length <= 0) || error) break;
Expand All@@ -223,7 +222,7 @@ struct sync_connection_base_impl {
} else {
read_body_transfer_chunk_encoding(socket_, response_, response_buffer,
body_stream);
}
}
} else {
throw std::runtime_error("Unsupported HTTP version number.");
}
Expand All@@ -249,14 +248,15 @@ struct sync_connection_base {
new_connection(
resolver_type& resolver, resolver_function_type resolve, bool https,
bool always_verify_peer, int timeout,
optional<string_type>/*unused*/const& certificate_filename =
optional<string_type> /*unused*/const& certificate_filename =
optional<string_type>(),
optional<string_type> const& verify_path = optional<string_type>(),
optional<string_type> const& certificate_file =
optional<string_type>(),
optional<string_type> const& private_key_file =
optional<string_type>(),
optional<string_type> const& ciphers = optional<string_type>(),
optional<string_type> const& sni_hostname = optional<string_type>(),
long ssl_options = 0) {
if (https) {
#ifdef BOOST_NETWORK_ENABLE_HTTPS
Expand All@@ -265,7 +265,7 @@ struct sync_connection_base {
new https_sync_connection<Tag, version_major, version_minor>(
resolver, resolve, always_verify_peer, timeout,
certificate_filename, verify_path, certificate_file,
private_key_file, ciphers, ssl_options));
private_key_file, ciphers,sni_hostname,ssl_options));
#else
throw std::runtime_error("HTTPS not supported.");
#endif
Expand Down
36 changes: 20 additions & 16 deletionsboost/network/protocol/http/client/connection/sync_ssl.hpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,20 +50,20 @@ struct https_sync_connection
https_sync_connection(
resolver_type& resolver, resolver_function_type resolve,
bool always_verify_peer, int timeout,
optional<string_type>/*unused*/const& certificate_filename =
optional<string_type> /*unused*/const& certificate_filename =
optional<string_type>(),
optional<string_type> const& verify_path = optional<string_type>(),
optional<string_type> const& certificate_file = optional<string_type>(),
optional<string_type> const& private_key_file = optional<string_type>(),
optional<string_type> const& ciphers = optional<string_type>(),
optional<string_type> const& sni_hostname = optional<string_type>(),
long ssl_options = 0)
: connection_base(),
timeout_(timeout),
timer_(resolver.get_io_service()),
resolver_(resolver),
resolve_(std::move(resolve)),
context_(resolver.get_io_service(),
asio::ssl::context::sslv23_client),
context_(resolver.get_io_service(), asio::ssl::context::sslv23_client),
socket_(resolver.get_io_service(), context_) {
if (ciphers) {
::SSL_CTX_set_cipher_list(context_.native_handle(), ciphers->c_str());
Expand All@@ -86,20 +86,21 @@ struct https_sync_connection
context_.set_verify_mode(asio::ssl::context_base::verify_none);
}
if (certificate_file)
context_.use_certificate_file(*certificate_file,
asio::ssl::context::pem);
context_.use_certificate_file(*certificate_file, asio::ssl::context::pem);
if (private_key_file)
context_.use_private_key_file(*private_key_file,
asio::ssl::context::pem);
context_.use_private_key_file(*private_key_file, asio::ssl::context::pem);
if (sni_hostname)
SSL_set_tlsext_host_name(socket_.native_handle(), sni_hostname->c_str());
}

void init_socket(string_type /*unused*/const& hostname, string_type const& port) {
void init_socket(string_type /*unused*/ const& hostname,
string_type const& port) {
connection_base::init_socket(socket_.lowest_layer(), resolver_, hostname,
port, resolve_);
socket_.handshake(asio::ssl::stream_base::client);
}

void send_request_impl(string_type/*unused*/const& method,
void send_request_impl(string_type /*unused*/const& method,
basic_request<Tag> const& request_,
body_generator_function_type generator) {
asio::streambuf request_buffer;
Expand All@@ -120,9 +121,8 @@ struct https_sync_connection
if (timeout_ > 0) {
timer_.expires_from_now(boost::posix_time::seconds(timeout_));
auto self = this->shared_from_this();
timer_.async_wait([=] (std::error_code const &ec) {
self->handle_timeout(ec);
});
timer_.async_wait(
[=](std::error_code const& ec) { self->handle_timeout(ec); });
}
}

Expand All@@ -141,7 +141,8 @@ struct https_sync_connection
connection_base::read_body(socket_, response_, response_buffer);
typename headers_range<basic_response<Tag> >::type connection_range =
headers(response_)["Connection"];
if (version_major == 1 && version_minor == 1 && !boost::empty(connection_range) &&
if (version_major == 1 && version_minor == 1 &&
!boost::empty(connection_range) &&
boost::iequals(std::begin(connection_range)->second, "close")) {
close_socket();
} else if (version_major == 1 && version_minor == 0) {
Expand All@@ -156,16 +157,19 @@ struct https_sync_connection
std::error_code ignored;
socket_.lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both,
ignored);
if (ignored) { return; }
if (ignored) {
return;
}
socket_.lowest_layer().close(ignored);
}

~https_sync_connection() { close_socket(); }

private:
void handle_timeout(std::error_code const& ec) {
if (!ec) { close_socket();
}
if (!ec) {
close_socket();
}
}

int timeout_;
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp