Skip to content

Issue #844 Add host information to log messages #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
5 changes: 3 additions & 2 deletions include/fc/network/http/websocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace fc { namespace http {
boost::any& get_session_data() { return _session_data; }

virtual std::string get_request_header(const std::string& key) = 0;
virtual std::string get_host() = 0;

fc::signal<void()> closed;
private:
Expand All @@ -44,7 +45,7 @@ namespace fc { namespace http {
class websocket_server
{
public:
websocket_server();
websocket_server(std::string host_header_key = std::string() );
~websocket_server();

void on_connection( const on_connection_handler& handler);
Expand All @@ -62,7 +63,7 @@ namespace fc { namespace http {
{
public:
websocket_tls_server( const std::string& server_pem = std::string(),
const std::string& ssl_password = std::string());
const std::string& ssl_password = std::string(), std::string host_header_key = std::string() );
~websocket_tls_server();

void on_connection( const on_connection_handler& handler);
Expand Down
113 changes: 49 additions & 64 deletions src/network/http/websocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,6 @@ namespace fc { namespace http {
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;

/// Custom Logging policies
/*typedef websocketpp::log::syslog<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::syslog<concurrency_type,
websocketpp::log::alevel> alog_type;
*/
//typedef base::alog_type alog_type;
//typedef base::elog_type elog_type;
typedef websocketpp::log::stub elog_type;
typedef websocketpp::log::stub alog_type;

Expand Down Expand Up @@ -91,14 +83,6 @@ namespace fc { namespace http {
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;

/// Custom Logging policies
/*typedef websocketpp::log::syslog<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::syslog<concurrency_type,
websocketpp::log::alevel> alog_type;
*/
//typedef base::alog_type alog_type;
//typedef base::elog_type elog_type;
typedef websocketpp::log::stub elog_type;
typedef websocketpp::log::stub alog_type;

Expand Down Expand Up @@ -131,8 +115,6 @@ namespace fc { namespace http {
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;

//typedef base::alog_type alog_type;
//typedef base::elog_type elog_type;
typedef websocketpp::log::stub elog_type;
typedef websocketpp::log::stub alog_type;

Expand Down Expand Up @@ -163,21 +145,18 @@ namespace fc { namespace http {
class websocket_connection_impl : public websocket_connection
{
public:
websocket_connection_impl( T con )
:_ws_connection(con){
}
websocket_connection_impl( T con, std::string host_header_key = std::string() )
:_ws_connection(con), host_header_key(host_header_key) {}

~websocket_connection_impl()
{
}
~websocket_connection_impl() {}

virtual void send_message( const std::string& message )override
{
idump((message));
//std::cerr<<"send: "<<message<<"\n";
idump( (message) );
auto ec = _ws_connection->send( message );
FC_ASSERT( !ec, "websocket send failed: ${msg}", ("msg",ec.message() ) );
}

virtual void close( int64_t code, const std::string& reason )override
{
_ws_connection->close(code,reason);
Expand All @@ -188,15 +167,27 @@ namespace fc { namespace http {
return _ws_connection->get_request_header(key);
}

virtual std::string get_host() override
{
if (!host_header_key.empty())
{
auto header = get_request_header(host_header_key);
if (!header.empty())
return header;
}
return _ws_connection->get_host();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think get_host is wrong, according to the docs it returns the host component of the requested URI, not the remote host.

Copy link
Author

@jmjatlanta jmjatlanta Apr 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will investigate. Please do not bother reviewing until I edit this comment.

}
private:
T _ws_connection;
std::string host_header_key;
};

typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;

class websocket_server_impl
{
public:
websocket_server_impl()
websocket_server_impl(std::string host_header_key)
:_server_thread( fc::thread::current() )
{

Expand All @@ -205,20 +196,20 @@ namespace fc { namespace http {
_server.set_reuse_addr(true);
_server.set_open_handler( [&]( connection_hdl hdl ){
_server_thread.async( [&](){
auto new_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
auto new_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>(
_server.get_con_from_hdl(hdl), host_header_key );
_on_connection( _connections[hdl] = new_con );
}).wait();
});
_server.set_message_handler( [&]( connection_hdl hdl, websocket_server_type::message_ptr msg ){
_server_thread.async( [&](){
auto current_con = _connections.find(hdl);
assert( current_con != _connections.end() );
wdump(("server")(msg->get_payload()));
//std::cerr<<"recv: "<<msg->get_payload()<<"\n";
auto payload = msg->get_payload();
std::shared_ptr<websocket_connection> con = current_con->second;
std::shared_ptr<websocket_connection> ws_con = current_con->second;
wdump( ("server") (ws_con->get_host() ) (payload) );
++_pending_messages;
auto f = fc::async([this,con,payload](){ if( _pending_messages ) --_pending_messages; con->on_message( payload ); });
auto f = fc::async([this,ws_con,payload](){ if( _pending_messages ) --_pending_messages; ws_con->on_message( payload ); });
if( _pending_messages > 100 )
f.wait();
}).wait();
Expand All @@ -231,17 +222,18 @@ namespace fc { namespace http {

_server.set_http_handler( [&]( connection_hdl hdl ){
_server_thread.async( [&](){
auto current_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
auto current_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>(
_server.get_con_from_hdl(hdl), host_header_key );
_on_connection( current_con );

auto con = _server.get_con_from_hdl(hdl);
con->defer_http_response();
std::string request_body = con->get_request_body();
wdump(("server")(request_body));
wdump( ("server") (current_con->get_host()) (request_body) );

fc::async([current_con, request_body, con] {
std::string response = current_con->on_http(request_body);
idump((response));
idump( ("server") (current_con->get_host()) (response) );
con->set_body( response );
con->set_status( websocketpp::http::status_code::ok );
con->send_http_response();
Expand Down Expand Up @@ -313,7 +305,7 @@ namespace fc { namespace http {
class websocket_tls_server_impl
{
public:
websocket_tls_server_impl( const string& server_pem, const string& ssl_password )
websocket_tls_server_impl( const string& server_pem, const string& ssl_password, std::string host_header_key )
:_server_thread( fc::thread::current() )
{
//if( server_pem.size() )
Expand All @@ -340,7 +332,8 @@ namespace fc { namespace http {
_server.set_reuse_addr(true);
_server.set_open_handler( [&]( connection_hdl hdl ){
_server_thread.async( [&](){
auto new_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
auto new_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>(
_server.get_con_from_hdl(hdl), host_header_key );
_on_connection( _connections[hdl] = new_con );
}).wait();
});
Expand All @@ -349,27 +342,29 @@ namespace fc { namespace http {
auto current_con = _connections.find(hdl);
assert( current_con != _connections.end() );
auto received = msg->get_payload();
std::shared_ptr<websocket_connection> con = current_con->second;
fc::async([con,received](){ con->on_message( received ); });
std::shared_ptr<websocket_connection> ws_con = current_con->second;
wdump( ("server") (ws_con->get_host()) (received) )
fc::async([ws_con,received](){ ws_con->on_message( received ); });
}).wait();
});

_server.set_http_handler( [&]( connection_hdl hdl ){
_server_thread.async( [&](){

auto current_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
auto current_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>(
_server.get_con_from_hdl(hdl), host_header_key );
try{
_on_connection( current_con );

auto con = _server.get_con_from_hdl(hdl);
wdump(("server")(con->get_request_body()));
wdump( ("server") (con->get_host()) (con->get_request_body()) );
auto response = current_con->on_http( con->get_request_body() );
idump((response));
idump( ("server") (current_con->get_host()) (response) );
con->set_body( response );
con->set_status( websocketpp::http::status_code::ok );
} catch ( const fc::exception& e )
{
edump((e.to_detail_string()));
edump( (current_con->get_host()) (e.to_detail_string()) );
}
current_con->closed();

Expand Down Expand Up @@ -414,18 +409,6 @@ namespace fc { namespace http {
fc::promise<void>::ptr _closed;
};













typedef websocketpp::client<asio_with_stub_log> websocket_client_type;
typedef websocketpp::client<asio_tls_stub_log> websocket_tls_client_type;

Expand All @@ -443,7 +426,7 @@ namespace fc { namespace http {
_client.clear_access_channels( websocketpp::log::alevel::all );
_client.set_message_handler( [&]( connection_hdl hdl, message_ptr msg ){
_client_thread.async( [&](){
wdump((msg->get_payload()));
wdump( (_connection->get_host()) (msg->get_payload()) );
//std::cerr<<"recv: "<<msg->get_payload()<<"\n";
auto received = msg->get_payload();
fc::async( [=](){
Expand Down Expand Up @@ -503,7 +486,7 @@ namespace fc { namespace http {
_client.clear_access_channels( websocketpp::log::alevel::all );
_client.set_message_handler( [&]( connection_hdl hdl, message_ptr msg ){
_client_thread.async( [&](){
wdump((msg->get_payload()));
wdump( (_connection->get_host()) (msg->get_payload()) );
_connection->on_message( msg->get_payload() );
}).wait();
});
Expand Down Expand Up @@ -611,7 +594,9 @@ namespace fc { namespace http {

} // namespace detail

websocket_server::websocket_server():my( new detail::websocket_server_impl() ) {}
websocket_server::websocket_server(std::string host_header_key)
:my( new detail::websocket_server_impl(host_header_key) ) {}

websocket_server::~websocket_server(){}

void websocket_server::on_connection( const on_connection_handler& handler )
Expand All @@ -632,10 +617,10 @@ namespace fc { namespace http {
my->_server.start_accept();
}

websocket_tls_server::websocket_tls_server( const string& server_pem,
const string& ssl_password, std::string host_header_key )
:my( new detail::websocket_tls_server_impl(server_pem, ssl_password, host_header_key) ) {}



websocket_tls_server::websocket_tls_server( const string& server_pem, const string& ssl_password ):my( new detail::websocket_tls_server_impl(server_pem, ssl_password) ) {}
websocket_tls_server::~websocket_tls_server(){}

void websocket_tls_server::on_connection( const on_connection_handler& handler )
Expand Down Expand Up @@ -686,7 +671,7 @@ namespace fc { namespace http {

auto con = my->_client.get_connection( uri, ec );

if( ec ) FC_ASSERT( !ec, "error: ${e}", ("e",ec.message()) );
if( ec ) FC_ASSERT( !ec, "uri: ${uri} error: ${e}", ("uri", uri) ("e",ec.message()) );

my->_client.connect(con);
my->_connected->wait();
Expand All @@ -713,7 +698,7 @@ namespace fc { namespace http {

auto con = smy->_client.get_connection( uri, ec );
if( ec )
FC_ASSERT( !ec, "error: ${e}", ("e",ec.message()) );
FC_ASSERT( !ec, "uri: ${uri} error: ${e}", ("uri", uri) ("e",ec.message()) );
smy->_client.connect(con);
smy->_connected->wait();
return smy->_connection;
Expand All @@ -736,7 +721,7 @@ namespace fc { namespace http {
auto con = my->_client.get_connection( uri, ec );
if( ec )
{
FC_ASSERT( !ec, "error: ${e}", ("e",ec.message()) );
FC_ASSERT( !ec, "uri: ${uri} error: ${e}", ("uri", uri) ("e",ec.message()) );
}
my->_client.connect(con);
my->_connected->wait();
Expand Down
8 changes: 8 additions & 0 deletions tests/network/http/websocket_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@

#include <fc/network/http/websocket.hpp>

#include <fc/log/logger.hpp>
#include <fc/log/console_appender.hpp>

#include <iostream>

BOOST_AUTO_TEST_SUITE(fc_network)

BOOST_AUTO_TEST_CASE(websocket_test)
{
// set up logging
fc::shared_ptr<fc::console_appender> ca(new fc::console_appender);
fc::logger l = fc::logger::get("rpc");
l.add_appender(ca);

fc::http::websocket_client client;
fc::http::websocket_connection_ptr s_conn, c_conn;
int port;
Expand Down