gimite / web-socket-js

HTML5 Web Socket implementation powered by Flash
BSD 3-Clause "New" or "Revised" License
2.73k stars 489 forks source link

Support unmasking server->client message #102

Closed lequarti closed 12 years ago

lequarti commented 12 years ago

Hi,

I work on Adobe Air application, for a purpose, I integrated the websocketJS to an Air HTML/JS Application. Evrything working fine, but data receveid onMessage seem to be hashed or undecoded.

I use a php-websocket server, with hiby-10 protocol implements, it's work fine with Chrome/Firefow browser, but not with the flash Interface.

Is there any solutions ?

Thx in advance.

gimite commented 12 years ago

So you use WebSocket class directly in ActionScript, not using web_socket.js in JavaScript? Then yes, event.message in ActionScript message event is encoded with encodeURIComponent. You can extract original message by decodeURIComponent(event.message).

This is due to historical reason. We needed to encode the message when we pass it to the JS<->Flash bridge library we used in the past. I believe we no longer need to do it. So the encoding may be removed in future version.

lequarti commented 12 years ago

Oh thx, waiting for the future version.

In fact Air 3 do not support Websocket :( (http://www.adobe.com/devnet/air/ajax/articles/air_and_webkit.html)

So I include "web_socket.js" in my Html and Js Air application to override the limitation, having the same application working fine natively under chrome and firefox using this server (https://github.com/lemmingzshadow/php-websocket).

I was pretty confused when the encoding blow up all my work, so for the moment I downgrade to draft-76, working fine and reworte the php server to broadcast draft-76 and hiby-10.

Best regards, for this amazing projet bringing a brand new techs to older browsers !

greetins.

gimite commented 12 years ago

So you use web_socket.js from JavaScript? Then the message should not be encoded, because web_socket.js internally calls decodeURIComponent. By "under Firefox", do you use MozWebSocket class (Firefox's native WebSocket) or WebSocket class (web_socket.js's WebSocket)? If the latter, there should not be difference between behavior in Firefox and Air. Maybe there's something specific to Air's JavaScript engine or communication with Flash?

lequarti commented 12 years ago

Yes I use web_socket.js from JavaScript, and I use (web_socket.js's WebSocket), the Air Html App use WebKit rendrering like Safari.

By the way I don't think so it's specific to Air Javascript engine, I reproduced the same issue under Mac and Camino Browser, may be it's the php websocket server, but still, It's strange, the same message work's fine with native extension.

In the future, I think I gonna do a portage of the WebSocketMain.swf as Adobe Air Native Extension, it might be easy based on the action script source code !

gimite commented 12 years ago

By the way I don't think so it's specific to Air Javascript engine, I reproduced the same issue under Mac and Camino Browser, may be it's the php websocket server, but still, It's strange, the same message work's fine with native extension.

I confirmed that it unescapes correctly in both Firefox and Chrome (forcing Flash implementation) when I use web-socket-ruby in server side. So it can be either:

In the future, I think I gonna do a portage of the WebSocketMain.swf as Adobe Air Native Extension, it might be easy based on the action script source code !

web-socket-js already provides library for ActionScript. See flash-src/build.xml which can generate WebSocket.swc. I guess you can also use it in Air. There's no examples/documentation, so it may require some effort to use it, though. I recommend to use WebSocket class directly, not WebSocketMain, because WebSocketMain is a bridge between JS and ActionScript.

lequarti commented 12 years ago

Here I'm back,

Well after a weekend of hard debuging, I finally found the solution.

First I use AS3WebSocket as Action script library, well it was easy and fast thant to readapt the WebSocket.as from your's, but I think a branch for Air support will be a good thing.

But using AS3WebSocket wasn't funny at all, in fact the As3corlib sha1 crypto doesn't fit for the Handshake, finaly I selected the Gsolo sha1 script.

Then the huge problem about encoding was due to using masking option in datasend, my php server send and masked data with a random Masking-key (hybi-10 draft). So why I had this issue in hybi10. Finally sending unmaske data do note provoke anny error.

This issue is closed for good purpose !! best regards

gimite commented 12 years ago

Oh I see. web-socket-js supports masking for client->server message (which is required), but doesn't support masking for server->client message (which is optional). I'll implement it. Thanks for let me know.

kanaka commented 12 years ago

@gimite, actually, server->client masking is prohibited by the spec. In fact, the client is required to close the connection if it detects the server has sent a masked frame. See section 5.1 of the spec.

Client->server masking is mandatory but may be relaxed in the future for non-browser (i.e. trusted) clients.

FYI, the masking is not encryption in any sense since the key is included with the frame. It is just a means of scrambling the client->server data to avoid confusing poorly implemented intermediaries.

gimite commented 12 years ago

Oh I see. Thanks for the information. (Note: It's section 4.1 in hybi-10 spec.)

Then that's an issue of PHP WebSocket server implementation. @irss , which PHP library are you using? Or did you implement yourself? I found multiple PHP WebSocket libraries, but I haven't found one which supports hybi-10.

lequarti commented 12 years ago

@gimite , I use this one : https://github.com/GulDmitry/php-websocket-server

@kanaka You have seen right, but as chrome / firefox are taking the making on server 2 client, I didn't change the php-websocket-server, so now I set to false the masking, everything is fine.

gimite commented 12 years ago

@irss Thanks. Reported the issue to php-websocket-server: https://github.com/GulDmitry/php-websocket-server/issues/1

gimite commented 12 years ago

FYI I heard from Chrome guy that Chrome accepts masked message because old spec didn't say it is disallowed clearly enough. Latest spec says it more clearly.

ranc commented 12 years ago

@kanaka: no need to hear, I tried it myself... chrome & FF support unmasking received frame... Spec says: (hybe-10) - section 4.1 (not 5.1): Frames sent from the server to the client are not masked. Unfortunately it does not specify MUST/MAY/SHOULD thus, to be on the safer side when developing protocol code you should: "Expect the worse but send the best" - or "parse as loose as possible but send as strict as possible".

Bottom line: client code SHOULD unmask the frame if the mask frame bit is set. Or you want to change all the servers in the world...

ranc commented 12 years ago

P.S: adding this code takes less time than arguing about it ;-)

gimite commented 12 years ago

Yeah that part was not clear enough in hybi-10, and was clarified in later version: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.1

A server MUST NOT mask any frames that it sends to the client.

ranc commented 12 years ago

Yes, you are correct. But since some servers already out there already did masking, it would be wise not to follow the guide in 17: ..." A client MUST close a connection if it detects a masked frame" ... especially since they realized they have compatibility issue and followed with the saying: ..."(These rules might be relaxed in a future specification.)".. :-)

Anyway, just an advise.... we do want this code to work as much as possible with lots of servers....

But the bug should not be closed either way since the parsing should not ignore the mask bit as it does today. It must follow some guide. either close or unmask. But now it ignores it and does not read the mask, which causes the stream to be out-of-sync.

gimite commented 12 years ago

But since some servers already out there already did masking

The only such server I know was php-websocket-server, which is already fixed. Please let me know if you know anything else. I may consider if some widely used server does masking.

But the bug should not be closed either way since the parsing should not ignore the mask bit as it does today. It must follow some guide. either close or unmask. But now it ignores it and does not read the mask, which causes the stream to be out-of-sync.

I agree. I filed separated issue: #103

ranc commented 12 years ago

10x. I have no such server in mind. It was more of a theoretical issue. I'll settle with #103 for now.

ranc commented 12 years ago

(and Compatibility with Chrome & FF...)

kanaka commented 12 years ago

If Chrome and FF are unmasking frames from the server then that is a spec violation and bugs should be filed against them. There is no ambiguity any longer in the specification, but it was never intended that server->client masking be permitted. Server->client masking serves no purpose and just slows down the connection which is why the working group decided to clarify the spec and make it unambiguous that it is never permitted.

Also the parenthetical comment (which I actually proposed) in the spec indicating that these rules may be relaxed in future versions only applies to client->server masking. Unfortunately the placement of the comment doesn't make that clear, but if you read the HyBi mailing list it is clear that the future relaxing only applies to making client->server masking optional.

I agree with #103 that web-socket-js should close the connection (probably sending a 1002 to be friendly).