Closed karlp closed 10 years ago
This could be fixed without modifying parsers in the following way:
I'm off for vacation for the next week, but I can take a crack at it afterwards if no one's patched it by then.
Ciao! -Andrew
On Fri, Jul 18, 2014 at 8:44 AM, Karl Palsson notifications@github.com wrote:
From the WebSockets standard,
The request MAY include a header field with the name |Sec-WebSocket-Protocol|. If present, this value indicates one or more comma-separated subprotocol the client wishes to speak, ordered by preference. The elements that comprise this value MUST be non-empty strings with characters in the range U+0021 to U+007E not including separator characters as defined in [RFC2616] and MUST all be unique strings. The ABNF for the value of this header field is 1#token, where the definitions of constructs and rules are as given in [RFC2616].
An example of client code that does this: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.javascript.git/tree/src/mqttws31.js#n973
this.socket = new WebSocket(wsurl, ["mqtt","mqttv3.1"]);
libwebsockets however, in the parser state machine for sec-websocket-protocol, does not split this on the comma, and try each protocol in turn. Instead, it looks for a struct libwebsocket_protocols with a name matching "mqtt, mqttv3.1".
You can't even work around this by registering a protocol with that name, as it then returns the combined name to the browser, which rejects it as being neither of the protocols requested.
Unfortunately, I'm finding the parsers.c::libwebsocket_parse() method to be... rather difficult to follow, so I've not managed to get a patch together for this at present.
— Reply to this email directly or view it on GitHub https://github.com/warmcat/libwebsockets/issues/147.
I stumbled about this issue too. I propose a more general solution to deal with arbitrary protocol name lists, as outlined in https://github.com/mhaberler/libwebsockets/commit/de3e7c913dd4e5ad71f84d70846782b3d18ea9c5 :
This should fix the selection logic, and also enable more flexible protocol handling in the server.
I'll look into generating a PR.
ok, here is a tentative fix for the Sec-WebSocket-Protocol header issue, which at the same time enables the behavior outlined above (give FILTER_PROTOCOL_CONNECTION the option to choose and set a ws protocol name and - optionally - a non-default libwebsockets_protocol reference):
https://github.com/warmcat/libwebsockets/pull/158
Also fulfill's karlp's above requirement.
works great for me - usage example: http://git.mah.priv.at/gitweb?p=emc2-dev.git;a=blobdiff;f=src/machinetalk/webtalk/webtalk_wsproxy.cc;h=01ac1dc02d5145eaf549d45a57a209b02f943c5f;hp=a6f0572eab7e18752127bd2528bf70cdd8a5201d;hb=33e90e10554fd765229edc0adcb6bb2dd0d8f644;hpb=9c6e8063614dc6bfae243243bc177daaaca0f271
I am a bit unsure about the correctness of the lib/server-handshake.c diff - any field overflow detection required?
happy to update the docs if merged.
header example - FILTER_PROTOCOL_CONNECTION selected machinekit1.0:
Upgrade: websocket
Connection: Upgrade
Host: 193.228.47.216:4711
Origin: http://193.228.47.216:4711
Sec-WebSocket-Key: 7TU1v07PT2yXFihHhRKn4Q==
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: http foo bar machinekit1.0 fasel
-----------------------
--- response header ---
HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: mIj9MYvF6koXih+/8Wt2bHorV04=
Sec-WebSocket-Protocol: machinekit1.0
-----------------------
just noticed a restriction with my approach: if there are several protocol structures, and their proto is switched from default, their per_session_data_size must be identical because by the time FILTER_PROTOCOL_CONNECTION is callled the userdata is already allocated from the default entry.
I see these options (in descending order of preference):
What do you guys think?
I'm not sure why my note didn't make it on this bug, but this was fixed three weeks ago with this
I can confirm that the current code works properly with firefox 31, but chromium 27 gets protocol errors. Given the names of the last release, that sounds like it's now working as well as it can with those browsers :)
From the WebSockets standard,
An example of client code that does this: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.javascript.git/tree/src/mqttws31.js#n973
libwebsockets however, in the parser state machine for sec-websocket-protocol, does not split this on the comma, and try each protocol in turn. Instead, it looks for a struct libwebsocket_protocols with a name matching "mqtt, mqttv3.1".
You can't even work around this by registering a protocol with that name, as it then returns the combined name to the browser, which rejects it as being neither of the protocols requested.
Unfortunately, I'm finding the parsers.c::libwebsocket_parse() method to be... rather difficult to follow, so I've not managed to get a patch together for this at present.