motemen / Plack-Middleware-WebSocket

WebSocket handshake helper middleware
26 stars 2 forks source link

Unexpected response code: 400 #5

Closed qknight closed 8 years ago

qknight commented 8 years ago

i tried this extension but the example is not working 100% correctly.

what works:

just in case someone knows a quick way to fix that, please let me know.

i will now look into the protocol using wireshark. maybe there is some protocol glitch.

thanks for providing this library, seems to be exactly what i need right now.

qknight commented 8 years ago

using wireshark

i've compared two websocket implementation

working websocket

this is from a GO based project:

GET /entry HTTP/1.1
Host: localhost:8080
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:8080
Sec-WebSocket-Version: 13
DNT: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: nixcloud.io=" 15144995390426881980 5027667857982651693 4803607069723604243 18038298082124500619"; RT_SID_example.com.8080=8aca461a1f96ae76a0f8ba96c909b1a8
Sec-WebSocket-Key: u8ZEejzm2z7PVyBfAUbHKw==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 9ilZBI4jjo/6rWI0+b9mIT3+xdI=

.~.){"body":"\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cmeta charset=\"utf-8\"\u003e\n  \u003cmeta name=\"generator\" content=\"pandoc\"\u003e\n  \u003cmeta name=\"viewport\" content=\"width=device-width, initial
...

Plack-Middleware-WebSocket

same browser as above

GET /echo HTTP/1.1
Host: localhost:5000
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:5000
Sec-WebSocket-Version: 13
DNT: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: nixcloud.io=" 15144995390426881980 5027667857982651693 4803607069723604243 18038298082124500619"; RT_SID_example.com.8080=8aca461a1f96ae76a0f8ba96c909b1a8
Sec-WebSocket-Key: VVP9f0R3SO0O5W01D72eMw==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

HTTP/1.0 400 Bad Request

tracing WebSocket.pm function calls

plackup app.psgi   
Twiggy: Accepting connections at http://0.0.0.0:5000/
WebSocket.pm: qknight was here: new

WebSocket.pm: qknight was here: call

127.0.0.1 - - [22/Feb/2016:14:25:25 +0100] "GET / HTTP/1.1" 200 1146 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"
WebSocket.pm: qknight was here: new

WebSocket.pm: qknight was here: call

WebSocket.pm: qknight was here: handshake

$VAR1 = {
          'HTTP_CACHE_CONTROL' => 'no-cache',
          'HTTP_PRAGMA' => 'no-cache',
          'QUERY_STRING' => '',
          'psgi.input' => \*{'Twiggy::Server::$null_io'},
          'HTTP_USER_AGENT' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36',
          'HTTP_ACCEPT_ENCODING' => 'gzip, deflate, sdch',
          'psgi.run_once' => '',
          'websocket.impl' => bless( {
                                       'env' => $VAR1
                                     }, 'Plack::Middleware::WebSocket::Impl' ),
          'HTTP_UPGRADE' => 'websocket',
          'HTTP_DNT' => '1',
          'HTTP_ORIGIN' => 'http://localhost:5000',
          'REQUEST_URI' => '/echo',
          'PATH_INFO' => '/echo',
          'psgi.multiprocess' => '',
          'SERVER_NAME' => '0.0.0.0',
          'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',
          'HTTP_SEC_WEBSOCKET_KEY' => 'Ow5N9WvFtTPBmEnohl8puw==',
          'REQUEST_METHOD' => 'GET',
          'psgi.errors' => *::STDERR,
          'psgi.streaming' => 1,
          'HTTP_CONNECTION' => 'Upgrade',
          'psgi.nonblocking' => 1,
          'psgix.io' => \*{'AnyEvent::Socket::$fh'},
          'psgix.input.buffered' => 1,
          'SERVER_PORT' => 5000,
          'SCRIPT_NAME' => '',
          'HTTP_HOST' => 'localhost:5000',
          'psgi.url_scheme' => 'http',
          'psgi.version' => [
                              1,
                              0
                            ],
          'SERVER_PROTOCOL' => 'HTTP/1.1',
          'HTTP_SEC_WEBSOCKET_EXTENSIONS' => 'permessage-deflate; client_max_window_bits',
          'psgi.multithread' => '',
          'HTTP_COOKIE' => 'nixcloud.io=" 15144995390426881980 5027667857982651693 4803607069723604243 18038298082124500619"; RT_SID_example.com.8080=8aca461a1f96ae76a0f8ba96c909b1a8',
          'REMOTE_ADDR' => '127.0.0.1',
          'HTTP_SEC_WEBSOCKET_VERSION' => '13'
        };
127.0.0.1 - - [22/Feb/2016:14:25:26 +0100] "GET /echo HTTP/1.1" 400 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"

in WebSocket.pm i see that it executes:

in WebSocket.pm: not executed are:

current idea:

qknight commented 8 years ago

some updates:

WebSocket.pm:

this code:

unless ($env->{HTTP_CONNECTION} eq 'upgrade' && $env->{HTTP_UPGRADE} eq 'WebSocket') { 

must be fixed like this:

unless (lc($env->{HTTP_CONNECTION}) eq 'upgrade' && lc($env->{HTTP_UPGRADE}) eq 'websocket') { 

or it won't work.

then i get a division by zero. probably only parameters which were changed / screwed

qknight commented 8 years ago

since we get: HTTP_SEC_WEBSOCKET_KEY from the client and NOT HTTP_SEC_WEBSOCKET_KEY1 and HTTP_SEC_WEBSOCKET_KEY2 i assume that this implementation must be updated to fit the new websocket standard.

see: http://comments.gmane.org/gmane.comp.web.haproxy/3386

interesting WS implementation: https://bitbucket-assetroot.s3.amazonaws.com/which_linden/eventlet/20111020/97/websocket.py?Signature=vibHeogbMOxEDO4hP6H46TiBagA%3D&Expires=1456157150&AWSAccessKeyId=AKIAIWY5XSVPZPDQYRQQ

ws standard RFC 6455: https://tools.ietf.org/html/rfc6455

qknight commented 8 years ago

just realized that there is: http://search.cpan.org/~toshioito/Plack-App-WebSocket-0.03/lib/Plack/App/WebSocket.pm

with a more recent websocket implementation which works with my browser yay.

motemen commented 8 years ago

I am sorry that this module is based on an old version of WebSocket protocol and may not support the current protocol up to date. Just updated README.

qknight commented 8 years ago

would be cool if you could add a link to: Plack::App::Websocket because that was a nice replacement for this obsolete codebase.

thanks for help.

motemen commented 8 years ago

Thanks, updated README again.