From be9b9dbdadd9d8e9c711639001a1f48d2671ab67 Mon Sep 17 00:00:00 2001 From: Saleh Hatefinya Date: Mon, 29 Jul 2024 22:16:42 +0330 Subject: [PATCH] Make permessage-deflate status queryable in websocket::stream --- .../beast/websocket/detail/impl_base.hpp | 12 ++++ include/boost/beast/websocket/impl/stream.hpp | 12 ++++ include/boost/beast/websocket/stream.hpp | 37 +++++++++++++ test/beast/websocket/handshake.cpp | 55 +++++++++++++++++++ 4 files changed, 116 insertions(+) diff --git a/include/boost/beast/websocket/detail/impl_base.hpp b/include/boost/beast/websocket/detail/impl_base.hpp index 62aa1675d7..667dfb1260 100644 --- a/include/boost/beast/websocket/detail/impl_base.hpp +++ b/include/boost/beast/websocket/detail/impl_base.hpp @@ -345,6 +345,12 @@ struct impl_base result = clamp(result, rd_msg_max); return result; } + + void + get_config_pmd(detail::pmd_offer &pmd) + { + pmd = pmd_config_; + } }; //------------------------------------------------------------------------------ @@ -495,6 +501,12 @@ struct impl_base result = clamp(result, rd_msg_max); return result; } + + void + get_config_pmd(detail::pmd_offer &pmd) + { + pmd = {}; + } }; } // detail diff --git a/include/boost/beast/websocket/impl/stream.hpp b/include/boost/beast/websocket/impl/stream.hpp index 7d43bbac2b..2c044ebdf4 100644 --- a/include/boost/beast/websocket/impl/stream.hpp +++ b/include/boost/beast/websocket/impl/stream.hpp @@ -175,6 +175,18 @@ get_option(timeout& opt) opt = impl_->timeout_opt; } +template +void +stream:: +get_status(permessage_deflate_status &status) const noexcept +{ + detail::pmd_offer pmd; + impl_->get_config_pmd(pmd); + status.active = pmd.accept; + status.client_window_bits = pmd.client_max_window_bits; + status.server_window_bits = pmd.server_max_window_bits; +} + template void stream:: diff --git a/include/boost/beast/websocket/stream.hpp b/include/boost/beast/websocket/stream.hpp index 64cab0e0d4..7dd307d714 100644 --- a/include/boost/beast/websocket/stream.hpp +++ b/include/boost/beast/websocket/stream.hpp @@ -38,6 +38,25 @@ namespace boost { namespace beast { namespace websocket { +/** permessage-deflate extension status. + + These settings indicate the status of the permessage-deflate + extension, showing if it is active and the window bits in use. + + Objects of this type are used with + @ref beast::websocket::stream::get_status. +*/ +struct permessage_deflate_status +{ + /// `true` if the permessage-deflate extension is active + bool active = false; + + /// The number of window bits used by the client + int client_window_bits = 0; + + /// The number of window bits used by the server + int server_window_bits = 0; +}; /** The type of received control frame. @@ -411,6 +430,24 @@ class stream void get_option(permessage_deflate& o); + /** Get the status of the permessage-deflate extension. + + Used to check the status of the permessage-deflate extension after + the WebSocket handshake. + + @param status A reference to a `permessage_deflate_status` object + where the status will be stored. + + @par Example + Checking the status of the permessage-deflate extension: + @code + permessage_deflate_status status; + ws.get_status(status); + @endcode + */ + void + get_status(permessage_deflate_status &status) const noexcept; + /** Set the automatic fragmentation option. Determines if outgoing message payloads are broken up into diff --git a/test/beast/websocket/handshake.cpp b/test/beast/websocket/handshake.cpp index 6d3b85965f..3ac501699c 100644 --- a/test/beast/websocket/handshake.cpp +++ b/test/beast/websocket/handshake.cpp @@ -136,6 +136,61 @@ class handshake_test : public websocket_test_suite } ts.close(); }); + + // handshake, deflate, supported + doStreamLoop([&](test::stream &ts) + { + echo_server es{log}; + ws_type ws{ts}; + ws.next_layer().connect(es.stream()); + response_type res; + try + { + websocket::permessage_deflate option{}; + option.client_enable = true; + option.client_max_window_bits = 14; + ws.set_option(option); + + w.handshake(ws, res, "localhost", "/"); + + websocket::permessage_deflate_status status; + ws.get_status(status); + BEAST_EXPECT(status.active); + BEAST_EXPECT(9 == status.server_window_bits); + BEAST_EXPECT(14 == status.client_window_bits); + } + catch(...) + { + ts.close(); + throw; + } + ts.close(); + }); + + // handshake, deflate, not supported + doStreamLoop([&](test::stream &ts) + { + echo_server es{log}; + ws_type_t ws{ts}; + ws.next_layer().connect(es.stream()); + response_type res; + try + { + w.handshake(ws, res, "localhost", "/"); + + websocket::permessage_deflate_status status; + ws.get_status(status); + BEAST_EXPECT(!status.active); + BEAST_EXPECT(0 == status.server_window_bits); + BEAST_EXPECT(0 == status.client_window_bits); + } + catch(...) + { + ts.close(); + throw; + } + ts.close(); + }); } void