diff --git a/doc/rippled-example.cfg b/doc/rippled-example.cfg index bc364cb8b..54c311e84 100644 --- a/doc/rippled-example.cfg +++ b/doc/rippled-example.cfg @@ -273,7 +273,41 @@ # keep rippled from connecting to other instances of rippled or # prevent RPC and WebSocket clients from connecting. # +# WebSocket permessage-deflate extension options # +# These settings configure the optional permessage-deflate extension +# options and may appear on any port configuration entry. They are meaningful +# only to ports which have enabled a WebSocket protocol. +# +# permessage_deflate = +# +# Determines if permessage_deflate extension negotiations are enabled. +# When enabled, clients may request the extension and the server will +# offer the enabled extension in response. +# +# client_max_window_bits = [9..15] +# server_max_window_bits = [9..15] +# client_no_context_takeover = +# server_no_context_takeover = +# +# These optional settings control options related to the permessage-deflate +# extension negotiation. For precise definitions of these fields please see +# the RFC 7692, "Compression Extensions for WebSocket": +# https://tools.ietf.org/html/rfc7692 +# +# compress_level = [0..9] +# +# When set, determines the amount of compression attempted, where 0 is +# the least amount and 9 is the most amount. Higher levels require more +# CPU resources. Levels 1 through 3 use a fast compression algorithm, +# while levels 4 through 9 use a more compact algorithm which uses more +# CPU resources. If unspecified, a default of 3 is used. +# +# memory_level = [1..9] +# +# When set, determines the relative amount of memory used to hold +# intermediate compression data. Higher numbers can give better compression +# ratios at the cost of higher memory and CPU resources. # # [rpc_startup] # diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index 984607c30..6e7132387 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -830,6 +830,7 @@ to_Port(ParsedPort const& parsed, std::ostream& log) p.ssl_cert = parsed.ssl_cert; p.ssl_chain = parsed.ssl_chain; p.ssl_ciphers = parsed.ssl_ciphers; + p.pmd_options = parsed.pmd_options; return p; } diff --git a/src/ripple/server/Port.h b/src/ripple/server/Port.h index 4f06bdc27..b6b2bc8fa 100644 --- a/src/ripple/server/Port.h +++ b/src/ripple/server/Port.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ struct Port std::string ssl_cert; std::string ssl_chain; std::string ssl_ciphers; + beast::websocket::permessage_deflate pmd_options; std::shared_ptr context; // How many incoming connections are allowed on this @@ -83,6 +85,7 @@ struct ParsedPort std::string ssl_cert; std::string ssl_chain; std::string ssl_ciphers; + beast::websocket::permessage_deflate pmd_options; int limit = 0; boost::optional ip; diff --git a/src/ripple/server/impl/BaseWSPeer.h b/src/ripple/server/impl/BaseWSPeer.h index cbc5c6243..a1acb8e33 100644 --- a/src/ripple/server/impl/BaseWSPeer.h +++ b/src/ripple/server/impl/BaseWSPeer.h @@ -110,7 +110,7 @@ protected: { template void - operator()(beast::http::message& req) + operator()(beast::http::message& req) const { req.fields.replace("User-Agent", BuildInfo::getFullVersionString()); @@ -118,7 +118,7 @@ protected: template void - operator()(beast::http::message& resp) + operator()(beast::http::message& resp) const { resp.fields.replace("Server", BuildInfo::getFullVersionString()); @@ -194,6 +194,7 @@ run() return strand_.post(std::bind( &BaseWSPeer::run, impl().shared_from_this())); impl().ws_.set_option(beast::websocket::decorate(identity{})); + impl().ws_.set_option(port().pmd_options); using namespace beast::asio; impl().ws_.async_accept(request_, strand_.wrap(std::bind( &BaseWSPeer::on_ws_handshake, impl().shared_from_this(), diff --git a/src/ripple/server/impl/Port.cpp b/src/ripple/server/impl/Port.cpp index 457a19d29..b574af160 100644 --- a/src/ripple/server/impl/Port.cpp +++ b/src/ripple/server/impl/Port.cpp @@ -217,6 +217,21 @@ parse_Port (ParsedPort& port, Section const& section, std::ostream& log) set(port.ssl_cert, "ssl_cert", section); set(port.ssl_chain, "ssl_chain", section); set(port.ssl_ciphers, "ssl_ciphers", section); + + port.pmd_options.server_enable = + section.value_or("permessage_deflate", false); + port.pmd_options.client_max_window_bits = + section.value_or("client_max_window_bits", 15); + port.pmd_options.server_max_window_bits = + section.value_or("server_max_window_bits", 15); + port.pmd_options.client_no_context_takeover = + section.value_or("client_no_context_takeover", false); + port.pmd_options.server_no_context_takeover = + section.value_or("server_no_context_takeover", false); + port.pmd_options.compLevel = + section.value_or("compress_level", 3); + port.pmd_options.memLevel = + section.value_or("memory_level", 4); } } // ripple