From 40a42dd6378d3f0ee404c20455b5e655cb226443 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Sun, 13 Nov 2011 20:46:54 -0600 Subject: [PATCH] misc fixes --- src/hybi_legacy_processor.hpp | 24 +++++++++++- src/hybi_processor.hpp | 24 +++++++++++- src/interfaces/session.hpp | 17 ++++++++- src/network_utilities.cpp | 18 ++++++++- src/network_utilities.hpp | 1 + src/websocket_constants.hpp | 7 ++++ src/websocket_server.hpp | 69 ++++++++++++++++------------------- 7 files changed, 115 insertions(+), 45 deletions(-) diff --git a/src/hybi_legacy_processor.hpp b/src/hybi_legacy_processor.hpp index e3adc73293..f6832e9570 100644 --- a/src/hybi_legacy_processor.hpp +++ b/src/hybi_legacy_processor.hpp @@ -87,7 +87,7 @@ public: if (response.header("Sec-WebSocket-Location") == "") { // TODO: extract from host header rather than hard code ws_uri uri = get_uri(request); - response.add_header("Sec-WebSocket-Location",uri.base()); + response.add_header("Sec-WebSocket-Location",uri.str()); } } @@ -99,10 +99,30 @@ public: ws_uri uri; uri.secure = m_secure; + + + std::string h = request.header("Host"); + + size_t found = h.find(":"); + if (found == std::string::npos) { + uri.host = h; + uri.port = (m_secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT); + } else { + uint16_t p = atoi(h.substr(found+1).c_str()); + + if (p == 0) { + throw(http::exception("Could not determine request uri. Check host header.",http::status_code::BAD_REQUEST)); + } else { + uri.host = h.substr(0,found); + uri.port = p; + } + } + // TODO: check if get_uri is a full uri - // TODO: host and port uri.resource = request.uri(); + std::cout << "parsed uri: " << uri.str() << std::endl; + return uri; } diff --git a/src/hybi_processor.hpp b/src/hybi_processor.hpp index 2a61c5fb04..30df3bee48 100644 --- a/src/hybi_processor.hpp +++ b/src/hybi_processor.hpp @@ -124,7 +124,7 @@ public: } else if (version == 7 || version == 8) { return request.header("Sec-WebSocket-Origin"); } else { - throw(http::exception("Could not determine origin header.",http::status_code::BAD_REQUEST)); + throw(http::exception("Could not determine origin header. Check Sec-WebSocket-Version header",http::status_code::BAD_REQUEST)); } } @@ -132,10 +132,30 @@ public: ws_uri uri; uri.secure = m_secure; + + + std::string h = request.header("Host"); + + size_t found = h.find(":"); + if (found == std::string::npos) { + uri.host = h; + uri.port = (m_secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT); + } else { + uint16_t p = atoi(h.substr(found+1).c_str()); + + if (p == 0) { + throw(http::exception("Could not determine request uri. Check host header.",http::status_code::BAD_REQUEST)); + } else { + uri.host = h.substr(0,found); + uri.port = p; + } + } + // TODO: check if get_uri is a full uri - // TODO: host and port uri.resource = request.uri(); + std::cout << "parsed uri: " << uri.str() << std::endl; + return uri; } diff --git a/src/interfaces/session.hpp b/src/interfaces/session.hpp index b6d931707b..e150bbeb14 100644 --- a/src/interfaces/session.hpp +++ b/src/interfaces/session.hpp @@ -78,6 +78,17 @@ public: error::value m_code; }; +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Server API * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* +server(uint16_t port, server_handler_ptr handler) +void run(); + + +*/ + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Server Session API * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -114,6 +125,8 @@ public: virtual void ping(const binary_string& payload) = 0; virtual void pong(const binary_string& payload) = 0; + virtual uint64_t buffered_amount() const = 0; + // Valid for CLOSED state virtual close::status::value get_local_close_code() const = 0; virtual utf8_string get_local_close_reason() const = 0; @@ -212,8 +225,10 @@ public: virtual int get_version() const = 0; virtual std::string get_origin() const = 0; - virtual const ws_uri& get_uri() const = 0; virtual bool get_secure() const = 0; + virtual std::string get_host() const = 0; + virtual std::string get_resource() const = 0; + virtual uint16_t get_port() const = 0; // Valid for CONNECTING state virtual void set_origin(const std::string& origin) = 0; diff --git a/src/network_utilities.cpp b/src/network_utilities.cpp index 571ef1a1ab..05aafec63b 100644 --- a/src/network_utilities.cpp +++ b/src/network_utilities.cpp @@ -26,6 +26,7 @@ */ #include "network_utilities.hpp" +#include "websocket_constants.hpp" #include #include "md5/md5.h" @@ -153,7 +154,7 @@ bool websocketpp::ws_uri::parse(const std::string& uri) { host = what[2]; if (what[3] == "") { - port = (secure ? 443 : 80); + port = (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT); } else { unsigned int t_port = atoi(std::string(what[3]).substr(1).c_str()); @@ -182,7 +183,7 @@ std::string websocketpp::ws_uri::base() { s << "ws" << (secure ? "s" : "") << "://" << host; - if (port != (secure ? 443 : 80)) { + if (port != (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT)) { s << ":" << port; } @@ -190,6 +191,19 @@ std::string websocketpp::ws_uri::base() { return s.str(); } +std::string websocketpp::ws_uri::str() { + std::stringstream s; + + s << "ws" << (secure ? "s" : "") << "://" << host; + + if (port != (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT)) { + s << ":" << port; + } + + s << resource; + return s.str(); +} + void md5_hash_string(char *string,char *hash) { md5_state_t state; diff --git a/src/network_utilities.hpp b/src/network_utilities.hpp index 6404726e17..f79390af1f 100644 --- a/src/network_utilities.hpp +++ b/src/network_utilities.hpp @@ -52,6 +52,7 @@ namespace websocketpp { struct ws_uri { bool parse(const std::string& uri); std::string base(); + std::string str(); bool secure; std::string host; diff --git a/src/websocket_constants.hpp b/src/websocket_constants.hpp index 4dc05cc73f..0084f550a0 100644 --- a/src/websocket_constants.hpp +++ b/src/websocket_constants.hpp @@ -47,6 +47,13 @@ namespace websocketpp { const uint64_t DEFAULT_MAX_MESSAGE_SIZE = 0xFFFFFF; // ~16MB + const uint16_t DEFAULT_PORT = 80; + const uint16_t DEFAULT_SECURE_PORT = 443; + + inline uint16_t default_port(bool secure) { + return (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT); + } + // System logging levels static const uint16_t LOG_ALL = 0; static const uint16_t LOG_DEBUG = 1; diff --git a/src/websocket_server.hpp b/src/websocket_server.hpp index 94173424e7..01d3134537 100644 --- a/src/websocket_server.hpp +++ b/src/websocket_server.hpp @@ -48,13 +48,9 @@ namespace po = boost::program_options; #include "hybi_legacy_processor.hpp" #include "hybi_processor.hpp" -//#include "websocket_session.hpp" #include "websocket_connection_handler.hpp" -//#include - #include "rng/blank_rng.hpp" - #include "http/parser.hpp" #include "logger/logger.hpp" @@ -211,6 +207,11 @@ public: m_io_service.post(boost::bind(&connection_type::write_message,connection_type::shared_from_this(),msg)); } + uint64_t buffered_amount() const { + // TODO: syncronize this member function + return m_write_buffer; + } + // Valid for CLOSED state close::status::value get_local_close_code() const { return m_local_close_code; @@ -681,9 +682,7 @@ public: // clear the queue except for the last message while (m_write_queue.size() > 1) { m_write_buffer -= m_write_queue.front()->size(); - std::cout << "int size before: " << m_write_queue.size() << std::endl; m_write_queue.pop(); - std::cout << "int size after: " << m_write_queue.size() << std::endl; } break; default: @@ -695,9 +694,7 @@ public: if (m_write_state == write_state::IDLE) { m_write_state = write_state::WRITING; } - - std::cout << "starting async write " << std::endl; - + boost::asio::async_write( m_socket, boost::asio::buffer(*m_write_queue.front()), @@ -733,10 +730,8 @@ public: return; } - std::cout << "size before: " << m_write_queue.size() << std::endl; m_write_buffer -= m_write_queue.front()->size(); m_write_queue.pop(); - std::cout << "size after: " << m_write_queue.size() << std::endl; if (m_write_state == write_state::WRITING) { m_write_state = write_state::IDLE; @@ -829,8 +824,6 @@ public: } private: - - server_ptr m_server; boost::asio::io_service& m_io_service; @@ -859,7 +852,7 @@ private: // Write queue std::queue m_write_queue; - size_t m_write_buffer; + uint64_t m_write_buffer; write_state::value m_write_state; // Close state @@ -904,30 +897,7 @@ public: m_io_service.run(); } - // creates a new session object and connects the next websocket - // connection to it. - void start_accept() { - // TODO: sanity check whether the session buffer size bound could be reduced - connection_ptr new_session( - new connection_type( - endpoint_type::shared_from_this(), - m_io_service, - m_handler - ) - ); - - m_acceptor.async_accept( - new_session->get_socket(), - boost::bind( - &endpoint_type::handle_accept, - endpoint_type::shared_from_this(), - new_session, - boost::asio::placeholders::error - ) - ); - - - } + // INTERFACE FOR LOCAL APPLICATIONS void set_max_message_size(uint64_t val) { @@ -1007,6 +977,29 @@ public: } private: + // creates a new session object and connects the next websocket + // connection to it. + void start_accept() { + // TODO: sanity check whether the session buffer size bound could be reduced + connection_ptr new_session( + new connection_type( + endpoint_type::shared_from_this(), + m_io_service, + m_handler + ) + ); + + m_acceptor.async_accept( + new_session->get_socket(), + boost::bind( + &endpoint_type::handle_accept, + endpoint_type::shared_from_this(), + new_session, + boost::asio::placeholders::error + ) + ); + } + // if no errors starts the session's read loop and returns to the // start_accept phase. void handle_accept(connection_ptr connection,const boost::system::error_code& error)