mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
removes a bunch of debug code, adds friend setup, adds role specific connection policy, begins work to integrate http parser
This commit is contained in:
@@ -28,6 +28,12 @@
|
||||
#ifndef WEBSOCKETPP_CONNECTION_HPP
|
||||
#define WEBSOCKETPP_CONNECTION_HPP
|
||||
|
||||
//#include "endpoint.hpp"
|
||||
#include "http/parser.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include "roles/server.hpp"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
@@ -42,26 +48,31 @@ struct connection_traits;
|
||||
|
||||
template <
|
||||
typename endpoint,
|
||||
template <class> class role,
|
||||
template <class> class socket>
|
||||
class connection
|
||||
: public socket< connection<endpoint,socket> >,
|
||||
public boost::enable_shared_from_this< connection<endpoint, socket> >
|
||||
: public role< connection<endpoint,role,socket> >,
|
||||
public socket< connection<endpoint,role,socket> >,
|
||||
public boost::enable_shared_from_this< connection<endpoint,role,socket> >
|
||||
{
|
||||
public:
|
||||
typedef connection_traits< connection<endpoint,socket> > traits;
|
||||
typedef connection_traits< connection<endpoint,role,socket> > traits;
|
||||
|
||||
// get types that we need from our traits class
|
||||
typedef typename traits::type type;
|
||||
typedef typename traits::role_type role_type;
|
||||
typedef typename traits::socket_type socket_type;
|
||||
|
||||
typedef endpoint endpoint_type;
|
||||
|
||||
// friends (would require C++11) this would enable connection::start to be
|
||||
// protected instead of public.
|
||||
// friend typename endpoint_traits<endpoint_type>::role_type;
|
||||
|
||||
connection(endpoint_type& e)
|
||||
: socket_type(e),
|
||||
m_endpoint(e)
|
||||
{
|
||||
std::cout << "setup connection" << std::endl;
|
||||
}
|
||||
: role_type(e),
|
||||
socket_type(e),
|
||||
m_endpoint(e) {}
|
||||
|
||||
void start() {
|
||||
// initialize the socket.
|
||||
@@ -73,17 +84,19 @@ public:
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected:
|
||||
void handle_socket_init(const boost::system::error_code& error) {
|
||||
if (error) {
|
||||
std::cout << "SSL handshake error" << std::endl;
|
||||
} else {
|
||||
this->websocket_handshake();
|
||||
m_endpoint.elog().at(log::elevel::ERROR) << "Connection initialization failed, error code: " << error << log::endl;
|
||||
this->terminate();
|
||||
return;
|
||||
}
|
||||
|
||||
this->websocket_handshake();
|
||||
}
|
||||
|
||||
void websocket_handshake() {
|
||||
std::cout << "Websocket Handshake" << std::endl;
|
||||
m_endpoint.alog().at(log::alevel::DEVEL) << "Websocket Handshake" << log::endl;
|
||||
|
||||
socket_type::get_socket().async_read_some(
|
||||
boost::asio::buffer(m_data, 512),
|
||||
@@ -94,13 +107,6 @@ public:
|
||||
boost::asio::placeholders::bytes_transferred
|
||||
)
|
||||
);
|
||||
|
||||
this->websocket_messages(); // temp
|
||||
}
|
||||
|
||||
// temporary
|
||||
void websocket_messages() {
|
||||
std::cout << "Websocket Messages" << std::endl;
|
||||
}
|
||||
|
||||
void handle_read(const boost::system::error_code& error,
|
||||
@@ -131,22 +137,36 @@ public:
|
||||
} else {
|
||||
std::cout << "write successful" << std::endl;
|
||||
// end session
|
||||
m_endpoint.remove_connection(type::shared_from_this());
|
||||
this->terminate();
|
||||
}
|
||||
}
|
||||
|
||||
// terminate cleans up a connection and removes it from the endpoint's
|
||||
// connection list.
|
||||
void terminate() {
|
||||
// TODO: close socket cleanly
|
||||
m_endpoint.remove_connection(type::shared_from_this());
|
||||
}
|
||||
protected:
|
||||
endpoint_type& m_endpoint;
|
||||
char m_data[512]; // temporary
|
||||
|
||||
http::parser::request m_request;
|
||||
http::parser::response m_response;
|
||||
};
|
||||
|
||||
// connection related types that it and its policy classes need.
|
||||
template <typename endpoint,template <class> class socket>
|
||||
struct connection_traits< connection<endpoint, socket> > {
|
||||
template <
|
||||
typename endpoint,
|
||||
template <class> class role,
|
||||
template <class> class socket>
|
||||
struct connection_traits< connection<endpoint,role,socket> > {
|
||||
// type of the connection itself
|
||||
typedef connection<endpoint,socket> type;
|
||||
typedef connection<endpoint,role,socket> type;
|
||||
|
||||
// types of the connection policies
|
||||
typedef endpoint endpoint_type;
|
||||
typedef role< type > role_type;
|
||||
typedef socket< type > socket_type;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,83 +28,123 @@
|
||||
#ifndef WEBSOCKETPP_ENDPOINT_HPP
|
||||
#define WEBSOCKETPP_ENDPOINT_HPP
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
template <typename T>
|
||||
struct endpoint_traits;
|
||||
|
||||
|
||||
|
||||
class endpoint_base {
|
||||
protected:
|
||||
boost::asio::io_service m_io_service;
|
||||
};
|
||||
}
|
||||
|
||||
#include "connection.hpp"
|
||||
#include "sockets/plain.hpp" // should this be here?
|
||||
#include "logger.hpp"
|
||||
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct endpoint_traits;
|
||||
|
||||
// endpoint_base provides core functionality used by policy base class constructors
|
||||
class endpoint_base {
|
||||
protected:
|
||||
boost::asio::io_service m_io_service;
|
||||
};
|
||||
|
||||
|
||||
// endpoint host class
|
||||
template <template <class> class role,template <class> class socket>
|
||||
template <
|
||||
template <class> class role,
|
||||
template <class> class socket = socket::plain,
|
||||
template <class> class logger = log::logger>
|
||||
class endpoint
|
||||
: public endpoint_base,
|
||||
public role< endpoint<role,socket> >,
|
||||
public socket< endpoint<role,socket> >
|
||||
{
|
||||
public:
|
||||
typedef endpoint_traits< endpoint<role,socket> > traits;
|
||||
typedef endpoint_traits< endpoint<role,socket,logger> > traits;
|
||||
|
||||
// get types that we need from our traits class
|
||||
typedef typename traits::type type;
|
||||
typedef typename traits::handler_ptr handler_ptr;
|
||||
typedef typename traits::role_type role_type;
|
||||
typedef typename traits::socket_type socket_type;
|
||||
typedef typename traits::alogger_type alogger_type;
|
||||
typedef typename traits::elogger_type elogger_type;
|
||||
typedef typename traits::connection_type connection_type;
|
||||
typedef typename traits::connection_ptr connection_ptr;
|
||||
|
||||
endpoint(handler_ptr h) : role_type(m_io_service,h),socket_type(m_io_service) {
|
||||
std::cout << "Setup endpoint" << std::endl;
|
||||
// Friend is used here to allow the CRTP base classes to access member
|
||||
// functions in the derived endpoint. This is done to limit the use of
|
||||
// public methods in endpoint and its CRTP bases to only those methods
|
||||
// intended for end-application use.
|
||||
friend class role< endpoint<role,socket> >;
|
||||
friend class socket< endpoint<role,socket> >;
|
||||
friend class connection<type,role< type >::template connection,socket< type >::template connection>;
|
||||
|
||||
// Highly simplified and preferred C++11 version:
|
||||
// friend role_type;
|
||||
// friend socket_type;
|
||||
// friend connection_type;
|
||||
|
||||
endpoint(handler_ptr h) : role_type(m_io_service,h),socket_type(m_io_service) {}
|
||||
|
||||
alogger_type& alog() {
|
||||
return m_alog;
|
||||
}
|
||||
|
||||
void start() {
|
||||
std::cout << "Connect" << std::endl;
|
||||
|
||||
connection_ptr con = create_connection();
|
||||
con->start();
|
||||
elogger_type& elog() {
|
||||
return m_elog;
|
||||
}
|
||||
|
||||
protected:
|
||||
connection_ptr create_connection() {
|
||||
connection_ptr new_connection(new connection_type(*this));
|
||||
m_connections.insert(new_connection);
|
||||
|
||||
alog().at(log::alevel::DEVEL) << "Connection created: count is now: " << m_connections.size() << log::endl;
|
||||
|
||||
return new_connection;
|
||||
}
|
||||
|
||||
void remove_connection(connection_ptr con) {
|
||||
m_connections.erase(con);
|
||||
|
||||
alog().at(log::alevel::DEVEL) << "Connection removed: count is now: " << m_connections.size() << log::endl;
|
||||
}
|
||||
private:
|
||||
std::set<connection_ptr> m_connections;
|
||||
std::set<connection_ptr> m_connections;
|
||||
alogger_type m_alog;
|
||||
elogger_type m_elog;
|
||||
};
|
||||
|
||||
// endpoint related types that it and its policy classes need.
|
||||
template <template <class> class role,template <class> class socket>
|
||||
struct endpoint_traits< endpoint<role, socket> > {
|
||||
template <
|
||||
template <class> class role,
|
||||
template <class> class socket,
|
||||
template <class> class logger>
|
||||
struct endpoint_traits< endpoint<role, socket, logger> > {
|
||||
// type of the endpoint itself
|
||||
typedef endpoint<role,socket> type;
|
||||
typedef endpoint<role,socket,logger> type;
|
||||
|
||||
// types of the endpoint policies
|
||||
typedef role< type > role_type;
|
||||
typedef socket< type > socket_type;
|
||||
|
||||
typedef logger<log::alevel::value> alogger_type;
|
||||
typedef logger<log::elevel::value> elogger_type;
|
||||
|
||||
// type of the handler that this endpoint and its connections call back.
|
||||
typedef typename role_type::handler handler;
|
||||
typedef typename role_type::handler_ptr handler_ptr;
|
||||
|
||||
// types of the connections that this endpoint manages and pointers to them
|
||||
typedef connection<type,socket< type >::template connection> connection_type;
|
||||
typedef connection<type,role< type >::template connection,socket< type >::template connection> connection_type;
|
||||
typedef boost::shared_ptr<connection_type> connection_ptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,8 +28,10 @@
|
||||
#ifndef HTTP_PARSER_HPP
|
||||
#define HTTP_PARSER_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "constants.hpp"
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace alevel {
|
||||
static const value DEVEL = 0x2000;
|
||||
|
||||
static const value ALL = 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
namespace elevel {
|
||||
typedef uint16_t value;
|
||||
@@ -82,7 +82,7 @@ namespace elevel {
|
||||
|
||||
static const value ALL = 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
template <typename level_type>
|
||||
class logger {
|
||||
public:
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
std::cout << m_prefix <<
|
||||
boost::posix_time::to_iso_extended_string(
|
||||
boost::posix_time::second_clock::local_time()
|
||||
) << " " << m_oss.str() << std::endl;
|
||||
) << " [" << m_write_level << "] " << m_oss.str() << std::endl;
|
||||
m_oss.str("");
|
||||
}
|
||||
|
||||
|
||||
442
src/policy.cpp
442
src/policy.cpp
@@ -1,446 +1,22 @@
|
||||
/*
|
||||
build situation
|
||||
general:
|
||||
endpoint.hpp
|
||||
- libboost_system
|
||||
|
||||
SSL:
|
||||
- libboost_date_time (if you use the default logger)
|
||||
|
||||
sockets/ssl.hpp
|
||||
- libcrypto
|
||||
- libssl
|
||||
|
||||
*/
|
||||
|
||||
/*#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
class server_handler {
|
||||
virtual void on_action() = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<server_handler> server_handler_ptr;
|
||||
|
||||
class client_handler {
|
||||
virtual void on_action() = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<client_handler> client_handler_ptr;
|
||||
|
||||
|
||||
namespace connection {
|
||||
template <typename endpoint_type,template <class> class security_policy>
|
||||
class connection
|
||||
: public security_policy< connection<endpoint_type,security_policy> >,
|
||||
public boost::enable_shared_from_this< connection<endpoint_type, security_policy> > {
|
||||
public:
|
||||
typedef connection<endpoint_type,security_policy> type;
|
||||
typedef security_policy< type > security_policy_type;
|
||||
|
||||
//typedef typename role_type::handler_ptr handler_ptr;
|
||||
|
||||
connection(endpoint_type& e) : security_policy_type(e),m_endpoint(e) {
|
||||
std::cout << "setup connection" << std::endl;
|
||||
}
|
||||
|
||||
void websocket_handshake() {
|
||||
std::cout << "Websocket Handshake" << std::endl;
|
||||
|
||||
security_policy_type::get_socket().async_read_some(
|
||||
boost::asio::buffer(m_data, 512),
|
||||
boost::bind(
|
||||
&type::handle_read,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred
|
||||
)
|
||||
);
|
||||
|
||||
this->websocket_messages();
|
||||
}
|
||||
void websocket_messages() {
|
||||
std::cout << "Websocket Messages" << std::endl;
|
||||
}
|
||||
|
||||
void handle_read(const boost::system::error_code& error,size_t bytes_transferred) {
|
||||
if (error) {
|
||||
std::cout << "read error" << std::endl;
|
||||
} else {
|
||||
std::cout << "read complete: " << m_data << std::endl;
|
||||
|
||||
std::string r = "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nbar";
|
||||
|
||||
boost::asio::async_write(
|
||||
security_policy_type::get_socket(),
|
||||
boost::asio::buffer(r, r.size()),
|
||||
boost::bind(
|
||||
&type::handle_write,
|
||||
type::shared_from_this(),
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_write(const boost::system::error_code& error) {
|
||||
if (error) {
|
||||
std::cout << "write error" << std::endl;
|
||||
} else {
|
||||
std::cout << "write successful" << std::endl;
|
||||
// end session
|
||||
m_endpoint.remove_connection(type::shared_from_this());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
endpoint_type& m_endpoint;
|
||||
char m_data[512];
|
||||
};
|
||||
|
||||
// Connection roles
|
||||
template <class connection_type>
|
||||
class server {
|
||||
public:
|
||||
typedef server_handler_ptr handler_ptr;
|
||||
|
||||
server (handler_ptr h) : m_handler(h) {
|
||||
std::cout << "setup server connection role" << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
handler_ptr m_handler;
|
||||
};
|
||||
|
||||
template <class connection_type>
|
||||
class client {
|
||||
public:
|
||||
typedef client_handler_ptr handler_ptr;
|
||||
|
||||
client (handler_ptr h) : m_handler(h) {
|
||||
std::cout << "setup client connection role" << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
handler_ptr m_handler;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace endpoint {
|
||||
|
||||
template <typename derived_t>
|
||||
struct endpoint_traits;
|
||||
|
||||
class endpoint_base {
|
||||
protected:
|
||||
boost::asio::io_service m_io_service;
|
||||
};
|
||||
|
||||
template <template <class> class role,template <class> class security_policy>
|
||||
class endpoint
|
||||
: public endpoint_base,
|
||||
public role< endpoint<role,security_policy> >,
|
||||
public security_policy< endpoint<role,security_policy> >
|
||||
{
|
||||
public:
|
||||
typedef role< endpoint<role,security_policy> > role_type;
|
||||
typedef security_policy< endpoint<role,security_policy> > security_policy_type;
|
||||
typedef endpoint<role,security_policy> type;
|
||||
|
||||
typedef typename role_type::handler_ptr handler_ptr;
|
||||
|
||||
typedef connection::connection<type,security_policy< endpoint<role,security_policy> >::template connection> connection_type;
|
||||
typedef boost::shared_ptr<connection_type> connection_ptr;
|
||||
|
||||
endpoint(handler_ptr h) : role_type(m_io_service,h),security_policy_type(m_io_service) {
|
||||
std::cout << "Setup endpoint" << std::endl;
|
||||
}
|
||||
|
||||
void start() {
|
||||
std::cout << "Connect" << std::endl;
|
||||
|
||||
connection_ptr con = create_connection();
|
||||
con->security_handshake();
|
||||
}
|
||||
|
||||
connection_ptr create_connection() {
|
||||
connection_ptr new_connection(new connection_type(*this));
|
||||
m_connections.insert(new_connection);
|
||||
return new_connection;
|
||||
}
|
||||
|
||||
void remove_connection(connection_ptr con) {
|
||||
m_connections.erase(con);
|
||||
}
|
||||
private:
|
||||
std::set<connection_ptr> m_connections;
|
||||
};
|
||||
|
||||
// endpoint related types that it's policy classes need.
|
||||
template <template <class> class role,template <class> class security_policy>
|
||||
struct endpoint_traits<endpoint<role, security_policy> > {
|
||||
typedef endpoint<role,security_policy> type;
|
||||
|
||||
typedef connection::connection<type,security_policy< endpoint<role,security_policy> >::template connection> connection_type;
|
||||
typedef boost::shared_ptr<connection_type> connection_ptr;
|
||||
};
|
||||
|
||||
// Security Policies
|
||||
template <typename endpoint_type>
|
||||
class plain {
|
||||
public:
|
||||
boost::asio::io_service& get_io_service() {
|
||||
return m_io_service;
|
||||
}
|
||||
|
||||
// Connection specific details
|
||||
template <typename connection_type>
|
||||
class connection {
|
||||
public:
|
||||
connection(plain<endpoint_type>& e) : m_socket(e.get_io_service()) {
|
||||
std::cout << "setup plain connection" << std::endl;
|
||||
}
|
||||
|
||||
void security_handshake() {
|
||||
std::cout << "performing plain security handshake" << std::endl;
|
||||
static_cast< connection_type* >(this)->websocket_handshake();
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket& get_raw_socket() {
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket& get_socket() {
|
||||
return m_socket;
|
||||
}
|
||||
private:
|
||||
boost::asio::ip::tcp::socket m_socket;
|
||||
};
|
||||
protected:
|
||||
plain (boost::asio::io_service& m) : m_io_service(m) {
|
||||
std::cout << "setup plain endpoint" << std::endl;
|
||||
}
|
||||
private:
|
||||
boost::asio::io_service& m_io_service;
|
||||
};
|
||||
|
||||
template <typename endpoint_type>
|
||||
class ssl {
|
||||
public:
|
||||
typedef ssl<endpoint_type> type;
|
||||
|
||||
std::string get_password() const {
|
||||
return "test";
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service() {
|
||||
return m_io_service;
|
||||
}
|
||||
|
||||
boost::asio::ssl::context& get_context() {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// Connection specific details
|
||||
template <typename connection_type>
|
||||
class connection {
|
||||
public:
|
||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
|
||||
|
||||
connection(ssl<endpoint_type>& e) : m_socket(e.get_io_service(),e.get_context()) {
|
||||
std::cout << "setup ssl connection" << std::endl;
|
||||
}
|
||||
|
||||
void security_handshake() {
|
||||
std::cout << "performing ssl security handshake" << std::endl;
|
||||
|
||||
m_socket.async_handshake(
|
||||
boost::asio::ssl::stream_base::server,
|
||||
boost::bind(
|
||||
&connection<connection_type>::handle_handshake,
|
||||
this,
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_handshake(const boost::system::error_code& error) {
|
||||
if (error) {
|
||||
std::cout << "SSL handshake error" << std::endl;
|
||||
} else {
|
||||
static_cast< connection_type* >(this)->websocket_handshake();
|
||||
}
|
||||
}
|
||||
|
||||
ssl_socket::lowest_layer_type& get_raw_socket() {
|
||||
return m_socket.lowest_layer();
|
||||
}
|
||||
|
||||
ssl_socket& get_socket() {
|
||||
return m_socket;
|
||||
}
|
||||
private:
|
||||
ssl_socket m_socket;
|
||||
};
|
||||
protected:
|
||||
ssl (boost::asio::io_service& m) : m_io_service(m),m_context(boost::asio::ssl::context::sslv23) {
|
||||
std::cout << "setup ssl endpoint" << std::endl;
|
||||
|
||||
try {
|
||||
m_context.set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
m_context.set_password_callback(boost::bind(&type::get_password, this));
|
||||
m_context.use_certificate_chain_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem");
|
||||
m_context.use_private_key_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem);
|
||||
m_context.use_tmp_dh_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/dh512.pem");
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
boost::asio::io_service& m_io_service;
|
||||
boost::asio::ssl::context m_context;
|
||||
};
|
||||
|
||||
// Endpoint roles
|
||||
template <class endpoint_type>
|
||||
class server {
|
||||
public:
|
||||
typedef server<endpoint_type> server_type;
|
||||
|
||||
typedef typename endpoint_traits<endpoint_type>::connection_ptr connection_ptr;
|
||||
|
||||
typedef server_handler_ptr handler_ptr; // duplicated typedef
|
||||
|
||||
server(boost::asio::io_service& m,handler_ptr h)
|
||||
: m_handler(h),
|
||||
m_io_service(m),
|
||||
m_endpoint(),
|
||||
m_acceptor(m) {
|
||||
std::cout << "setup server endpoint role" << std::endl;
|
||||
}
|
||||
|
||||
void listen(unsigned short port) {
|
||||
m_endpoint.port(port);
|
||||
m_acceptor.open(m_endpoint.protocol());
|
||||
m_acceptor.set_option(boost::asio::socket_base::reuse_address(true));
|
||||
m_acceptor.bind(m_endpoint);
|
||||
m_acceptor.listen();
|
||||
|
||||
this->accept();
|
||||
|
||||
|
||||
m_io_service.run();
|
||||
}
|
||||
|
||||
void connect() {
|
||||
static_cast< endpoint_type* >(this)->start();
|
||||
}
|
||||
|
||||
void public_api() {
|
||||
std::cout << "endpoint::server::public_api()" << std::endl;
|
||||
}
|
||||
protected:
|
||||
handler_ptr get_handler() {
|
||||
return m_handler;
|
||||
}
|
||||
|
||||
void protected_api() {
|
||||
std::cout << "endpoint::server::protected_api()" << std::endl;
|
||||
}
|
||||
private:
|
||||
void accept() {
|
||||
connection_ptr con = static_cast< endpoint_type* >(this)->create_connection();
|
||||
|
||||
m_acceptor.async_accept(
|
||||
con->get_raw_socket(),
|
||||
|
||||
boost::bind(
|
||||
&server_type::handle_accept,
|
||||
this,
|
||||
con,
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_accept(connection_ptr con, const boost::system::error_code& error) {
|
||||
if (!error) {
|
||||
con->security_handshake();
|
||||
} else {
|
||||
throw "";
|
||||
}
|
||||
|
||||
this->accept();
|
||||
}
|
||||
|
||||
void private_api() {
|
||||
std::cout << "endpoint::server::private_api()" << std::endl;
|
||||
}
|
||||
handler_ptr m_handler;
|
||||
boost::asio::io_service& m_io_service;
|
||||
boost::asio::ip::tcp::endpoint m_endpoint;
|
||||
boost::asio::ip::tcp::acceptor m_acceptor;
|
||||
};
|
||||
|
||||
template <class endpoint_type>
|
||||
class client {
|
||||
public:
|
||||
//typedef connection::client connection_type;
|
||||
typedef client_handler_ptr handler_ptr; // duplicated typedef
|
||||
|
||||
client (boost::asio::io_service& m,handler_ptr h) : m_handler(h),m_io_service(m) {
|
||||
std::cout << "setup client endpoint role" << std::endl;
|
||||
}
|
||||
|
||||
void connect() {
|
||||
static_cast< endpoint_type* >(this)->start();
|
||||
}
|
||||
|
||||
void public_api() {
|
||||
std::cout << "endpoint::client::public_api()" << std::endl;
|
||||
}
|
||||
protected:
|
||||
handler_ptr get_handler() {
|
||||
return m_handler;
|
||||
}
|
||||
|
||||
void protected_api() {
|
||||
std::cout << "endpoint::client::protected_api()" << std::endl;
|
||||
}
|
||||
private:
|
||||
void private_api() {
|
||||
std::cout << "endpoint::client::private_api()" << std::endl;
|
||||
}
|
||||
handler_ptr m_handler;
|
||||
boost::asio::io_service& m_io_service;
|
||||
};
|
||||
|
||||
template <template <class> class endpoint_role,template <class> class security_type>
|
||||
class factory {
|
||||
public:
|
||||
typedef endpoint<endpoint_role,security_type> endpoint_type;
|
||||
typedef endpoint_role<endpoint_type> endpoint_interface;
|
||||
typedef boost::shared_ptr<endpoint_interface> endpoint_ptr;
|
||||
|
||||
typedef typename endpoint_type::handler_ptr handler_ptr;
|
||||
|
||||
endpoint_ptr create(handler_ptr h) {
|
||||
return endpoint_ptr(new endpoint_type(h));
|
||||
}
|
||||
};
|
||||
|
||||
}*/
|
||||
|
||||
// Application start
|
||||
#include "endpoint.hpp"
|
||||
#include "roles/server.hpp"
|
||||
#include "sockets/ssl.hpp"
|
||||
|
||||
typedef websocketpp::endpoint<websocketpp::role::server,websocketpp::socket::plain> endpoint_type;
|
||||
typedef websocketpp::endpoint<websocketpp::role::server,websocketpp::socket::ssl> endpoint_type;
|
||||
//typedef websocketpp::endpoint<websocketpp::role::server> endpoint_type;
|
||||
typedef websocketpp::role::server<endpoint_type>::handler handler_type;
|
||||
typedef websocketpp::role::server<endpoint_type>::handler_ptr handler_ptr;
|
||||
|
||||
@@ -462,7 +38,11 @@ int main () {
|
||||
std::cout << "Endpoint 0" << std::endl;
|
||||
handler_ptr h(new application_server_handler());
|
||||
endpoint_type e(h);
|
||||
|
||||
|
||||
e.alog().set_level(websocketpp::log::alevel::ALL);
|
||||
e.elog().set_level(websocketpp::log::elevel::ALL);
|
||||
|
||||
|
||||
e.listen(9000);
|
||||
//e.connect();
|
||||
//e.public_api();
|
||||
|
||||
@@ -54,31 +54,36 @@ public:
|
||||
typedef endpoint endpoint_type;
|
||||
typedef typename endpoint_traits<endpoint>::connection_ptr connection_ptr;
|
||||
|
||||
client (boost::asio::io_service& m,handler_ptr h) : m_handler(h),m_io_service(m) {
|
||||
std::cout << "setup client endpoint role" << std::endl;
|
||||
}
|
||||
client (boost::asio::io_service& m,handler_ptr h)
|
||||
: m_endpoint(static_cast< endpoint_type& >(*this)),
|
||||
m_handler(h),
|
||||
m_io_service(m) {}
|
||||
|
||||
void connect() {
|
||||
static_cast< endpoint_type* >(this)->start();
|
||||
}
|
||||
|
||||
void public_api() {
|
||||
std::cout << "endpoint::client::public_api()" << std::endl;
|
||||
}
|
||||
// Connection specific details
|
||||
template <typename connection_type>
|
||||
class connection {
|
||||
public:
|
||||
connection(server<endpoint_type>& e) {}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
protected:
|
||||
bool is_server() {
|
||||
return false;
|
||||
}
|
||||
|
||||
handler_ptr get_handler() {
|
||||
return m_handler;
|
||||
}
|
||||
|
||||
void protected_api() {
|
||||
std::cout << "endpoint::client::protected_api()" << std::endl;
|
||||
}
|
||||
private:
|
||||
void private_api() {
|
||||
std::cout << "endpoint::client::private_api()" << std::endl;
|
||||
}
|
||||
handler_ptr m_handler;
|
||||
boost::asio::io_service& m_io_service;
|
||||
endpoint_type& m_endpoint;
|
||||
handler_ptr m_handler;
|
||||
boost::asio::io_service& m_io_service;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,16 @@ namespace role {
|
||||
template <class endpoint>
|
||||
class server {
|
||||
public:
|
||||
// Connection specific details
|
||||
template <typename foo_type>
|
||||
class connection {
|
||||
public:
|
||||
connection(server<endpoint>& e) {}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
// handler interface callback class
|
||||
class handler {
|
||||
virtual void on_action() = 0;
|
||||
@@ -52,16 +62,16 @@ public:
|
||||
// types
|
||||
typedef server<endpoint> type;
|
||||
typedef endpoint endpoint_type;
|
||||
|
||||
typedef typename endpoint_traits<endpoint>::connection_ptr connection_ptr;
|
||||
|
||||
server(boost::asio::io_service& m,handler_ptr h)
|
||||
: m_handler(h),
|
||||
: m_ws_endpoint(static_cast< endpoint_type& >(*this)),
|
||||
m_handler(h),
|
||||
m_io_service(m),
|
||||
m_endpoint(),
|
||||
m_acceptor(m)
|
||||
{
|
||||
std::cout << "setup server endpoint role" << std::endl;
|
||||
}
|
||||
{}
|
||||
|
||||
void listen(unsigned short port) {
|
||||
m_endpoint.port(port);
|
||||
@@ -70,25 +80,24 @@ public:
|
||||
m_acceptor.bind(m_endpoint);
|
||||
m_acceptor.listen();
|
||||
|
||||
this->accept();
|
||||
this->start_accept();
|
||||
|
||||
m_ws_endpoint.alog().at(log::alevel::DEVEL) << "role::server listening on port " << port << log::endl;
|
||||
|
||||
m_io_service.run();
|
||||
}
|
||||
|
||||
void public_api() {
|
||||
std::cout << "role::server::public_api()" << std::endl;
|
||||
}
|
||||
protected:
|
||||
bool is_server() {
|
||||
return true;
|
||||
}
|
||||
|
||||
handler_ptr get_handler() {
|
||||
return m_handler;
|
||||
}
|
||||
|
||||
void protected_api() {
|
||||
std::cout << "role::server::protected_api()" << std::endl;
|
||||
}
|
||||
private:
|
||||
void accept() {
|
||||
connection_ptr con = static_cast< endpoint_type* >(this)->create_connection();
|
||||
// start_accept creates a new connection and begins an async_accept on it
|
||||
void start_accept() {
|
||||
connection_ptr con = m_ws_endpoint.create_connection();
|
||||
|
||||
m_acceptor.async_accept(
|
||||
con->get_raw_socket(),
|
||||
@@ -101,20 +110,20 @@ private:
|
||||
);
|
||||
}
|
||||
|
||||
// handle_accept will begin the connection's read/write loop and then reset
|
||||
// the server to accept a new connection. Errors returned by async_accept
|
||||
// are logged and ingored.
|
||||
void handle_accept(connection_ptr con, const boost::system::error_code& error) {
|
||||
if (!error) {
|
||||
con->start();
|
||||
if (error) {
|
||||
m_ws_endpoint.elog().at(log::elevel::ERROR) << "async_accept returned error: " << error << log::endl;
|
||||
} else {
|
||||
throw "";
|
||||
con->start();
|
||||
}
|
||||
|
||||
this->accept();
|
||||
}
|
||||
|
||||
void private_api() {
|
||||
std::cout << "role::server::private_api()" << std::endl;
|
||||
this->start_accept();
|
||||
}
|
||||
|
||||
endpoint_type& m_ws_endpoint;
|
||||
handler_ptr m_handler;
|
||||
boost::asio::io_service& m_io_service;
|
||||
boost::asio::ip::tcp::endpoint m_endpoint;
|
||||
|
||||
@@ -49,13 +49,10 @@ public:
|
||||
template <typename connection_type>
|
||||
class connection {
|
||||
public:
|
||||
connection(plain<endpoint_type>& e) : m_socket(e.get_io_service()) {
|
||||
std::cout << "setup plain connection" << std::endl;
|
||||
}
|
||||
connection(plain<endpoint_type>& e) : m_socket(e.get_io_service()) {}
|
||||
|
||||
void async_init(socket_init_callback callback) {
|
||||
std::cout << "performing plain security handshake" << std::endl;
|
||||
//static_cast< connection_type* >(this)->websocket_handshake();
|
||||
// TODO: should this use post()?
|
||||
callback(boost::system::error_code());
|
||||
}
|
||||
|
||||
@@ -70,9 +67,7 @@ public:
|
||||
boost::asio::ip::tcp::socket m_socket;
|
||||
};
|
||||
protected:
|
||||
plain (boost::asio::io_service& m) : m_io_service(m) {
|
||||
std::cout << "setup plain endpoint" << std::endl;
|
||||
}
|
||||
plain (boost::asio::io_service& m) : m_io_service(m) {}
|
||||
private:
|
||||
boost::asio::io_service& m_io_service;
|
||||
};
|
||||
|
||||
@@ -43,6 +43,7 @@ template <typename endpoint_type>
|
||||
class ssl {
|
||||
public:
|
||||
typedef ssl<endpoint_type> type;
|
||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
|
||||
|
||||
std::string get_password() const {
|
||||
return "test";
|
||||
@@ -58,21 +59,26 @@ public:
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// should be private friended?
|
||||
ssl_socket::handshake_type get_handshake_type() {
|
||||
if (static_cast< endpoint_type* >(this)->is_server()) {
|
||||
return boost::asio::ssl::stream_base::server;
|
||||
} else {
|
||||
return boost::asio::ssl::stream_base::client;
|
||||
}
|
||||
}
|
||||
|
||||
// Connection specific details
|
||||
template <typename connection_type>
|
||||
class connection {
|
||||
public:
|
||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
|
||||
|
||||
connection(ssl<endpoint_type>& e) : m_socket(e.get_io_service(),e.get_context()) {
|
||||
std::cout << "setup ssl connection" << std::endl;
|
||||
}
|
||||
connection(ssl<endpoint_type>& e) : m_socket(e.get_io_service(),e.get_context()),m_endpoint(e) {}
|
||||
|
||||
void async_init(boost::function<void(const boost::system::error_code&)> callback) {
|
||||
std::cout << "performing ssl security handshake" << std::endl;
|
||||
|
||||
m_socket.async_handshake(
|
||||
boost::asio::ssl::stream_base::server,
|
||||
m_endpoint.get_handshake_type(),
|
||||
boost::bind(
|
||||
&connection<connection_type>::handle_init,
|
||||
this,
|
||||
@@ -100,7 +106,8 @@ public:
|
||||
return m_socket;
|
||||
}
|
||||
private:
|
||||
ssl_socket m_socket;
|
||||
ssl_socket m_socket;
|
||||
ssl<endpoint_type>& m_endpoint;
|
||||
};
|
||||
protected:
|
||||
ssl (boost::asio::io_service& m) : m_io_service(m),m_context(boost::asio::ssl::context::sslv23) {
|
||||
@@ -112,16 +119,17 @@ protected:
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
m_context.set_password_callback(boost::bind(&type::get_password, this));
|
||||
m_context.use_certificate_chain_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem");
|
||||
m_context.use_private_key_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem);
|
||||
m_context.use_tmp_dh_file("/Users/zaphoyd/Documents/websocketpp/src/ssl/dh512.pem");
|
||||
m_context.use_certificate_chain_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/server.pem");
|
||||
m_context.use_private_key_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/server.pem", boost::asio::ssl::context::pem);
|
||||
m_context.use_tmp_dh_file("/Users/zaphoyd/Documents/ZS/websocketpp/src/ssl/dh512.pem");
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
boost::asio::io_service& m_io_service;
|
||||
boost::asio::ssl::context m_context;
|
||||
boost::asio::io_service& m_io_service;
|
||||
boost::asio::ssl::context m_context;
|
||||
ssl_socket::handshake_type m_handshake_type;
|
||||
};
|
||||
|
||||
} // namespace socket
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
B6FE8D5A14730B1200B32547 /* libboost_system.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B6DF1CBC1434AE070029A1B1 /* libboost_system.dylib */; };
|
||||
B6FE8D5C14730B1A00B32547 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B6FE8D5B14730B1A00B32547 /* libcrypto.dylib */; };
|
||||
B6FE8D5E14730B2200B32547 /* libssl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B6FE8D5D14730B2200B32547 /* libssl.dylib */; };
|
||||
B6FE8D6614757D6400B32547 /* libboost_date_time.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B6DF1CBE1434AF6A0029A1B1 /* libboost_date_time.dylib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -284,6 +285,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B6FE8D6614757D6400B32547 /* libboost_date_time.dylib in Frameworks */,
|
||||
B6FE8D5E14730B2200B32547 /* libssl.dylib in Frameworks */,
|
||||
B6FE8D5C14730B1A00B32547 /* libcrypto.dylib in Frameworks */,
|
||||
B6FE8D5A14730B1200B32547 /* libboost_system.dylib in Frameworks */,
|
||||
|
||||
Reference in New Issue
Block a user