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
asvetlov
left a comment
There was a problem hiding this comment.
I did not review carefully but left some notes.
| proxy=None, | ||
| proxy_auth=None): | ||
| proxy_auth=None, | ||
| compress=0): |
There was a problem hiding this comment.
Let's use compress=15 as initial value and don't accept True
aiohttp/client.py
Outdated
| 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.
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 |
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.
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
| if origin is not None: | ||
| headers[hdrs.ORIGIN] = origin | ||
| if compress: | ||
| if compress is True: |
There was a problem hiding this comment.
The check is not needed: let's assume compress is always integer.
asvetlov
left a comment
There was a problem hiding this comment.
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.
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.
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: |
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.
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.
Constructor from parent class is ok, isn't it?
Drop __init__ function.
docs/client_reference.rst
Outdated
| :param aiohttp.BasicAuth proxy_auth: an object that represents proxy HTTP | ||
| Basic Authorization (optional) | ||
|
|
||
| :param bool compress: Enable Per-Message Compress Extension support |
|
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.txtchangesfolder<issue_id>.<type>for example (588.bug)issue_idchange 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.