pion
5.0.6
|
00001 // --------------------------------------------------------------------- 00002 // pion: a Boost C++ framework for building lightweight HTTP interfaces 00003 // --------------------------------------------------------------------- 00004 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) 00005 // 00006 // Distributed under the Boost Software License, Version 1.0. 00007 // See http://www.boost.org/LICENSE_1_0.txt 00008 // 00009 00010 #ifndef __PION_TCP_SERVER_HEADER__ 00011 #define __PION_TCP_SERVER_HEADER__ 00012 00013 #include <set> 00014 #include <boost/asio.hpp> 00015 #include <boost/noncopyable.hpp> 00016 #include <boost/shared_ptr.hpp> 00017 #include <boost/thread/mutex.hpp> 00018 #include <boost/thread/condition.hpp> 00019 #include <pion/config.hpp> 00020 #include <pion/logger.hpp> 00021 #include <pion/scheduler.hpp> 00022 #include <pion/tcp/connection.hpp> 00023 00024 00025 namespace pion { // begin namespace pion 00026 namespace tcp { // begin namespace tcp 00027 00028 00032 class PION_API server : 00033 private boost::noncopyable 00034 { 00035 public: 00036 00038 virtual ~server() { if (m_is_listening) stop(false); } 00039 00041 void start(void); 00042 00048 void stop(bool wait_until_finished = false); 00049 00051 void join(void); 00052 00058 void set_ssl_key_file(const std::string& pem_key_file); 00059 00061 std::size_t get_connections(void) const; 00062 00064 inline unsigned int get_port(void) const { return m_endpoint.port(); } 00065 00067 inline void set_port(unsigned int p) { m_endpoint.port(p); } 00068 00070 inline boost::asio::ip::address get_address(void) const { return m_endpoint.address(); } 00071 00073 inline void set_address(const boost::asio::ip::address& addr) { m_endpoint.address(addr); } 00074 00076 inline const boost::asio::ip::tcp::endpoint& get_endpoint(void) const { return m_endpoint; } 00077 00079 inline void set_endpoint(const boost::asio::ip::tcp::endpoint& ep) { m_endpoint = ep; } 00080 00082 inline bool get_ssl_flag(void) const { return m_ssl_flag; } 00083 00085 inline void set_ssl_flag(bool b = true) { m_ssl_flag = b; } 00086 00088 inline connection::ssl_context_type& get_ssl_context_type(void) { return m_ssl_context; } 00089 00091 inline bool is_listening(void) const { return m_is_listening; } 00092 00094 inline void set_logger(logger log_ptr) { m_logger = log_ptr; } 00095 00097 inline logger get_logger(void) { return m_logger; } 00098 00100 inline boost::asio::ip::tcp::acceptor& get_acceptor(void) { return m_tcp_acceptor; } 00101 00103 inline const boost::asio::ip::tcp::acceptor& get_acceptor(void) const { return m_tcp_acceptor; } 00104 00105 00106 protected: 00107 00113 explicit server(const unsigned int tcp_port); 00114 00120 explicit server(const boost::asio::ip::tcp::endpoint& endpoint); 00121 00128 explicit server(scheduler& sched, const unsigned int tcp_port = 0); 00129 00136 server(scheduler& sched, const boost::asio::ip::tcp::endpoint& endpoint); 00137 00144 virtual void handle_connection(tcp::connection_ptr& tcp_conn) { 00145 tcp_conn->set_lifecycle(connection::LIFECYCLE_CLOSE); // make sure it will get closed 00146 tcp_conn->finish(); 00147 } 00148 00150 virtual void before_starting(void) {} 00151 00153 virtual void after_stopping(void) {} 00154 00156 inline boost::asio::io_service& get_io_service(void) { return m_active_scheduler.get_io_service(); } 00157 00158 00160 logger m_logger; 00161 00162 00163 private: 00164 00166 void handle_stop_request(void); 00167 00169 void listen(void); 00170 00177 void handle_accept(tcp::connection_ptr& tcp_conn, 00178 const boost::system::error_code& accept_error); 00179 00186 void handle_ssl_handshake(tcp::connection_ptr& tcp_conn, 00187 const boost::system::error_code& handshake_error); 00188 00193 void finish_connection(tcp::connection_ptr& tcp_conn); 00194 00197 std::size_t prune_connections(void); 00198 00199 00201 typedef std::set<tcp::connection_ptr> ConnectionPool; 00202 00203 00205 single_service_scheduler m_default_scheduler; 00206 00208 scheduler & m_active_scheduler; 00209 00211 boost::asio::ip::tcp::acceptor m_tcp_acceptor; 00212 00214 connection::ssl_context_type m_ssl_context; 00215 00217 boost::condition m_server_has_stopped; 00218 00220 boost::condition m_no_more_connections; 00221 00223 ConnectionPool m_conn_pool; 00224 00226 boost::asio::ip::tcp::endpoint m_endpoint; 00227 00229 bool m_ssl_flag; 00230 00232 bool m_is_listening; 00233 00235 mutable boost::mutex m_mutex; 00236 }; 00237 00238 00240 typedef boost::shared_ptr<server> server_ptr; 00241 00242 00243 } // end namespace tcp 00244 } // end namespace pion 00245 00246 #endif