1 /*
2 * nghttp2 - HTTP/2 C Library
3 *
4 * Copyright (c) 2015 Tatsuhiro Tsujikawa
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25 #include "asio_client_session_tls_impl.h"
26 #include "asio_common.h"
27
28 namespace nghttp2 {
29 namespace asio_http2 {
30 namespace client {
31
session_tls_impl(boost::asio::io_service & io_service,boost::asio::ssl::context & tls_ctx,const std::string & host,const std::string & service,const boost::posix_time::time_duration & connect_timeout)32 session_tls_impl::session_tls_impl(
33 boost::asio::io_service &io_service, boost::asio::ssl::context &tls_ctx,
34 const std::string &host, const std::string &service,
35 const boost::posix_time::time_duration &connect_timeout)
36 : session_impl(io_service, connect_timeout), socket_(io_service, tls_ctx) {
37 // this callback setting is no effect is
38 // ssl::context::set_verify_mode(boost::asio::ssl::verify_peer) is
39 // not used, which is what we want.
40 socket_.set_verify_callback(boost::asio::ssl::rfc2818_verification(host));
41 auto ssl = socket_.native_handle();
42 if (!util::numeric_host(host.c_str())) {
43 SSL_set_tlsext_host_name(ssl, host.c_str());
44 }
45 }
46
~session_tls_impl()47 session_tls_impl::~session_tls_impl() {}
48
start_connect(tcp::resolver::iterator endpoint_it)49 void session_tls_impl::start_connect(tcp::resolver::iterator endpoint_it) {
50 auto self = std::static_pointer_cast<session_tls_impl>(shared_from_this());
51 boost::asio::async_connect(
52 socket(), endpoint_it,
53 [self](const boost::system::error_code &ec,
54 tcp::resolver::iterator endpoint_it) {
55 if (self->stopped()) {
56 return;
57 }
58
59 if (ec) {
60 self->not_connected(ec);
61 return;
62 }
63
64 self->socket_.async_handshake(
65 boost::asio::ssl::stream_base::client,
66 [self, endpoint_it](const boost::system::error_code &ec) {
67 if (self->stopped()) {
68 return;
69 }
70
71 if (ec) {
72 self->not_connected(ec);
73 return;
74 }
75
76 if (!tls_h2_negotiated(self->socket_)) {
77 self->not_connected(make_error_code(
78 NGHTTP2_ASIO_ERR_TLS_NO_APP_PROTO_NEGOTIATED));
79 return;
80 }
81
82 self->connected(endpoint_it);
83 });
84 });
85 }
86
socket()87 tcp::socket &session_tls_impl::socket() { return socket_.next_layer(); }
88
read_socket(std::function<void (const boost::system::error_code & ec,std::size_t n)> h)89 void session_tls_impl::read_socket(
90 std::function<void(const boost::system::error_code &ec, std::size_t n)> h) {
91 socket_.async_read_some(boost::asio::buffer(rb_), h);
92 }
93
write_socket(std::function<void (const boost::system::error_code & ec,std::size_t n)> h)94 void session_tls_impl::write_socket(
95 std::function<void(const boost::system::error_code &ec, std::size_t n)> h) {
96 boost::asio::async_write(socket_, boost::asio::buffer(wb_, wblen_), h);
97 }
98
shutdown_socket()99 void session_tls_impl::shutdown_socket() {
100 boost::system::error_code ignored_ec;
101 socket_.lowest_layer().close(ignored_ec);
102 }
103
104 } // namespace client
105 } // namespace asio_http2
106 } // namespace nghttp2
107