-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Implement WebSocket API #2088
Implement WebSocket API #2088
Conversation
test/web-platform-tests/to-run.yaml
Outdated
Secure-Close-1005-verify-code.htm: [fail, See https://github.com/websockets/ws/issues/1257] | ||
closing-handshake/003.html*: [fail, See https://github.com/websockets/ws/issues/1257] | ||
interfaces/WebSocket/close/close-basic.html*: [fail, Mutates globals] | ||
interfaces/WebSocket/close/close-connecting.html*: [fail, Potentially buggy test as Chrome fails it too] |
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.
Firefox doesn’t fail it locally, however (even though wpt.fyi says otherwise). Fixing it seems to require digging through ws module's guts, which I didn't do.
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.
This assertion fails in ws if close()
is called when connecting as the 'close'
event is emitted on the same tick.
This patch should fix the issue:
diff --git a/lib/websocket.js b/lib/websocket.js
index e0ed7c5..0730510 100644
--- a/lib/websocket.js
+++ b/lib/websocket.js
@@ -152,8 +152,6 @@ class WebSocket extends EventEmitter {
this._closeMessage = reason;
this._closeCode = code;
- if (this._finalized) return;
-
if (code === 1005) this.close();
else this.close(code, reason);
};
@@ -213,15 +211,14 @@ class WebSocket extends EventEmitter {
* @private
*/
emitClose () {
- this.readyState = WebSocket.CLOSED;
-
- this.emit('close', this._closeCode, this._closeMessage);
-
if (this._extensions[PerMessageDeflate.extensionName]) {
this._extensions[PerMessageDeflate.extensionName].cleanup();
}
- this.removeAllListeners();
+ process.nextTick(() => {
+ this.readyState = WebSocket.CLOSED;
+ this.emit('close', this._closeCode, this._closeMessage);
+ });
}
/**
@@ -282,7 +279,9 @@ class WebSocket extends EventEmitter {
}
if (this.readyState === WebSocket.CLOSING) {
- if (this._closeFrameSent && this._closeFrameReceived) this._socket.end();
+ if (this._closeFrameSent && this._closeFrameReceived && !this._finalized) {
+ this._socket.end();
+ }
return;
}
Let me know if you need it or open a PR :)
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 patch does not fix the issue, unfortunately :( Seems like the actual error thrown is
Error: Parse Error
at Socket.socketOnData (_http_client.js:439:20)
at Socket.emit (events.js:159:13)
at addChunk (_stream_readable.js:265:12)
at readableAddChunk (_stream_readable.js:252:11)
at Socket.Readable.push (_stream_readable.js:209:10)
at TCP.onread (net.js:608:20)
I assume we can't do much about this.
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.
Hmm this is weird.
|
||
DIR: websockets | ||
|
||
Create-Secure-extensions-empty.htm: [fail, Buggy test as the test does not take into account the mandatory permessage-deflate extension] |
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.
All browsers fail this test, with Chrome and Firefox failing the same way we do: https://wpt.fyi/websockets/Create-Secure-extensions-empty.htm
test/web-platform-tests/to-run.yaml
Outdated
|
||
Create-Secure-extensions-empty.htm: [fail, Buggy test as the test does not take into account the mandatory permessage-deflate extension] | ||
Secure-Close-1005-verify-code.htm: [fail, See https://github.com/websockets/ws/issues/1257] | ||
closing-handshake/003.html*: [fail, See https://github.com/websockets/ws/issues/1257] |
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.
These two have a chance of being fixed upstream soon. See linked ticket.
test/web-platform-tests/to-run.yaml
Outdated
Create-Secure-extensions-empty.htm: [fail, Buggy test as the test does not take into account the mandatory permessage-deflate extension] | ||
Secure-Close-1005-verify-code.htm: [fail, See https://github.com/websockets/ws/issues/1257] | ||
closing-handshake/003.html*: [fail, See https://github.com/websockets/ws/issues/1257] | ||
interfaces/WebSocket/close/close-basic.html*: [fail, Mutates globals] |
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.
This test passes because we implement things correctly, but because the wrappers are shared across JSDOM windows it will affect the next test, thus causing failures. (This one was a pain to debug as one can imagine.)
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 know at least one more test which behaves this way, though it's among the CSSOM tests and not included here yet. Annoying to debug, indeed.
Since we eventually want to run most failing tests to make sure that they're still failing, we ought to add a new failure reason ([mutates-globals]
or something more general?) for these tests to make sure they won't ever run and affect others later. That doesn't need to be done in this pull request though.
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.
Agreed on all counts.
We also need a new failure reason for flaky tests. I experienced one of them while auditing which tests we could enable after the WPT roll.
Also it'd be good to add a WPT for the first commit. |
6ed777e
to
f19090d
Compare
Comments addressed. WPT rolled. #1559 fixed. Travis is green. This PR is ready for review :) |
This is so great to see, thank you @TimothyGu. Wish I could be of help in review, I'll just watch and learn from this one. |
resolve(); | ||
this._onConnectionClosed(...args); | ||
}); | ||
this._ws.on("headers", 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.
This will be renamed to 'upgrade'
in version 4. Listeners will receive the http.IncomingMessage
instance.
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.
Great work, I can only offer nitpicks.
While not directly related to your code, I notice that the WPT Python server becomes rather noisy during the WebSocket tests. I wonder if we can do something about that without silencing potentially useful information.
Regardless, LGTM :-)
// Event's constructor assumes all options correspond to IDL attributes with the same names, and sets them on `this`. | ||
// That is not the case for these modifier boolean options, but since the options are set on `this` anyway we'll | ||
// access them that way. The spec doesn't say much about the case where keyArg is not one of the valid ones | ||
// (https://www.w3.org/TR/uievents-key/#keys-modifier), but at least Chrome returns false for invalid modifiers. Since |
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 think we always try to reference the latest available version of a spec even if that means a draft, so this should probably be https://w3c.github.io/uievents-key/#keys-modifier instead.
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.
Yup, my bad.
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.
Bump, in case this was missed.
test/web-platform-tests/to-run.yaml
Outdated
Create-Secure-extensions-empty.htm: [fail, Buggy test as the test does not take into account the mandatory permessage-deflate extension] | ||
Secure-Close-1005-verify-code.htm: [fail, See https://github.com/websockets/ws/issues/1257] | ||
closing-handshake/003.html*: [fail, See https://github.com/websockets/ws/issues/1257] | ||
interfaces/WebSocket/close/close-basic.html*: [fail, Mutates globals] |
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 know at least one more test which behaves this way, though it's among the CSSOM tests and not included here yet. Annoying to debug, indeed.
Since we eventually want to run most failing tests to make sure that they're still failing, we ought to add a new failure reason ([mutates-globals]
or something more general?) for these tests to make sure they won't ever run and affect others later. That doesn't need to be done in this pull request though.
@@ -0,0 +1,35 @@ | |||
<!DOCTYPE html> | |||
<html dir="rtl"> |
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.
Is the "rtl"-direction relevant here, or merely the result of copy-paste?
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.
It was a copypasta issue 😕 thanks for spotting!
Hey @Zirro, thanks for the review. I’ll fix the issues as soon as I fully wake up. @lpinca thanks for giving us the heads-up. how soon do you anticipate ws v4.x to be released? If it’s going to be soon I might just put this PR on hold until it is.
Another issue we are seeing is around |
@lpinca Something else that could be help greatly is if you could release some RC versions of ws so we could test against it right now, and not have to wait until the formal release. I guess that also helps flesh out the bugs that may have creeped in the major release of ws :) |
I'm only waiting for someone to take a look at websockets/ws@4e8bd12 to see if error messages/types are good enough. They have been criticized a lot in the past. Changes are breaking but trivial so it doesn't have much sense to go through a beta/RC phase. |
This brings the event accessor handling more in-line with Web IDL.
Permanently upgraded to ws@4. Only 5 failing tests left, none of which we can do much about. |
|
||
// undefined check included so that we can omit the property in internal usage. | ||
if (eventInitDict.view !== null && eventInitDict.view !== undefined) { | ||
if (eventInitDict && eventInitDict.view !== null && eventInitDict.view !== undefined) { |
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.
When could eventInitDict
be falsy? I would have though the Web IDL layer would have guaranteed it to be an object by now.
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.
When we get lazy and call it like SomeEvent.createImpl(['name'])
test/web-platform-tests/to-run.yaml
Outdated
blob/Blob-constructor.html: [fail, "- Blob is not a function | ||
- a date is not instanceof Date | ||
- a regexp is not instanceof Regexp | ||
- strange v8 behaviour when error triggered in overridden array length | ||
- HTMLSelectElement does not have indexed properties | ||
- MessageChannel not implemented | ||
- element attributes does not have indexed properties"] | ||
file/File-constructor-endings.html: [needs-await] | ||
file/File-constructor.html: [fail, WPT bug with fix available at https://github.com/w3c/web-platform-tests/pull/8802] |
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.
Merged the PR if you want to roll again
sequence<Touch> changedTouches = []; | ||
}; | ||
|
||
[Constructor(DOMString type, optional TouchEventInit eventInitDict), |
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 note in the commit message that this also adds the TouchEvent constructor
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.
Well, I guess it won't work anyway, since we don't implement Touch instances or TouchList.
The `key in wrapper` check is fragile as it is susceptible to changes in the wrapper's prototype object.
This should be ready to merge. |
Depends on web-platform-tests/wpt#8746 to be merged and rolled before this could be applied.
Fixes #1195. Closes #2075.
Travis CI will fail due to the tests not being current.