Add permessage-deflate
support, again
#426
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In #328, @kazk implemented support for the
permessage-deflate
extention. Implementing this extention required the ability to parse theSec-Websocket-Extentions
header, so @kazk submitted a pull request to theheaders
crate. However, the maintainers of theheaders
crate don't wan't to support this header yet, as they don't wan't to commit to any particular API. As such, they suggested that it should be implemented in this or some other crate, tweaked as necessary and potentially moved into theheaders
crate in the future.This PR reverts the commit that reverted @kazk's commit that added
permessage-deflate
support. It also copies his implementation ofSecWebsocketExtentions
intended for theheaders
crate.The implementation of
SecWebsocketExtentions
relied on some internal utilities of theheaders
crate. I've removed some of those dependencies and re-implemented others. I have also gated the implementation behind the existinghandshake
feature, as well as any code that relies on it, since it relies on theheaders
crate, which in turn relies on many other HTTP crates.Blocking issues
headers
crate is licensed under the MIT license, while this crate uses a dual MIT+Apache license. Assuming we don't want to change the license on this crate, @kazk would need to consent to the re-licensing of his PR.Unresolved questions
deflate
feature without havingtungstenite
handle the Websocket handshake. There is aWebSocket::from_raw_socket_with_extensions
method to allow for exactly that, but it takes anExtensions
struct, which has no public constructor.WebSocketConfig::accept_offers
method, which implements the server part of extension negotiation and requires thehandshake
feature. This method is intended to allow fortungstenite
to be integrated into web frameworks. No similar public method exists for clients, although that might not be a big issue, since a client knows whether a request will be a Websocket request up front.WebSocketConfig::accept_offers
feels out of place on theWebSocketConfig
. We could make it a standalone function, perhaps in theextensions
module.SecWebsocketExtentions
implementation public. This is necessary to make theWebSocketConfig::accept_offers
method usable. This does mean that ifSecWebsocketExtentions
were to be added toheaders
in the future, switching to that implementation would (I think) be a breaking change. An alternative would be to haveWebSocketConfig::accept_offers
take and return aHeaderValue
, which it would parse itself. This would allow us to makeSecWebsocketExtentions
a private implementation detail.WebSocketConfig
and a new variant was added to theError
enum. Since this field and variant depends on thedeflate
feature, I've annotated both with#[non_exhaustive]
. I've done the same toProtocolError
, which currently has variants gated behindhandshake
. This sadly means that you cannot createWebSocketConfig
using the initializer syntax, instead you have to create an instance withWebSocketConfig::default
and mutate it afterward. Sadly, I see no way to avoid this. It would be possible to disable#[non_exhaustive]
if all relevant features are enabled.