-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add permessage-deflate
support, again
#426
base: master
Are you sure you want to change the base?
Conversation
This causes the library not to build. This reverts commit 42b8797.
Still doesn't build.
Re-implements a couple of internal utilities from the header crate. Also makes some changes to the SecWebsocketExtensions code. The build is fixed again, tests pass.
I will be happy to go through the details of the permessage-deflate spec – or rather even fix the bug myself, while some missing window bits support. However, the bug is extremely niche as these extension fields are very rarely used, so I'd prefer to try to get this merged and then do an improvement pull on top of that. |
@kazk Would you be willing to relicense your PR under the MIT + Apache dual license as used by this crate? If not, I believe we can use the code under MIT + Apache anyways, as long as we add a
Additionaly, we would probably have to add "Copyright (c) 2014-2023 Sean McArthur" to |
What's the status of this pr? |
I forgot about it, sorry. I'd like to modify it to meet the necessary licensing obligations, which shouldn't be too hard. |
I'm not a lawyer, but I think that the notices I've to the license files should be compliant with all relevant licenses. As such, this PR is now ready for review! 🥳 Sorry for the delay. |
I apologize for the delay.
Yes, you can do whatever is necessary for what I did :) |
kazk has agreed to relicense his original PR under MIT+Apache, which means we don't have to add extra notices to our license files. This reverts commit 049c753.
Glad to see it still going on, thanks your great work @SvizelPritula @kazk . So are there any other problems pending this? Sorry for disturbing, but seems that I should ping you @nakedible-p @daniel-abramov . |
I remember I checked #328 back then, and it seems like there are many common parts (back then it was reverted due to dependencies. So yeah, I'm not against merging it. I'd also appreciate it if someone who tracked the issue could approve it, though (to ensure that I did not miss anything since I did not go as thoroughly through all the changes as I typically try to do). |
We have been running a copy of this branch for couple of weeks now in production, at least in the standard cases it seems to work good, both directions server client and client server, different languages clients connect to the server. |
This sounds pretty good! It's always good to know that someone tested it in production! @SvizelPritula, would you be interested in rebasing on top of a |
@daniel-abramov @SvizelPritula just checking in. Is there anything else that needs to be done before this branch can be merged? |
I've merged this branch with |
Just checking in if there are any updates on this PR? |
The tests are now fixed, everything should be working. Sorry for taking so long, I was busy with exams. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update!
I had to quickly go through the changes again (albeit skipping all deflate-specific logic) as I keep forgetting the things between reviews (the PR is pretty large).
Generally it looks good, I'm only a bit concerned with a slightly more complicated logic in protocol/**
(we have more branching and more conditions), but making it better would possibly require a bigger overhaul.
I also decided to run our benchmarks locally and it seems like this version is somewhat slower than the version in master
when it comes to reading. I consistently get a regression of around 15-17%.
read+unmask 100k small messages (server)
time: [6.6915 ms 6.7087 ms 6.7273 ms]
change: [+14.968% +15.822% +16.508%] (p = 0.00 < 0.05)
Performance has regressed.
Found 17 outliers among 100 measurements (17.00%)
6 (6.00%) low mild
5 (5.00%) high mild
6 (6.00%) high severe
read 100k small messages (client)
time: [6.4633 ms 6.4821 ms 6.5024 ms]
change: [+17.048% +17.722% +18.370%] (p = 0.00 < 0.05)
Performance has regressed.
Found 4 outliers among 100 measurements (4.00%)
3 (3.00%) high mild
1 (1.00%) high severe
Unfortunately, I did not have time to dig in and investigate the root causes, but I assume that it might be related to the changes around IncompleteMessage
/ extend_incomplete()
, and/or handling of OpData::Continue
.
autobahn/client/ | ||
autobahn/server/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
autobahn/client/ | |
autobahn/server/ |
Probably leftovers from a local testing? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those folders contain the test results after running scripts/autobahn-client.sh
or scripts/autobahn-server.sh
. Those shouldn't be commited, so I added them to .gitignore
.
src/protocol/mod.rs
Outdated
.as_mut() | ||
.and_then(|x| x.compression.as_mut()) | ||
.unwrap() | ||
.decompress(payload.to_vec(), fin)? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this involves copying the data which might get expensive. Since the original payload
is not required after the decompression, it's probably better to use into()
to directly convert it into Vec<u8>
.
Removes unused code from a test and fixes a typo in a comment. Co-authored-by: Daniel Abramov <inetcrack2@gmail.com>
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. We would need to add a proper license notice, or @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.