beast
beast copied to clipboard
client-only permessage-deflate still sends server headers
I'm using boost 1.81 and beast to connect as a client to a remote websocket host, and with compression disabled, everything works fine.
This endpoint supports permessage-deflate from clients, and will also fail to upgrade if any server deflate headers are included.
If I try to add compression like so:
auto ret = std::make_shared<websocket_t>(io_ctx, ssl_ctx);
boost::beast::websocket::permessage_deflate pd_option{false, true};
ret->set_option(pd_option);
The upgrade headers still include server_max_window_bits, and the websocket upgrade is rejected. The issue seems to be in the translation between pd_option and beast's internal pmd_offer; the latter seems to support client and server at once only.
Attempts to set the server window size to 0 to prevent the field from being written (looking at the source of pmd_extension.ipp) yield an invalid value error.
Would it be possible for pmd_offer to respect the pd_option's server_enable flag and not send those headers?
Decorators do the job, but just feel super clunky since the option to use client or server compression was all ready specified.
// Set a decorator to manually modify the websocket upgrade request for one-sided PMD negotiation
ret->set_option(boost::beast::websocket::stream_base::decorator(
[pd_option](boost::beast::websocket::request_type& req) {
std::string deflate_header("permessage-deflate;");
if(pd_option.server_enable) {
deflate_header.append(" server_max_window_bits=");
deflate_header.append(std::to_string(pd_option.server_max_window_bits));
}
if(pd_option.client_enable) {
deflate_header.append(" client_max_window_bits=");
deflate_header.append(std::to_string(pd_option.client_max_window_bits));
}
req.set(boost::beast::http::field::sec_websocket_extensions, deflate_header);
}));
have you tried setting server_max_window_bits on the pd_option struct ?
@klemens-morgenstern yes, setting it to anything in a valid range has it sent as a header, and attempting to set it to an an invalid value gives beast errors about invalid values.
Aside from the decorator above, I'm not sure how to only send the client PMD header.
Sorry for the late response.
The decorator solves it?
While I can suppress the server headers with the decorator, it seems strange that they're sent at all when we specify no server headers in the permessage_deflate pd_option