mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
adds connection client methods for adding subprotocols to the handshake request
This commit is contained in:
@@ -36,7 +36,7 @@ Implimented, needs more testing
|
||||
- exception/error handling
|
||||
- Logging
|
||||
- Client role
|
||||
- Server subprotocol negotiation
|
||||
- Subprotocol negotiation
|
||||
|
||||
Implimented, API not finalized
|
||||
- open_handler
|
||||
@@ -46,7 +46,6 @@ Implimented, API not finalized
|
||||
|
||||
Needs work:
|
||||
- PowerPC support
|
||||
- Client subprotocol negotiation
|
||||
- Extension support
|
||||
- permessage_compress extension
|
||||
- Visual Studio / Windows support
|
||||
|
||||
@@ -133,7 +133,63 @@ BOOST_AUTO_TEST_CASE( connect_con ) {
|
||||
channel2 >> *con;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( select_subprotocol ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
using websocketpp::error::make_error_code;
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
|
||||
BOOST_CHECK( con );
|
||||
|
||||
con->select_subprotocol("foo",ec);
|
||||
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::server_only) );
|
||||
BOOST_CHECK_THROW( con->select_subprotocol("foo") , websocketpp::lib::error_code );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( add_subprotocols_invalid ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
using websocketpp::error::make_error_code;
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
BOOST_CHECK( con );
|
||||
|
||||
con->add_subprotocol("",ec);
|
||||
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::invalid_subprotocol) );
|
||||
BOOST_CHECK_THROW( con->add_subprotocol("") , websocketpp::lib::error_code );
|
||||
|
||||
con->add_subprotocol("foo,bar",ec);
|
||||
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::invalid_subprotocol) );
|
||||
BOOST_CHECK_THROW( con->add_subprotocol("foo,bar") , websocketpp::lib::error_code );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( add_subprotocols ) {
|
||||
client c;
|
||||
websocketpp::lib::error_code ec;
|
||||
std::stringstream out;
|
||||
std::string o;
|
||||
|
||||
c.register_ostream(&out);
|
||||
|
||||
connection_ptr con = c.get_connection("ws://localhost/", ec);
|
||||
BOOST_CHECK( con );
|
||||
|
||||
con->add_subprotocol("foo",ec);
|
||||
BOOST_CHECK( !ec );
|
||||
|
||||
BOOST_CHECK_NO_THROW( con->add_subprotocol("bar") );
|
||||
|
||||
c.connect(con);
|
||||
|
||||
o = out.str();
|
||||
websocketpp::http::parser::request r;
|
||||
r.consume(o.data(),o.size());
|
||||
|
||||
std::cout << o << std::endl;
|
||||
|
||||
BOOST_CHECK( r.ready() );
|
||||
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "foo, bar");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,11 +39,11 @@
|
||||
#include <websocketpp/processors/processor.hpp>
|
||||
#include <websocketpp/transport/base/connection.hpp>
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
@@ -542,6 +542,35 @@ public:
|
||||
*/
|
||||
const std::vector<std::string> & get_requested_subprotocols() const;
|
||||
|
||||
/// Adds the given subprotocol string to the request list (exception free)
|
||||
/**
|
||||
* Adds a subprotocol to the list to send with the opening handshake. This
|
||||
* may be called multiple times to request more than one. If the server
|
||||
* supports one of these, it may choose one. If so, it will return it
|
||||
* in it's handshake reponse and the value will be available via
|
||||
* get_subprotocol(). Subprotocol requests should be added in order of
|
||||
* preference.
|
||||
*
|
||||
* @param request The subprotocol to request
|
||||
*
|
||||
* @param ec A reference to an error code that will be filled in the case of
|
||||
* errors
|
||||
*/
|
||||
void add_subprotocol(const std::string &request, lib::error_code & ec);
|
||||
|
||||
/// Adds the given subprotocol string to the request list
|
||||
/**
|
||||
* Adds a subprotocol to the list to send with the opening handshake. This
|
||||
* may be called multiple times to request more than one. If the server
|
||||
* supports one of these, it may choose one. If so, it will return it
|
||||
* in it's handshake reponse and the value will be available via
|
||||
* get_subprotocol(). Subprotocol requests should be added in order of
|
||||
* preference.
|
||||
*
|
||||
* @param request The subprotocol to request
|
||||
*/
|
||||
void add_subprotocol(const std::string &request);
|
||||
|
||||
/// Select a subprotocol to use (exception free)
|
||||
/**
|
||||
* Indicates which subprotocol should be used for this connection. Valid
|
||||
@@ -549,6 +578,8 @@ public:
|
||||
* been requested by the client. Consult get_requested_subprotocols() for a
|
||||
* list of valid subprotocols.
|
||||
*
|
||||
* This member function is valid on server endpoints/connections only
|
||||
*
|
||||
* @param value The subprotocol to select
|
||||
*
|
||||
* @param ec A reference to an error code that will be filled in the case of
|
||||
@@ -563,6 +594,8 @@ public:
|
||||
* been requested by the client. Consult get_requested_subprotocols() for a
|
||||
* list of valid subprotocols.
|
||||
*
|
||||
* This member function is valid on server endpoints/connections only
|
||||
*
|
||||
* @param value The subprotocol to select
|
||||
*/
|
||||
void select_subprotocol(const std::string & value);
|
||||
|
||||
@@ -77,6 +77,9 @@ enum value {
|
||||
/// Invalid UTF-8
|
||||
invalid_utf8,
|
||||
|
||||
/// Invalid subprotocol
|
||||
invalid_subprotocol,
|
||||
|
||||
/// Bad or unknown connection
|
||||
bad_connection,
|
||||
|
||||
@@ -87,7 +90,13 @@ enum value {
|
||||
con_creation_failed,
|
||||
|
||||
/// Selected subprotocol was not requested by the client
|
||||
unrequested_subprotocol
|
||||
unrequested_subprotocol,
|
||||
|
||||
/// Attempted to use a client specific feature on a server endpoint
|
||||
client_only,
|
||||
|
||||
/// Attempted to use a server specific feature on a client endpoint
|
||||
server_only,
|
||||
}; // enum value
|
||||
|
||||
|
||||
@@ -125,6 +134,8 @@ public:
|
||||
return "Extracted close code is in a reserved range";
|
||||
case error::invalid_utf8:
|
||||
return "Invalid UTF-8";
|
||||
case error::invalid_subprotocol:
|
||||
return "Invalid subprotocol";
|
||||
case error::bad_connection:
|
||||
return "Bad Connection";
|
||||
case error::test:
|
||||
@@ -133,6 +144,10 @@ public:
|
||||
return "Connection creation attempt failed";
|
||||
case error::unrequested_subprotocol:
|
||||
return "Selected subprotocol was not requested by the client";
|
||||
case error::client_only:
|
||||
return "Feature not available on server endpoints";
|
||||
case error::server_only:
|
||||
return "Feature not available on client endpoints";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@@ -327,10 +327,45 @@ connection<config>::get_requested_subprotocols() const {
|
||||
return m_requested_subprotocols;
|
||||
}
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::add_subprotocol(const std::string & value,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
if (m_is_server) {
|
||||
ec = error::make_error_code(error::client_only);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the value is empty or has a non-RFC2616 token character it is invalid.
|
||||
if (value.empty() || std::find_if(value.begin(),value.end(),
|
||||
http::is_not_token_char) != value.end())
|
||||
{
|
||||
ec = error::make_error_code(error::invalid_subprotocol);
|
||||
return;
|
||||
}
|
||||
|
||||
m_requested_subprotocols.push_back(value);
|
||||
}
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::add_subprotocol(const std::string & value) {
|
||||
lib::error_code ec;
|
||||
this->add_subprotocol(value,ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::select_subprotocol(const std::string & value,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
if (!m_is_server) {
|
||||
ec = error::make_error_code(error::server_only);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.empty()) {
|
||||
ec = lib::error_code();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user