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