RDFS
The Rice Comp413 2017 class' continuation on the work of the 2016 RDFS.
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
server_https.h
1 #ifndef SERVER_HTTPS_HPP
2 #define SERVER_HTTPS_HPP
3 
4 #include "server_http.h"
5 
6 #ifdef USE_STANDALONE_ASIO
7 #include <asio/ssl.hpp>
8 #else
9 #include <boost/asio/ssl.hpp>
10 #endif
11 
12 #include <algorithm>
13 #include <openssl/ssl.h>
14 
15 namespace SimpleWeb {
16  using HTTPS = asio::ssl::stream<asio::ip::tcp::socket>;
17 
18  template <>
19  class Server<HTTPS> : public ServerBase<HTTPS> {
20  std::string session_id_context;
21  bool set_session_id_context = false;
22 
23  public:
24  Server(const std::string &cert_file, const std::string &private_key_file, const std::string &verify_file = std::string())
25  : ServerBase<HTTPS>::ServerBase(443), context(asio::ssl::context::tlsv12) {
26  context.use_certificate_chain_file(cert_file);
27  context.use_private_key_file(private_key_file, asio::ssl::context::pem);
28 
29  if(verify_file.size() > 0) {
30  context.load_verify_file(verify_file);
31  context.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert | asio::ssl::verify_client_once);
32  set_session_id_context = true;
33  }
34  }
35 
36  void start() override {
37  if(set_session_id_context) {
38  // Creating session_id_context from address:port but reversed due to small SSL_MAX_SSL_SESSION_ID_LENGTH
39  session_id_context = std::to_string(config.port) + ':';
40  session_id_context.append(config.address.rbegin(), config.address.rend());
41  SSL_CTX_set_session_id_context(context.native_handle(), reinterpret_cast<const unsigned char *>(session_id_context.data()),
42  std::min<std::size_t>(session_id_context.size(), SSL_MAX_SSL_SESSION_ID_LENGTH));
43  }
44  ServerBase::start();
45  }
46 
47  protected:
48  asio::ssl::context context;
49 
50  void accept() override {
51  auto connection = create_connection(*io_service, context);
52 
53  acceptor->async_accept(connection->socket->lowest_layer(), [this, connection](const error_code &ec) {
54  auto lock = connection->handler_runner->continue_lock();
55  if(!lock)
56  return;
57 
58  if(ec != asio::error::operation_aborted)
59  this->accept();
60 
61  auto session = std::make_shared<Session>(config.max_request_streambuf_size, connection);
62 
63  if(!ec) {
64  asio::ip::tcp::no_delay option(true);
65  error_code ec;
66  session->connection->socket->lowest_layer().set_option(option, ec);
67 
68  session->connection->set_timeout(config.timeout_request);
69  session->connection->socket->async_handshake(asio::ssl::stream_base::server, [this, session](const error_code &ec) {
70  session->connection->cancel_timeout();
71  auto lock = session->connection->handler_runner->continue_lock();
72  if(!lock)
73  return;
74  if(!ec)
75  this->read_request_and_content(session);
76  else if(this->on_error)
77  this->on_error(session->request, ec);
78  });
79  }
80  else if(this->on_error)
81  this->on_error(session->request, ec);
82  });
83  }
84  };
85 } // namespace SimpleWeb
86 
87 #endif /* SERVER_HTTPS_HPP */
std::size_t max_request_streambuf_size
Definition: server_http.h:296
std::string address
Definition: server_http.h:299
Definition: server_http.h:48
long timeout_request
Timeout on request handling. Defaults to 5 seconds.
Definition: server_http.h:291
Definition: server_http.h:51
std::shared_ptr< asio::io_service > io_service
If you have your own asio::io_service, store its pointer here before running start().
Definition: server_http.h:329
unsigned short port
Port number to use. Defaults to 80 for HTTP and 443 for HTTPS.
Definition: server_http.h:286
Config config
Set before calling start().
Definition: server_http.h:304