Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : 6 : #include "http/http_server.h" 7 : 8 : #include "http/http_session.h" 9 : #include "io/event_manager.h" 10 : 11 : using namespace std; 12 : 13 90 : HttpServer::HttpServer(EventManager *evm, const SslConfig &config, uint8_t dscp) 14 : : SslServer(evm, boost::asio::ssl::context::tlsv12_server, 15 90 : config.ssl_enabled, false), dscp_value_(dscp) { 16 : //ctor 17 90 : if (config.ssl_enabled) { 18 : 19 : // Get SSL context from base class and update 20 2 : boost::asio::ssl::context *ctx = context(); 21 2 : boost::system::error_code ec; 22 : 23 : // set mode 24 2 : ctx->set_options(boost::asio::ssl::context::default_workarounds | 25 : boost::asio::ssl::context::no_sslv3 | 26 : boost::asio::ssl::context::no_sslv2 | 27 : boost::asio::ssl::context::no_tlsv1 | 28 : boost::asio::ssl::context::no_tlsv1_1, ec); 29 2 : if (ec.value() != 0) { 30 0 : exit(EINVAL); 31 : } 32 : 33 : // CA certificate, used to verify if the peer certificate 34 : // is signed by a trusted CA 35 2 : std::string ca_cert_filename = config.ca_cert; 36 2 : bool insecure = config.ssl_insecure; 37 2 : if (!ca_cert_filename.empty() && !insecure) { 38 : 39 : // Verify peer has CA signed certificate 40 1 : ctx->set_verify_mode(boost::asio::ssl::verify_peer | 41 : boost::asio::ssl::verify_fail_if_no_peer_cert, ec); 42 1 : if (ec.value() != 0) { 43 0 : exit(EINVAL); 44 : } 45 : 46 1 : ctx->load_verify_file(ca_cert_filename, ec); 47 1 : if (ec.value() != 0) { 48 0 : exit(EINVAL); 49 : } 50 : } 51 : 52 : // server certificate 53 2 : ctx->use_certificate_file(config.certfile, 54 : boost::asio::ssl::context::pem, ec); 55 2 : if (ec.value() != 0) { 56 0 : exit(EINVAL); 57 : } 58 : 59 : // server private key 60 2 : ctx->use_private_key_file(config.keyfile, 61 : boost::asio::ssl::context::pem, ec); 62 2 : if (ec.value() != 0) { 63 0 : exit(EINVAL); 64 : } 65 2 : } 66 90 : } 67 : 68 174 : HttpServer::~HttpServer() { 69 : //dtor 70 174 : } 71 : 72 90 : void HttpServer::Shutdown() { 73 90 : http_handlers_.clear(); 74 90 : TcpServer::Shutdown(); 75 90 : } 76 : 77 10 : SslSession *HttpServer::AllocSession(SslSocket *socket) { 78 10 : SslSession *session = new HttpSession(this, socket); 79 10 : boost::system::error_code err; 80 10 : HttpSession *https = static_cast<HttpSession *>(session); 81 10 : https->SetSocketOptions(); 82 10 : return session; 83 : } 84 : 85 10 : bool HttpServer::AcceptSession(TcpSession *session) { 86 10 : HttpSession *h_session = dynamic_cast<HttpSession *>(session); 87 10 : if (dscp_value_) { 88 0 : h_session->SetDscpSocketOption(dscp_value_); 89 : } 90 10 : h_session->AcceptSession(); 91 10 : return true; 92 : } 93 : 94 0 : bool HttpServer::AcceptSession(SslSession *session) { 95 0 : HttpSession *h_session = dynamic_cast<HttpSession *>(session); 96 0 : if (dscp_value_) { 97 0 : h_session->SetDscpSocketOption(dscp_value_); 98 : } 99 0 : h_session->AcceptSession(); 100 0 : return true; 101 : } 102 : 103 7786 : void HttpServer::RegisterHandler(const string &path, HttpHandlerFn handler) { 104 7786 : http_handlers_.insert(make_pair(path, handler)); 105 7786 : } 106 : 107 10 : HttpServer::HttpHandlerFn HttpServer::GetHandler(const string &path) { 108 10 : HandlerTrie::iterator iter = http_handlers_.find(path); 109 10 : if (iter == http_handlers_.end()) { 110 : // check if wildcard entry is present 111 0 : iter = http_handlers_.find(HTTP_WILDCARD_ENTRY); 112 0 : if (iter == http_handlers_.end()) { 113 0 : return NULL; 114 : } 115 : } 116 10 : return iter->second; 117 : } 118 : 119 0 : void HttpServer::UpdateDscp(uint8_t value) { 120 0 : if (value == dscp_value_) 121 0 : return; 122 0 : dscp_value_ = value; 123 0 : SetListenSocketDscp(value); 124 : }