Skip to content
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

Abort the request if close is called while connecting #956

Merged
merged 1 commit into from
Jan 10, 2017
Merged

Conversation

lpinca
Copy link
Member

@lpinca lpinca commented Jan 5, 2017

Currently WebSocket.prototype.close() only sets the readyState to CLOSED if called before receiving a handshake response. Then the connection is eventually closed when the response is received.
This is wrong as the connection event is still emitted on the server.

This patch aborts the client request if WebSocket.prototype.close() is called before receiving a handshake response.

Fixes #388

this.readyState = WebSocket.CLOSED;
return;
this._req.abort();
this.emit('error', new Error('closed while connecting'));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is added to match the browser behavior. I'm not sure if we want this error.
I'm also not sure if the error message is ok, suggestions?

this._req = httpObj.get(requestOptions);

this._req.on('error', (error) => {
if (this._req.aborted) return;
Copy link
Member Author

@lpinca lpinca Jan 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to avoid "socket hang up" errors which are emitted when a request is aborted and a response is not received.

We can remove the check as the error would be swallowed anyway but I think it's better to be explicit here.

@lpinca
Copy link
Member Author

lpinca commented Jan 8, 2017

@websockets/admin please review when/if you can.

@3rd-Eden
Copy link
Member

3rd-Eden commented Jan 9, 2017

Looks sane to me.

this.readyState = WebSocket.CLOSED;
return;
this._req.abort();
this.emit('error', new Error('closed while connecting'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well it makes sense, so just keep it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the error message? Can you think of something better?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some alternatives:

  • "closed before the connection is established"
  • "closed before receiving a handshake response"

I have no strong opinions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

closed before the connection is established is a good one as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll change it to that, merge this and release 2.0.0-beta.0 if there are no objections.

@lpinca lpinca merged commit 772a814 into master Jan 10, 2017
@lpinca lpinca deleted the abort/request branch January 10, 2017 13:43
@Nibbler999
Copy link
Member

@lpinca This breaks engine.io - if you try to connect to a server which is down you get an infinite loop because engine.io calls close when you emit the error in close.

@lpinca
Copy link
Member Author

lpinca commented Jan 14, 2017

Should this be fixed in Engine.IO?

@lpinca
Copy link
Member Author

lpinca commented Jan 14, 2017

I guess Engine.IO is not the only one who calls close() or terminate() inside an error listener and I think this should work without issues.
I'll try to fix this later.

@julien-f
Copy link
Contributor

@3rd-Eden Throwing while connecting deviates from the web API in which close() can be used to closes the connection attempt.

What's the proper way to abort a connection with ws?

@lpinca
Copy link
Member Author

lpinca commented May 24, 2017

@julien-f add a listener for the 'error' event. The browser invokes onerror() when close() is called while connecting.

@julien-f
Copy link
Contributor

My bad, I'm mistaken, close() does not throw.

@lpinca Thanks for your answer and sorry for bothering you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WebSocket.close() does not close the connection
4 participants