Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Issue 1208473005: WebSocket Compression (Closed)

Created:
5 years, 6 months ago by kaendfinger
Modified:
5 years, 1 month ago
CC:
reviews_dartlang.org
Base URL:
https://github.com/dart-lang/sdk.git
Target Ref:
refs/heads/master
Visibility:
Public.

Description

Patch Set 1 #

Total comments: 16

Patch Set 2 : Take Suggestions #

Total comments: 5

Patch Set 3 : Take Suggestions #

Total comments: 7

Patch Set 4 : Provide all changes #

Patch Set 5 : Fix a lot of issues #

Patch Set 6 : Bug Fixes and Improvements #

Patch Set 7 : Format Code #

Patch Set 8 : Add Test #

Patch Set 9 : Remove Debugging Line #

Total comments: 18
Unified diffs Side-by-side diffs Delta from patch set Stats (+613 lines, -251 lines) Patch
M sdk/lib/io/websocket.dart View 1 2 3 4 5 6 9 chunks +128 lines, -14 lines 6 comments Download
M sdk/lib/io/websocket_impl.dart View 1 2 3 4 5 6 28 chunks +446 lines, -237 lines 9 comments Download
M tests/standalone/io/web_socket_test.dart View 1 2 3 4 5 6 7 8 2 chunks +39 lines, -0 lines 3 comments Download

Messages

Total messages: 13 (3 generated)
kaendfinger
5 years, 6 months ago (2015-06-24 19:35:43 UTC) #2
Søren Gjesse
Thanks for working on this. Here is the first round of comments. Please add some ...
5 years, 6 months ago (2015-06-25 15:41:27 UTC) #3
kaendfinger
5 years, 5 months ago (2015-07-03 01:47:43 UTC) #4
Søren Gjesse
https://codereview.chromium.org/1208473005/diff/20001/sdk/lib/io/websocket.dart File sdk/lib/io/websocket.dart (right): https://codereview.chromium.org/1208473005/diff/20001/sdk/lib/io/websocket.dart#newcode87 sdk/lib/io/websocket.dart:87: var header = "permessage-deflate"; Please add constants for all ...
5 years, 5 months ago (2015-07-03 13:14:55 UTC) #5
kaendfinger
5 years, 5 months ago (2015-07-11 18:11:12 UTC) #6
kustermann
Thanks for the update. Soeren is on vacation ATM. I tried to take a look, ...
5 years, 5 months ago (2015-07-20 09:34:12 UTC) #8
kaendfinger
On 2015/07/20 09:34:12, kustermann wrote: > Thanks for the update. Soeren is on vacation ATM. ...
5 years, 5 months ago (2015-07-20 18:02:29 UTC) #9
kaendfinger
5 years, 4 months ago (2015-07-28 18:28:35 UTC) #10
kaendfinger
I have written a test for WebSocket compression now. We are actually using it in ...
5 years, 4 months ago (2015-08-19 16:53:46 UTC) #11
Søren Gjesse
5 years, 4 months ago (2015-08-24 08:21:50 UTC) #13
In general this is looking very good. I have a number of comments in relation to
the header parsing, but when that is fixed this is ready to land.

One thing that would be really nice to test is the different header parameter
formatting, (white space, quoted/not quoted) e.g.

server_no_context_takeover;  server_max_window_bits =  "10"

That would require connecting a socket directly and building the headers like
_upgrade in websocket_impl.dart does in a test.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket.dart
File sdk/lib/io/websocket.dart (right):

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket.d...
sdk/lib/io/websocket.dart:80: * Create a Compression Header
Please add more documentation here on what requested is, and what is returned -
it doesn't just create a compression header.

As far as I can see if requested is not passed this generates a client request,
and if requested is passed it generates the server response.

Maybe add methods

String _createClientRequestHeader()
List _createServerResponseHeader(requested)

