Files
rippled/src/interfaces/session.hpp
Peter Thorson 40a42dd637 misc fixes
2011-11-13 20:46:54 -06:00

326 lines
13 KiB
C++

/*
* Copyright (c) 2011, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef WEBSOCKET_INTERFACE_SESSION_HPP
#define WEBSOCKET_INTERFACE_SESSION_HPP
#include <boost/shared_ptr.hpp>
#include <string>
#include <vector>
#include "../websocket_constants.hpp"
#include "../network_utilities.hpp"
namespace websocketpp {
namespace session {
namespace state {
enum value {
CONNECTING = 0,
OPEN = 1,
CLOSING = 2,
CLOSED = 3
};
}
namespace error {
enum value {
FATAL_ERROR = 0, // force session end
SOFT_ERROR = 1, // should log and ignore
PROTOCOL_VIOLATION = 2, // must end session
PAYLOAD_VIOLATION = 3, // should end session
INTERNAL_SERVER_ERROR = 4, // cleanly end session
MESSAGE_TOO_BIG = 5 // ???
};
}
class exception : public std::exception {
public:
exception(const std::string& msg,
error::value code = error::FATAL_ERROR)
: m_msg(msg),m_code(code) {}
~exception() throw() {}
virtual const char* what() const throw() {
return m_msg.c_str();
}
error::value code() const throw() {
return m_code;
}
std::string m_msg;
error::value m_code;
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Server API *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
server(uint16_t port, server_handler_ptr handler)
void run();
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Server Session API *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class server {
public:
// Valid always
virtual session::state::value get_state() const = 0;
virtual unsigned int get_version() const = 0;
virtual std::string get_request_header(const std::string& key) const = 0;
virtual std::string get_origin() const = 0;
// Information about the requested URI
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;
// Information about the connected endpoint
/* Tentative API member function */ virtual boost::asio::ip::tcp::endpoint get_endpoint() const = 0;
// Valid for CONNECTING state
virtual void add_response_header(const std::string& key, const std::string& value) = 0;
virtual void replace_response_header(const std::string& key, const std::string& value) = 0;
virtual const std::vector<std::string>& get_subprotocols() const = 0;
virtual const std::vector<std::string>& get_extensions() const = 0;
virtual void select_subprotocol(const std::string& value) = 0;
virtual void select_extension(const std::string& value) = 0;
// Valid for OPEN state
virtual void send(const utf8_string& payload) = 0;
virtual void send(const binary_string& data) = 0;
virtual void close(close::status::value code, const utf8_string& reason) = 0;
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;
virtual close::status::value get_remote_close_code() const = 0;
virtual utf8_string get_remote_close_reason() const = 0;
virtual bool get_failed_by_me() const = 0;
virtual bool get_dropped_by_me() const = 0;
virtual bool get_closed_by_me() const = 0;
};
typedef boost::shared_ptr<server> server_ptr;
typedef server_ptr server_session_ptr;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Server Handler API *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class server_handler {
public:
virtual ~server_handler() {}
// validate will be called after a websocket handshake has been received and
// before it is accepted. It provides a handler the ability to refuse a
// connection based on application specific logic (ex: restrict domains or
// negotiate subprotocols). To reject the connection throw a handshake_error
//
// handshake_error parameters:
// log_message - error message to send to server log
// http_error_code - numeric HTTP error code to return to the client
// http_error_msg - (optional) string HTTP error code to return to the
// client (useful for returning non-standard error codes)
virtual void validate(server_ptr session) = 0;
// on_open is called after the websocket session has been successfully
// established and is in the OPEN state. The session is now avaliable to
// send messages and will begin reading frames and calling the on_message/
// on_close/on_error callbacks. A client may reject the connection by
// closing the session at this point.
virtual void on_open(server_ptr session) = 0;
// on_close is called whenever an open session is closed for any reason.
// This can be due to either endpoint requesting a connection close or an
// error occuring. Information about why the session was closed can be
// extracted from the session itself.
//
// on_close will be the last time a session calls its handler. If your
// application will need information from `session` after this function you
// should either save the session_ptr somewhere or copy the data out.
virtual void on_close(server_ptr session) = 0;
// on_message (binary version) will be called when a binary message is
// recieved. Message data is passed as a vector of bytes (unsigned char).
// data will not be avaliable after this callback ends so the handler must
// either completely process the message or copy it somewhere else for
// processing later.
virtual void on_message(server_ptr session, binary_string_ptr data) = 0;
// on_message (text version). Identical to on_message except the data
// parameter is a string interpreted as UTF-8. WebSocket++ guarantees that
// this string is valid UTF-8.
virtual void on_message(server_ptr session, utf8_string_ptr msg) = 0;
// on_fail is called whenever a session is terminated or failed before it
// was successfully established. This happens if there is an error during
// the handshake process or if the server refused the connection.
//
// on_fail will be the last time a session calls its handler. If your
// application will need information from `session` after this function you
// should either save the session_ptr somewhere or copy the data out.
virtual void on_fail(server_ptr session) {};
// on_ping is called whenever a ping is recieved with the binary
// application data from the ping. If on_ping returns true the
// implimentation will send a response pong.
virtual bool on_ping(server_ptr session, binary_string_ptr data) {
return true;
}
// on_pong is called whenever a pong is recieved with the binary
// application data from the pong.
virtual void on_pong(server_ptr session, binary_string_ptr data) {}
// TODO: on_ping_timeout
};
typedef boost::shared_ptr<server_handler> server_handler_ptr;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Client Session API *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class client {
public:
client(const std::string& uri) {};
// Valid always
virtual session::state::value get_state() const = 0;
virtual int get_version() const = 0;
virtual std::string get_origin() 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;
virtual void add_request_header(const std::string& key, const std::string& value) = 0;
virtual void replace_request_header(const std::string& key, const std::string& value) = 0;
virtual void request_subprotocol(const std::string& value) = 0;
virtual void request_extension(const std::string& value) = 0;
// Valid for OPEN state
virtual std::string get_response_header(const std::string& key) const = 0;
virtual std::string get_subprotocol() const;
virtual const std::vector<std::string>& get_extensions() const = 0;
virtual void send(const utf8_string& msg) = 0;
virtual void send(const binary_string& data) = 0;
virtual void close(close::status::value code, const binary_string& reason) = 0;
virtual void ping(const binary_string& payload) = 0;
virtual void pong(const binary_string& payload) = 0;
// Valid for CLOSED state
virtual close::status::value get_local_close_code() const = 0;
virtual utf8_string get_local_close_reason() const = 0;
virtual close::status::value get_remote_close_code() const = 0;
virtual utf8_string get_remote_close_reason() const = 0;
virtual bool failed_by_me() const = 0;
virtual bool dropped_by_me() const = 0;
virtual bool closed_by_me() const = 0;
};
typedef boost::shared_ptr<client> client_ptr;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Client Handler API *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class client_handler {
public:
// on_open is called after the websocket session has been successfully
// established and is in the OPEN state. The session is now avaliable to
// send messages and will begin reading frames and calling the on_message/
// on_close/on_error callbacks. A client may reject the connection by
// closing the session at this point.
virtual void on_open(client_ptr session) = 0;
// on_close is called whenever an open session is closed for any reason.
// This can be due to either endpoint requesting a connection close or an
// error occuring. Information about why the session was closed can be
// extracted from the session itself.
//
// on_close will be the last time a session calls its handler. If your
// application will need information from `session` after this function you
// should either save the session_ptr somewhere or copy the data out.
virtual void on_close(client_ptr session) = 0;
// on_message (binary version) will be called when a binary message is
// recieved. Message data is passed as a vector of bytes (unsigned char).
// data will not be avaliable after this callback ends so the handler must
// either completely process the message or copy it somewhere else for
// processing later.
virtual void on_message(client_ptr session, binary_string_ptr data) = 0;
// on_message (text version). Identical to on_message except the data
// parameter is a string interpreted as UTF-8. WebSocket++ guarantees that
// this string is valid UTF-8.
virtual void on_message(client_ptr session, utf8_string_ptr msg) = 0;
// on_fail is called whenever a session is terminated or failed before it
// was successfully established. This happens if there is an error during
// the handshake process or if the server refused the connection.
//
// on_fail will be the last time a session calls its handler. If your
// application will need information from `session` after this function you
// should either save the session_ptr somewhere or copy the data out.
virtual void on_fail(client_ptr session) {};
// on_ping is called whenever a ping is recieved with the binary
// application data from the ping. If on_ping returns true the
// implimentation will send a response pong.
virtual bool on_ping(server_ptr session, binary_string_ptr data) {
return true;
}
// on_pong is called whenever a pong is recieved with the binary
// application data from the pong.
virtual void on_pong(server_ptr session, binary_string_ptr data) {}
// TODO: on_ping_timeout
};
typedef boost::shared_ptr<client_handler> client_handler_ptr;
}
}
#endif // WEBSOCKET_INTERFACE_SESSION_HPP