Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / third_party / Simple-web-server / repo / server_https.hpp
1 #ifndef SERVER_HTTPS_HPP
2 #define SERVER_HTTPS_HPP
3
4 #include "server_http.hpp"
5 #include <boost/asio/ssl.hpp>
6 #include <openssl/ssl.h>
7 #include <algorithm>
8
9 namespace SimpleWeb {
10     typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> HTTPS;    
11     
12     template<>
13     class Server<HTTPS> : public ServerBase<HTTPS> {
14         std::string session_id_context;
15         bool set_session_id_context=false;
16     public:
17         DEPRECATED Server(unsigned short port, size_t thread_pool_size, const std::string& cert_file, const std::string& private_key_file,
18                 long timeout_request=5, long timeout_content=300,
19                 const std::string& verify_file=std::string()) : 
20                 Server(cert_file, private_key_file, verify_file) {
21             config.port=port;
22             config.thread_pool_size=thread_pool_size;
23             config.timeout_request=timeout_request;
24             config.timeout_content=timeout_content;
25         }
26         
27         Server(const std::string& cert_file, const std::string& private_key_file, const std::string& verify_file=std::string()):
28                 ServerBase<HTTPS>::ServerBase(443), context(boost::asio::ssl::context::tlsv12) {
29             context.use_certificate_chain_file(cert_file);
30             context.use_private_key_file(private_key_file, boost::asio::ssl::context::pem);
31             
32             if(verify_file.size()>0) {
33                 context.load_verify_file(verify_file);
34                 context.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert |
35                                         boost::asio::ssl::verify_client_once);
36                 set_session_id_context=true;
37             }
38         }
39         
40         void start() {
41             if(set_session_id_context) {
42                 // Creating session_id_context from address:port but reversed due to small SSL_MAX_SSL_SESSION_ID_LENGTH
43                 session_id_context=std::to_string(config.port)+':';
44                 session_id_context.append(config.address.rbegin(), config.address.rend());
45                 SSL_CTX_set_session_id_context(context.native_handle(), reinterpret_cast<const unsigned char*>(session_id_context.data()),
46                                                std::min<size_t>(session_id_context.size(), SSL_MAX_SSL_SESSION_ID_LENGTH));
47             }
48             ServerBase::start();
49         }
50
51     protected:
52         boost::asio::ssl::context context;
53         
54         void accept() {
55             //Create new socket for this connection
56             //Shared_ptr is used to pass temporary objects to the asynchronous functions
57             auto socket=std::make_shared<HTTPS>(*io_service, context);
58
59             acceptor->async_accept((*socket).lowest_layer(), [this, socket](const boost::system::error_code& ec) {
60                 //Immediately start accepting a new connection (if io_service hasn't been stopped)
61                 if (ec != boost::asio::error::operation_aborted)
62                     accept();
63
64                 
65                 if(!ec) {
66                     boost::asio::ip::tcp::no_delay option(true);
67                     socket->lowest_layer().set_option(option);
68                     
69                     //Set timeout on the following boost::asio::ssl::stream::async_handshake
70                     auto timer=get_timeout_timer(socket, config.timeout_request);
71                     socket->async_handshake(boost::asio::ssl::stream_base::server, [this, socket, timer]
72                             (const boost::system::error_code& ec) {
73                         if(timer)
74                             timer->cancel();
75                         if(!ec)
76                             read_request_and_content(socket);
77                         else if(on_error)
78                             on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
79                     });
80                 }
81                 else if(on_error)
82                     on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
83             });
84         }
85     };
86 }
87
88
89 #endif  /* SERVER_HTTPS_HPP */
90