hramenko / bauglir-websocket

Automatically exported from code.google.com/p/bauglir-websocket
0 stars 0 forks source link

Possible websocket anomaly in Chrome 19 beta #37

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Does this library handle extensions negotiation correctly?

See this recent issue: http://code.google.com/p/chromium/issues/detail?id=123231

Great work btw! 

What steps will reproduce the problem?
1.
2.
3.

What is the expected output? What do you see instead?

What version of the product are you using? On what operating system?

Please provide any additional information below.

Original issue reported on code.google.com by hmekhs...@gmail.com on 13 Apr 2012 at 7:34

GoogleCodeExporter commented 9 years ago
Hi,
did you actually test it and find any issue?

If you want to refuse extension(s)/protocol(s), your server implementation 
should look like this

[C#]
  public class TestWebSocketServer : WebSocketServer
  {
    public override WebSocketServerConnection GetConnectionInstance(
      TcpClient aClient,
      WebSocketHeaders aHeaders,
      string aHost, string aPort, string aResourceName, string aOrigin, string aCookie, string aVersion,
      ref string aProtocol, ref string aExtension,
      ref int aHttpCode
    )
    {
      aProtocol = "-";
      aExtension = "-";
      return new TestWebSocketServerConnection(aClient, this);
    }
  }

[Pascal]
function TTestWebSocketServer.GetWebSocketConnectionClass(Socket: 
TTCPCustomConnectionSocket;
      Header: TStringList;
      ResourceName, Host, Port, Origin, Cookie: string;
      out HttpResult: integer;
      var Protocol, Extensions: string
): TWebSocketServerConnections;
begin
  result := TTestWebSocketServerConnection;
  Protocol := '-';
  Extensions := '-';
end;

Where Protocol and Extensions variables should return either allowed 
protocol/extensions or "-" to inform client what protocol/extension your server 
accepts or that it does not accepts any.

E.g. I currently have an application that does not accept any extensions and 
does accepts all protocols (for convenience: application deals with certain 
protocol specifically and falls back to default protocol for all others):

function TP2WebSocketServer.GetWebSocketConnectionClass(
  Socket: TTCPCustomConnectionSocket; Header: TStringList; ResourceName,
  Host, Port, Origin, Cookie: string; out HttpResult: integer;
  var Protocol, Extensions: string): TWebSocketServerConnections;
begin
  result := TP2WebSocketServerConnection;
  Protocol := Protocol;
  Extensions := '-';
end;

I actually have client running all the time with admin protocol to get 
application statistics in Chrome Nightly, so I would notice :)

Original comment by Bronisla...@bauglir.com on 13 Apr 2012 at 8:02

GoogleCodeExporter commented 9 years ago
Oooh. I get it now. I will create my own WebSocket subclass to deny the chrome 
compression extension. Thanks a lot dude. You're the man!

Original comment by hmekhs...@gmail.com on 13 Apr 2012 at 8:26

GoogleCodeExporter commented 9 years ago
Just to clarify, those variables, when "comming into" this method, contain 
protocols and extensions requested by client and this is the place where to 
decide what to accept and  what to refuse.

Protocol is comma separated list of possible protocol, server should return 
either "-" or one of requested protocols (in my implementation above, I also 
wrote clients, so I know that only one protocol is requested, if any), here you 
can parse the Protocol variable, check it for supported protocols and select 
one, or refuse any..

Extensions are little bit mot complicated 
http://tools.ietf.org/html/rfc6455#page-48.
Variable does contain header value at this point, does not parse any. You must 
parse ext. names and parameters yourselves (at this point only per frame 
deflate exists, so no problem here, yet). And implementation should return list 
of supported extensions. 

So the server reads request, fills Protocol and Extensions variables, runs this 
method, and then use those variables to respond to client.

(there's also HttpResult prefilled to 101 Switching Protocols, by specifying 
other again in this method one can refuse connection immediately by specifying 
reason (404 not found, 301 moved permanently, etc.))  

Original comment by Bronisla...@bauglir.com on 13 Apr 2012 at 8:45

GoogleCodeExporter commented 9 years ago
I am still having trouble with this.  My implementation works with Firefox and 
Chrome<19 but not with Chrome 19.  Confirming the handshake messages in 
Wireshark, this is what I see being sent:

GET /chatserver HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: (omitted for this post)
Origin: (omitted for this post)
Sec-WebSocket-Key: TbwnVcuUiqGgZn7hxvxzvQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: D45BJ+Vfydy1Upcs3Hze/nuiaS8=
Sec-WebSocket-Extensions: -

The connection does not progress from there.  Is there something else I need to 
do?

Original comment by aaro...@gmail.com on 5 May 2012 at 3:23

GoogleCodeExporter commented 9 years ago
For clarification, when I say that the connection does not progress, I mean 
that the very next packet is a FIN/ACK from the client.  The connection closes.

I do not see the convention for using "-" to indicate no extensions in RFC6455. 
 Where does this come from?  In any case, I cannot get the Chrome 19 websocket 
connection to work with or without the "-".

Original comment by aaro...@gmail.com on 5 May 2012 at 7:55

GoogleCodeExporter commented 9 years ago
Hi,
no problem here... still working in Chrome dev

I do not know about you implementation, but if you use regular dash, the header 
(either protocol or extension) is not sent. Of course you cannot sent dash 
directly. My implementation use dash as a sign not to send such header.
As I wrote, - is sign for my implementation, this does not come from RFC. I've 
chosen this, because i needed the way to refuse extension or protocol. But as I 
wrote, this header should not be sent, tri to debug the response from the 
server.

