-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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 initial support for PerMessage Deflate #2273
Conversation
this is good! but could you add unit and functional tests |
Add no takeover extension to server and client.
TODO: add tests
The file upload tests in |
Codecov Report
@@ Coverage Diff @@
## master #2273 +/- ##
==========================================
- Coverage 97.24% 97.24% -0.01%
==========================================
Files 39 39
Lines 8096 8201 +105
Branches 1411 1439 +28
==========================================
+ Hits 7873 7975 +102
- Misses 97 98 +1
- Partials 126 128 +2
Continue to review full report at Codecov.
|
Add parser test for rsv1
Client deflate support should now more complete fix linting
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.
I did not review carefully but left some notes.
@@ -380,7 +384,8 @@ def _ws_connect(self, url, *, | |||
origin=None, | |||
headers=None, | |||
proxy=None, | |||
proxy_auth=None): | |||
proxy_auth=None, | |||
compress=0): |
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.
Let's use compress=15
as initial value and don't accept True
aiohttp/client.py
Outdated
@@ -26,6 +26,8 @@ | |||
from .helpers import (PY_35, CeilTimeout, TimeoutHandle, _BaseCoroMixin, | |||
deprecated_noop, sentinel) | |||
from .http import WS_KEY, WebSocketReader, WebSocketWriter | |||
from .http_websocket import extensions_gen as ws_ext_gen |
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.
Why do you rename imports?
Just use ws_ext_gen
and ws_ext_parse
in http_websocket.py
.
aiohttp/http_websocket.py
Outdated
client_notakeover=False): | ||
# compress wbit 8 does not support in zlib | ||
if compress < 9 or compress > 15: | ||
return False |
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.
Raise ValueError
here.
aiohttp/http_websocket.py
Outdated
for ext in extensions: | ||
if ext.startswith('permessage-deflate'): | ||
compress = 15 | ||
for param in [s.strip() for s in ext.split(';')][1:]: |
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.
I believe regex parse is more robust.
Fix client code Add more tests
If reader created with compress=0, it will raise PROTOCOL_ERROR if rvb1 = 1.
aiohttp/client.py
Outdated
@@ -420,6 +424,11 @@ def _ws_connect(self, url, *, | |||
headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ','.join(protocols) | |||
if origin is not None: | |||
headers[hdrs.ORIGIN] = origin | |||
if compress: | |||
if compress is True: |
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.
The check is not needed: let's assume compress
is always integer.
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.
Sorry for non-instant review.
The PR is complex, the RFC https://tools.ietf.org/html/rfc7692 is complicated.
Everything looks good but please fix my notes.
Also please make https://codecov.io/gh/aio-libs/aiohttp/pull/2273/diff green.
The PR changes default websockets behavior, I have a feeling that is very important change
aiohttp/http_websocket.py
Outdated
if compress < 9 or compress > 15: | ||
raise ValueError('Compress wbits must between 9 and 15, ' | ||
'zlib does not support wbits=8') | ||
enabledext = None |
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.
Please use a list: enabledext = []
.
Append an element to the list every time if needed.
Return '; '.join(enabledext)
-- or just a list maybe, do joining in caller.
Join is recommended way for performing such operations, it's faster and more memory effective.
Take a look on https://github.com/python/cpython/blob/master/Lib/asyncio/base_futures.py#L54-L71 for inspiration
aiohttp/client.py
Outdated
) | ||
if compress == 0: | ||
pass | ||
elif compress == -1: |
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.
I could live with this code style but it looks too C-ish.
What's about raising internal HandshakeError
exception defined in http_websocket.py
as
class HandshakeError(Exception):
pass
try:
raise HandshakeError('Invalid window size')
except HandshakeError as exc:
raise WSServerHandshakeError(
resp.request_info,
resp.history,
message=exc.args[0],
code=resp.status,
headers=resp.headers)
Using exception instead of return value.
aiohttp/client.py
Outdated
compress, notakeover = ws_ext_parse( | ||
resp.headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] | ||
) | ||
if compress == 0: |
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.
What the check does?
aiohttp/client.py
Outdated
# websocket compress | ||
notakeover = False | ||
if compress: | ||
if hdrs.SEC_WEBSOCKET_EXTENSIONS in resp.headers: |
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.
Use resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)
, do getting the header only once.
aiohttp/http_websocket.py
Outdated
class WSHandshakeError(Exception): | ||
"""WebSocket protocol handshake error.""" | ||
|
||
def __init__(self, message): |
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.
Constructor from parent class is ok, isn't it?
Drop __init__
function.
docs/client_reference.rst
Outdated
@@ -524,6 +524,8 @@ The client session supports the context manager protocol for self closing. | |||
:param aiohttp.BasicAuth proxy_auth: an object that represents proxy HTTP | |||
Basic Authorization (optional) | |||
|
|||
:param bool compress: Enable Per-Message Compress Extension support |
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.
Update method signature too.
Last question: should we enable websockets by default? |
I think we can disable compression for client side by default, maybe need more test with other server software to make sure they are compatible. |
@fanthos sounds good |
|
Disable websocket compression on client side by default
Thanks! |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a [new issue] for related bugs. |
What do these changes do?
Add initial support for WebSocket deflate compress.
Right now both server and client are supported.
Are there changes in behavior for the user?
No
Related issue number
#673
Checklist
CONTRIBUTORS.txt
changes
folder<issue_id>.<type>
for example (588.bug)issue_id
change it to the pr id after creating the pr.feature
: Signifying a new feature..bugfix
: Signifying a bug fix..doc
: Signifying a documentation improvement..removal
: Signifying a deprecation or removal of public API..misc
: A ticket has been closed, but it is not of interest to users.