Skip to content

Commit

Permalink
Make permessage-deflate status queryable in websocket::stream
Browse files Browse the repository at this point in the history
  • Loading branch information
britasys authored and ashtum committed Sep 1, 2024
1 parent a9121c2 commit 21545db
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/boost/beast/websocket/detail/impl_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,12 @@ struct impl_base<true>
result = clamp(result, rd_msg_max);
return result;
}

void
get_config_pmd(detail::pmd_offer &pmd)
{
pmd = pmd_config_;
}
};

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -495,6 +501,12 @@ struct impl_base<false>
result = clamp(result, rd_msg_max);
return result;
}

void
get_config_pmd(detail::pmd_offer &pmd)
{
pmd = {};
}
};

} // detail
Expand Down
12 changes: 12 additions & 0 deletions include/boost/beast/websocket/impl/stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ get_option(timeout& opt)
opt = impl_->timeout_opt;
}

template <class NextLayer, bool deflateSupported>
void
stream<NextLayer, deflateSupported>::
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<class NextLayer, bool deflateSupported>
void
stream<NextLayer, deflateSupported>::
Expand Down
37 changes: 37 additions & 0 deletions include/boost/beast/websocket/stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
55 changes: 55 additions & 0 deletions test/beast/websocket/handshake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<false> 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
Expand Down

0 comments on commit 21545db

Please sign in to comment.