that forward to _createHeader.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket.d...
sdk/lib/io/websocket.dart:82: List _createHeader([List<String> requested]) {
Pass HeaderValue here and use its parameters (see comment in next file).

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket.d...
sdk/lib/io/websocket.dart:93: requested.contains("client_no_context_takeover")))
{
Please make the values "server_no_context_takeover" , "server_max_window_bits",
"client_max_window_bits" and "client_no_context_takeover" constants:

const String clientNoContextTakeover = "client_no_context_takeover";
...

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket.d...
sdk/lib/io/websocket.dart:104: requested.any((x) =>
x.startsWith("server_max_window_bits="))) {
This check is fragile, there can be WS on both sides of the = sign. See comments
in next file on parsing parameters.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket.d...
sdk/lib/io/websocket.dart:109: ? int.parse(part,
According to
https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-27 the value
must not have leading zeros.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket.d...
sdk/lib/io/websocket.dart:111: : serverMaxWindowBits;
You also need to check for the allowed range 8-15.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
File sdk/lib/io/websocket_impl.dart (right):

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:115: var rsv = (byte & 0x70) >> 4;
I don't think this temp is required - see below.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:117: if (rsv != 0 && rsv != 4) {
Please use

  if ((byte & (RSV1 | RSV2)) != 0)

to test against the defined mask bits

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:118: // The RSV1, RSV2 bits RSV3 must be all
zero.
Please remove RSV3 from this comment.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:122: if (rsv == 4) {
Please use

  if ((byte & RSV3) != 0) {

to test against the defined mask bit

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:127: _opcode = (byte & 0x0F);
Please use the new constant OPCODE here.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:464: extensionHeader.split(",").map((it) =>
it.split("; "));
Both the splitting using "," and "; " seems fragile. The "," could be inside a
quoted parameter value, and separation with just ";" is also OK.

We do have the problem with dart:io parsing into HttpHeader that the ","
splitting is not performed by default. For now please add a TODO that the ","
splitting should do proper parsing of multiple header values.

For the parsing of parameters I think you can just use the HeaderValue parameter
parsing:

  var value = HeaderValue.parse(s);

the value.parameters has the parameter map.

There is one slight issue with this, and that is that the current HeaderValue
parser requires the format 'x=1' - it does not support just 'x'. That should be
simple to add to http_headers.dart (around line 747) to check for either '=' or
';' and give a value of null when there is no value.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:529: {this.clientMaxWindowBits,
nit: Please indent like this (one space more for the lines under the {-line).

    {this.clientMaxWindowBits,
     this.serverMaxWindowBits,
     this.serverNoContextTakeover: false,

...

There are more places like this.

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:719: header[index++] = hoc;
Just set this byte like this (no need to the rsv and hoc temps):

header[index++] = FIN | compressed ? RSV3 : 0 | opcode

https://codereview.chromium.org/1208473005/diff/180001/sdk/lib/io/websocket_i...
sdk/lib/io/websocket_impl.dart:1037: extensionHeader.split(", ").map((it) =>
it.split("; "));
Please see above (comment on _negoatiateCompression) on the parsing of the
header.

https://codereview.chromium.org/1208473005/diff/180001/tests/standalone/io/we...
File tests/standalone/io/web_socket_test.dart (right):

https://codereview.chromium.org/1208473005/diff/180001/tests/standalone/io/we...
tests/standalone/io/web_socket_test.dart:552: 
Please create a new test file web_socket_compression_test.dart (just copy
createServer and other helpers needed).

https://codereview.chromium.org/1208473005/diff/180001/tests/standalone/io/we...
tests/standalone/io/web_socket_test.dart:553: void testCompressionSupport(bool
enabled, bool allowContextTakeover) {
Please add tests involving the max_window_bits as well.

https://codereview.chromium.org/1208473005/diff/180001/tests/standalone/io/we...
tests/standalone/io/web_socket_test.dart:564:
WebSocketTransformer.upgrade(request, compression: options).then((webSocket) {
nit: Long line.

Powered by Google App Engine
This is Rietveld 408576698