diff --git a/examples/echo_server/echo_server b/examples/echo_server/echo_server index 19507a8e07..3abbfec5f5 100755 Binary files a/examples/echo_server/echo_server and b/examples/echo_server/echo_server differ diff --git a/examples/echo_server/echo_server.cpp b/examples/echo_server/echo_server.cpp index f8200463e6..b67116641c 100644 --- a/examples/echo_server/echo_server.cpp +++ b/examples/echo_server/echo_server.cpp @@ -29,9 +29,11 @@ int main(int argc, char* argv[]) { tcp::endpoint endpoint(tcp::v6(), port); websocketpp::server_ptr server( - new websocketpp::server(io_service,endpoint,host,echo_handler) + new websocketpp::server(io_service,endpoint,echo_handler) ); + server->add_host(host); + std::cout << "Starting echo server on " << host << std::endl; io_service.run(); diff --git a/readme.txt b/readme.txt index 98e630f40d..dbc4fdf03b 100644 --- a/readme.txt +++ b/readme.txt @@ -66,8 +66,9 @@ Avaliable flags: - CXX=*: uses * as the c++ compiler instead of system default Build tested on -- Mac OS X 10.7 with apple gcc 4.2, macports gcc 4.6, apple llvm/clang - +- Mac OS X 10.7 with apple gcc 4.2, macports gcc 4.6, apple llvm/clang, boost 1.47 +- Fedora 15, gcc 4.6, boost 1.46 +- Ubunutu server, gcc, boost 1.42 diff --git a/src/websocket_server.cpp b/src/websocket_server.cpp index d97ad4957d..997c4618db 100644 --- a/src/websocket_server.cpp +++ b/src/websocket_server.cpp @@ -35,18 +35,24 @@ using websocketpp::server; server::server(boost::asio::io_service& io_service, const tcp::endpoint& endpoint, - const std::string& host, connection_handler_ptr defc) - : m_host(host), - m_io_service(io_service), + : m_io_service(io_service), m_acceptor(io_service, endpoint), m_def_con_handler(defc) { this->start_accept(); } +void server::add_host(std::string host) { + m_hosts.insert(host); +} + +void server::remove_host(std::string host) { + m_hosts.erase(host); +} + void server::start_accept() { - session_ptr new_ws(new session(m_io_service,m_host,m_def_con_handler)); - + session_ptr new_ws(new session(m_io_service,m_def_con_handler)); + m_acceptor.async_accept( new_ws->socket(), boost::bind( @@ -62,6 +68,12 @@ void server::handle_accept(session_ptr session, const boost::system::error_code& error) { if (!error) { + // set up session + std::set::iterator it; + for (it = m_hosts.begin(); it != m_hosts.end(); it++) { + session->add_host(*it); + } + session->start(); } else { std::cout << "Error" << std::endl; diff --git a/src/websocket_server.hpp b/src/websocket_server.hpp index 6377272ca2..4b71fcdbff 100644 --- a/src/websocket_server.hpp +++ b/src/websocket_server.hpp @@ -33,6 +33,8 @@ #include #include +#include + using boost::asio::ip::tcp; namespace websocketpp { @@ -41,9 +43,14 @@ class server { public: server(boost::asio::io_service& io_service, const tcp::endpoint& endpoint, - const std::string& host, connection_handler_ptr defc); + // Add or remove a host string (host:port) to the list of acceptable + // hosts to accept websocket connections from. Additions/deletions here + // only affect new connections. + void add_host(std::string host); + void remove_host(std::string host); + private: // creates a new session object and connects the next websocket // connection to it. void start_accept(); @@ -54,8 +61,7 @@ class server { const boost::system::error_code& error); private: - - std::string m_host; + std::set m_hosts; boost::asio::io_service& m_io_service; tcp::acceptor m_acceptor; connection_handler_ptr m_def_con_handler; diff --git a/src/websocket_session.cpp b/src/websocket_session.cpp index 6df3bc3431..e16c183e9a 100644 --- a/src/websocket_session.cpp +++ b/src/websocket_session.cpp @@ -39,6 +39,13 @@ using websocketpp::session; +session::session (boost::asio::io_service& io_service, + connection_handler_ptr defc) + : m_socket(io_service), + m_status(CONNECTING), + m_http_error_code(0), + m_local_interface(defc) {} + tcp::socket& session::socket() { return m_socket; } @@ -68,6 +75,13 @@ void session::set_handler(connection_handler_ptr new_con) { m_local_interface->connect(shared_from_this()); } +void session::add_host(std::string host) { + m_hosts.insert(host); +} + +void session::remove_host(std::string host) { + m_hosts.erase(host); +} std::string session::get_header(const std::string& key) const { std::map::const_iterator h = m_headers.find(key); @@ -255,9 +269,10 @@ void session::handle_read_handshake(const boost::system::error_code& e, // TODO: use exceptions or a helper function or something better here - // verify the presence of required headers - if (get_header("Host") != m_host) { - std::cerr << "Invalid or missing Host header. " << get_header("Host") << "!=" << m_host << std::endl; + // verify the presence of required headers + if (m_hosts.find(get_header("Host")) == m_hosts.end()) { + std::cerr << "Invalid or missing Host header: " + << get_header("Host") << std::endl; this->set_http_error(400); } if (!boost::iequals(get_header("Upgrade"),"websocket")) { diff --git a/src/websocket_session.hpp b/src/websocket_session.hpp index b6ba70481d..79b871b6c7 100644 --- a/src/websocket_session.hpp +++ b/src/websocket_session.hpp @@ -28,13 +28,6 @@ #ifndef WEBSOCKET_SESSION_HPP #define WEBSOCKET_SESSION_HPP -#include -#include -#include -#include -#include -#include - #include #include @@ -43,6 +36,14 @@ #include +#include +#include +#include +#include +#include +#include +#include + namespace websocketpp { class session; typedef boost::shared_ptr session_ptr; @@ -69,17 +70,12 @@ public: typedef enum ws_status status_code; - session (boost::asio::io_service& io_service, - const std::string& host, - connection_handler_ptr defc) - : m_host(host), - m_socket(io_service), - m_status(CONNECTING), - m_http_error_code(0), - m_local_interface(defc) {} + session (boost::asio::io_service& io_service, connection_handler_ptr defc); tcp::socket& socket(); + /*** SERVER INTERFACE ***/ + // This function is called to begin the session loop. This method and all // that come after it are called as a result of an async event completing. // if any method in this chain returns before adding a new async event the @@ -94,7 +90,14 @@ public: void set_handler(connection_handler_ptr new_con); - // Public handshake interface + /*** HANDSHAKE INTERFACE ***/ + + // Add or remove a host string (host:port) to the list of acceptable + // hosts to accept websocket connections from. Additions/deletions here + // only affect only this connection. This list is initially populated based + // on values stored in the server. + void add_host(std::string host); + void remove_host(std::string host); // By default a failed handshake validation will return an HTTP 400 Bad // Request error. If your application wants to reject the connection for @@ -120,7 +123,7 @@ public: //void add_extension(); - // Public session interface + /*** SESSION INTERFACE ***/ // send basic frame types void send(const std::string &msg); // text @@ -196,6 +199,7 @@ private: std::string lookup_http_error_string(int code); private: + std::set m_hosts; std::string m_host; tcp::socket m_socket; status_code m_status;