Lawouach / WebSocket-for-Python

WebSocket client and server library for Python 2 and 3 as well as PyPy (ws4py 0.5.1)
https://ws4py.readthedocs.org/en/latest/
BSD 3-Clause "New" or "Revised" License
1.12k stars 288 forks source link

ws4py 0.2.2 no longer working on Chrome version 30 #108

Closed robdennis closed 10 years ago

robdennis commented 10 years ago

We're using version 0.2.2 of ws4py (which I'm aware is not the latest version), and following a recent update to chrome version 30, we're no longer able to make a websocket connection (though Firefox is fine).

edited chrome console:

WebSocket connection to 'ws://<url>/ws' failed: Error during WebSocket handshake: Sec-WebSocket-Protocol mismatch

I believe this is due to this changeset that changes the Chrome implementation to be more stringent against the spec: https://code.google.com/p/chromium/issues/detail?id=259666

It's possible this is handled in the most recent version of ws4py, but since Chrome 30 was a relatively recent release, I assumed that a more timely though less updated bug report was the preference.

edit: grammar/spelling

Lawouach commented 10 years ago

Thanks for this report. The bug probably lives as well with more recent version of ws4py. I will verify and fix it. However, I tend not to work on so old releases as 0.2.x. Is it a necessary requirement for you?

robdennis commented 10 years ago

I think it's fine to just concentrate on trunk, we need to update to 0.3.x anyway. In the unlikely event we're stuck on 0.2.x I'm sure I can backport the fix and make a pull-request.

Thanks for the quick response and for looking into it.

davidgiven commented 10 years ago

I think I've run into this as well with the version in Debian, which is 0.2.4.

Before I submit a Debian bug asking them to update their package to 0.3 series, does anyone know whether this bug still manifests there?

jodal commented 10 years ago

I'm the maintainer of the package in Debian. Upgrading the package to 0.3.2 is close to the top of my todo list.

I'm not able to reproduce this issue myself, so I can't confirm if it's been fixed in 0.3.x.

Lawouach commented 10 years ago

It's weird, running Chromium version 32.0.1690.0 (232629), I cannot reproduce this issue either with 0.3.3 nor 0.2.4. It works just fine.

davidgiven commented 10 years ago

Hm. After running some tests myself:

Chrome 31.0.1650.26 beta --- fails Chromium 29.0.1547.57 for Debian --- succeeds Iceweasel 19.0.2 --- succeeds

If it's any help, the server I'm using is at http://cowlark.com/~dg/thickishstring/ (I'll try to keep it running for a couple of days). If it fails, you get a 'Disconnected from server' error and a diagnostic in the Javascript console. If it succeeds, you get a login page.

For reference, my source is at https://cowlark.com/thickishstring, but of course as it's a full server application it's a bit fiddly to get running.

Lawouach commented 10 years ago

Gotcha. Thanks. Indeed, I get the same error when protocols are provided to the client websocket on connection. Both with 0.2.x and 0.3.x.

Thanks @davidgiven

Lawouach commented 10 years ago

Interestingly however, if you do setup your server so that it knows about this subprotocol, it works well. For instance, using:

'tools.websocket.protocols': ['movie', 'music', 'work']

With a CherryPy server, and if the client requests the 'music' subprotocol, the response will correctly returns a:

Sec-WebSocket-Protocol: music

response header and the connection will go through.

jodal commented 10 years ago

@davidgiven Just wanted to give you an update: python-ws4py 0.3.2 is finally in Debian unstable, and should be in testing in about 10 days.

Lawouach commented 10 years ago

That's pretty cool. Thanks Stein.

davidgiven commented 10 years ago

Huzzah. Thanks.

robdennis commented 10 years ago

I'm curious as to the disposition of this ticket now. Based on the research of @Lawouach, it appears as if setting a subprotocol on the server allows a Chrome connection to be made without issue.

Is setting up those protocols the official remediation for this issue? Or instead, is there still work to be done on supporting Chrome 30+ without needing to set up those protocols (e.g. how it was before)?

Lawouach commented 10 years ago

Well, I believe Chrome is doing the wrong thing. The RFC 6455 seems to say that the server may decide not to acknowledge the requested subprotocol by not returning a Sec-WebSocket-Protocol header:

If the client's handshake did not contain such a header field or if the server does not agree to any of the client's requested subprotocols, the only acceptable value is null. The absence of such a field is equivalent to the null value (meaning that if the server does not wish to agree to one of the suggested subprotocols, it MUST NOT send back a |Sec-WebSocket-Protocol| header field in its response).

As far as I know, this is what ws4py does. It will not return the header if it doesn't have a matching subprotocol. If a matching protocol is found, it is selected and returned as per the spec.

If Chrome fails because the header is missing, then it's Chrome's fault I believe.

robdennis commented 10 years ago

Alright, certainly a reasonable position. Given that there is reproducible behavior on Chrome, do you intend to open a Chrome issue in their tracker? I'm not sure I'm knowledgeable enough to make such a ticket myself.

Lawouach commented 10 years ago

I dug a little more and actually Chrome does the right thing here as per the client-side API of WebSocket. It fails the connection accordingly but also fires an error and a close events. The latter has its status set to 1006 and the "wasClean" flag set to false. The only issue I could see is that the 1006 code is rather generic and clients won't be able to programmatically make a decision about the reason why it failed. So no bug on Chrome side, no bug on ws4py side. Everything is fine and this ticket can be closed I think.

Thanks for the report. I will try to make it clear in the docs regarding that behavior.