Brona

Original comment by Bronisla...@bauglir.com on 7 May 2012 at 7:47

GoogleCodeExporter commented 9 years ago
I'm seeing something similar with Chrome 19... "does not progress" is a good 
description. If I reject the extension with Extensions := '-'; then the connect 
works ok, but when the client sends the first message into the server, it's not 
received. When I shut the client down, then the message shows up at the server.

Worked fine on Chrome 18 (without Extensions := '-'; ) and works fine on 
Firefox.

Original comment by gensma...@gmail.com on 18 May 2012 at 11:15

GoogleCodeExporter commented 9 years ago
Hi, I'm sendng demo
1/ run ServerDemo.exe
2/ run ws.html in Chrome
3/ start server
4/ connect from Chrome to server and send data
5/ click on that connection in server demo (you should see both data and 
headers from client)

you can send PNG images both way, you can connec more clinets to that server. 
Data on server do not update automatically (except for connection list view), 
co if you send data from client, you must select that conection even if alredy 
selected

Original comment by Bronisla...@bauglir.com on 18 May 2012 at 1:19

Attachments:

GoogleCodeExporter commented 9 years ago
Here's what happens with the demo you posted when I try it with Chrome 19:

Run ServerDemo.exe
Press Start Server
Launch ws.html in Google Chrome
press OPEN button on ws.html page
Connection appears on server:

OnOpen 1
OnAfterAddConnection 1
OnBeforeAddConnection 1

upgrade=websocket
connection=Upgrade
host=localhost:81
origin=null
sec-websocket-protocol=proto1, proto2
sec-websocket-key=MVOyaWdUblnxtKdyCiEMxw==
sec-websocket-version=13
sec-websocket-extensions=x-webkit-deflate-frame

type the word "test" in the ws.html input box
Press SEND on ws.html page
Nothing appears on server or in server log, even when I select the connection 
again in the server demo ui

Then I loaded a small(1500 bytes) "png" using the ws.html choose file
The connection immediately goes away on server and this shows in the server log:

OnAfterRemoveConnection 1
OnBeforeRemoveConnection 1
OnClose 1, 1006, , closed by peer
OnRead 1, final: 1, ext1: 0, ext2: 0, ext3: 0, type: 1, length: 4
OnOpen 1
OnAfterAddConnection 1
OnBeforeAddConnection 1

Comment: I think this is similar to what I'm seeing in my app - the onRead 
appears to get "stuck" somehow and doesn't become visible to the server until 
the connection closes.

Original comment by gensma...@gmail.com on 18 May 2012 at 8:37

GoogleCodeExporter commented 9 years ago
I should add that this is repeatable across multiple machines - e.g. I get the 
same result on my other desktops and on my laptop with Chrome 19.

Original comment by gensma...@gmail.com on 18 May 2012 at 8:39

GoogleCodeExporter commented 9 years ago
Another data point... if I msConfig disable "Base Filtering Engine" and 
reboot... Chrome 19  and your demo works. This would imply it's some sort of MS 
Firewall related issue maybe? But simply shutting off the Firewall and adding 
rules doesn't resolve it... I have to disable the service to get it to work. 
Weird that the issue is unique to Chrome 19.

Original comment by gensma...@gmail.com on 19 May 2012 at 12:00

GoogleCodeExporter commented 9 years ago
Ha! we have a problem maker there... well it would seem that firewall is 
blocking the connection, you have to probably set it up not only to send data 
to such port but also listen on such port and both unrestrictivelly 

B.

Original comment by Bronisla...@bauglir.com on 19 May 2012 at 2:08

GoogleCodeExporter commented 9 years ago
Weird... I have my windows firewall up and running, and everything is fine...

you also wrote, that managing WS rules did not help, you have to turn off the 
firewall all together; combining that with the fact that you wrote, that FF 
works fine, that the problem may not be in generic port settings, but try to 
look whether there are some Chrome/Chromium/WebKit specific settings within the 
firewall.

Original comment by Bronisla...@bauglir.com on 19 May 2012 at 2:16

GoogleCodeExporter commented 9 years ago
My websocket server app works ok with Chrome 19, it's just that the messages 
coming in aren't decoded because of the new Chrome 19 compression extension. 
But I don't have any hangs - the messages flow through. It's when I try to deny 
the extension in my server app that the trouble begins, and I get the strange 
hang up. So the thing that seems to trip the apparent firewall hang is when I 
try to deny the extension (which you're also doing in your demo). Weird.

Original comment by gensma...@gmail.com on 21 May 2012 at 3:14

GoogleCodeExporter commented 9 years ago
in a comment 4, it seems like your client is receiving actually 
"Sec-WebSocket-Extensions: -", can you confirm that? If so, can you modify my 
WS library that server sends no such header under any circumstances? 
function TWebSocketServer.CreateServerConnection
just comment the block in this function 
if (fncExtensions <> '-') then
begin
  s := s +  'Sec-WebSocket-Extensions: ' + fncExtensions + #13#10;
end;
and test whether no such header is sent from server to client (there can be 
Sec-WebSocket-Extensions header in server response). How does it behave then?

Original comment by Bronisla...@bauglir.com on 21 May 2012 at 9:56

GoogleCodeExporter commented 9 years ago
Issue 38 has been merged into this issue.

Original comment by Bronisla...@bauglir.com on 22 May 2012 at 11:44

GoogleCodeExporter commented 9 years ago
Issue 39 has been merged into this issue.

Original comment by Bronisla...@bauglir.com on 23 May 2012 at 12:26