Sockjs-erlang strange behavior

341 views
Skip to first unread message

Denis F.

unread,
Feb 24, 2012, 3:13:00 AM2/24/12
to soc...@googlegroups.com
Hello guys.
I'm sorry for this stupid question, but i'm trying to make sockjs-erlang work for a few days, so i need help.
Ok, what i did was compiling sockjs-erlang cowboy example (echo service). My Firefox browser with firebug installed shows me usage of websockets (highest priority transport, isn't it?..), everything is clear.
What i did next was copypasting example code into my test application, which consists of _app and _sup modules, both empty. Copypasted module is available here: http://pastebin.com/0Z6VgPzk. Module is starting by calling strata_sockjs:start() from app init/2 function.
Application starts normally:
Running localhost:8081
Eshell V5.8.4  (abort with ^G)
(stratanode@localhost)1> application:which_applications().
[{sasl,"SASL  CXC 138 11","2.1.9.4"},
 {strata,"Strata","0.1"},
 {cowboy,"Small, fast, modular HTTP server.","0.5.0"},
 {sockjs,"SockJS","0.2.1"},
 {stdlib,"ERTS  CXC 138 10","1.17.4"},
 {kernel,"ERTS  CXC 138 10","2.14.4"}]
(stratanode@localhost)2>                     
But when pointing _same_ browser on localhost:8081 all i get is usage of xhr_streaming:
Req: GET http://localhost:8081/echo/info
Rep: 200 OK, {"websocket":true,"cookie_needed":false,"origins":["*:*"],"entropy":156599810} // Ok, websockets enabled
Req: GET http://localhost:8081/echo/280/c1u1h45o/websocket
Rep: 400 Bad Request // Here is a problem
Req: POST http://localhost:8081/echo/280/4s81eimy/xhr_streaming
// ...so on, using of XHR

I've tried to debug the code. All i've got is the fact, that sockjs_cowboy_handler:init/3 function returns {upgrade, protocol, cowboy_http_websocket} as expected (on "upgrade" request, of course). But cowboy throws out 400 Bad Request response.
It's time to post here a 'whyyyyyyyy?!.jpg'.
Anybody, please, explain me this behavior. What i did wrong?..

P.S. I build application with rebar. can it be some kind of versions mismatch issue?..

Marek Majkowski

unread,
Feb 24, 2012, 5:06:12 AM2/24/12
to m...@shizz.ru, soc...@googlegroups.com

Your code is:

service_echo(Conn, {recv, Data}) ->
error_logger:info_msg("Conn: ~p~nData: ~p", [Conn, Data]),
sockjs:send(Data, Conn);
service_echo(_Conn, _) ->
error_logger:warning_msg("Conn: ~p~nData: ~p", [Conn, Data]),
ok.

The latter won't work: undefined Data. I modified it to be:

service_echo(Conn, R = {recv, Data}) ->
error_logger:info_msg("Conn: ~p~nData: ~p", [Conn, R]),
sockjs:send(Data, Conn);
service_echo(Conn, R) ->
error_logger:warning_msg("Conn: ~p~nData: ~p", [Conn, R]),
ok.

And all works fine.

> I've tried to debug the code. All i've got is the fact, that
> sockjs_cowboy_handler:init/3 function returns {upgrade, protocol,
> cowboy_http_websocket} as expected (on "upgrade" request, of course). But
> cowboy throws out 400 Bad Request response.
> It's time to post here a 'whyyyyyyyy?!.jpg'.
> Anybody, please, explain me this behavior. What i did wrong?..

How did you get that 400? If using Curl - than this is a correct behaviour,
you should see:

$ curl localhost:8081/echo/a/b/websocket -v
> GET /echo/a/b/websocket HTTP/1.1
>
< HTTP/1.1 400 Bad Request
< Connection: keep-alive
< Content-Length: 34
< Date: Fri, 24 Feb 2012 10:04:01 GMT
< Server: Cowboy
<
Can "Upgrade" only to "WebSocket".

Take a careful look what the Chrome Inspector says,
and make sure that your app doesn't crash on the server
side.

> P.S. I build application with rebar. can it be some kind of versions
> mismatch issue?..

Unlikely.

Cheers,
Marek

Denis F.

unread,
Feb 24, 2012, 6:14:24 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
Thanks for your attention, majek.
I test my application with firefox browser only, with firebug enabled, so curl is not used.
Sorry for pastebin link, that's the old version of code. Current version is here: http://pastebin.com/v49QYrwB. So there is no problem with undefined Data.
Here is debug output to console i have when loading page and sending exactly one message:
init()   // init of strata_sockjs to handle 'GET /'
handle()   // reply the static page
terminate()   // terminate
GET /echo/info   // part of sockjs protocol, here we're reply 'websocket=true'
                         // here is 'Upgrade' query performed, which is not logged
POST /echo/368/cohtapcb/xhr_streaming   // switching to XHR
MSG: Conn: {sockjs_session,{<<"z7tvoCSrOBECYNHu1KMbJg==">>,<0.170.0>}}, Data: init   // initialization
POST /echo/368/cohtapcb/xhr_send   // have incoming message
MESG: Conn: {sockjs_session,{<<"z7tvoCSrOBECYNHu1KMbJg==">>,<0.170.0>}}, Data: <<"type something here">>   // and log it

What i want to say is: my application works, but it rolls down to XHR transport, despite the fact that websockets are enabled in my browser.
Just to illustrate the situation - look on requests in firefox: http://dl.dropbox.com/u/5858965/sockjs-requests.png.

Marek Majkowski

unread,
Feb 24, 2012, 6:23:43 AM2/24/12
to m...@shizz.ru, soc...@googlegroups.com
On Fri, Feb 24, 2012 at 11:14, Denis F. <m...@shizz.ru> wrote:
> Thanks for your attention, majek.
> I test my application with firefox browser only, with firebug enabled, so
> curl is not used.

Right. I can't reproduce that. What version of firefox? What firebug?
Maybe broken proxy settings?

> Sorry for pastebin link, that's the old version of code. Current version is
> here: http://pastebin.com/v49QYrwB. So there is no problem with undefined
> Data.

Ok.

> Here is debug output to console i have when loading page and sending exactly
> one message:
> init()   // init of strata_sockjs to handle 'GET /'
> handle()   // reply the static page
> terminate()   // terminate
> GET /echo/info   // part of sockjs protocol, here we're reply
> 'websocket=true'
>                          // here is 'Upgrade' query performed, which is not
> logged
> POST /echo/368/cohtapcb/xhr_streaming   // switching to XHR
> MSG: Conn: {sockjs_session,{<<"z7tvoCSrOBECYNHu1KMbJg==">>,<0.170.0>}},
> Data: init   // initialization
> POST /echo/368/cohtapcb/xhr_send   // have incoming message
> MESG: Conn: {sockjs_session,{<<"z7tvoCSrOBECYNHu1KMbJg==">>,<0.170.0>}},
> Data: <<"type something here">>   // and log it
>
> What i want to say is: my application works, but it rolls down to XHR
> transport, despite the fact that websockets are enabled in my browser.

Right.

> Just to illustrate the situation - look on requests in firefox:
> http://dl.dropbox.com/u/5858965/sockjs-requests.png.

Okay, can you send me websocket request and response headers?
You can get them via firebug or you can run tcpdump, like:
$ tcpdump -ni any port 8081 -s0 -A

Marek

mprize

unread,
Feb 24, 2012, 6:30:30 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
Hello,

In my app I use the following options for sockjs_handler:init_state. Would you try?
[{cookie_needed, true},
  {response_limit, 4096},
  {logger, Mylogger}]

Best wishes,
Max

Denis F.

unread,
Feb 24, 2012, 7:13:27 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
majek,
Firefox version 10.0.2.
Headers:
Request:
GET /echo/368/cah8dfr1/websocket HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 8
Sec-WebSocket-Origin: http://localhost:8081
Sec-WebSocket-Key: 6U7LZSDrrhhlrzREdSh78A==
Cookie: JSESSIONID=dummy
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Response:
HTTP/1.1 400 Bad Request
Connection: keep-alive
Content-Length: 0
Date: Fri, 24 Feb 2012 10:57:26 GMT
Server: Cowboy


Denis F.

unread,
Feb 24, 2012, 7:17:39 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
mprize,
I've tried to set this options. Unfortunately i got no effect, i still have 400 Bad Request response.
Thanks for help.

Denis F.

unread,
Feb 24, 2012, 7:23:40 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
Oh, Firebug version is 1.9.1.

Marek Majkowski

unread,
Feb 24, 2012, 7:26:41 AM2/24/12
to m...@shizz.ru, soc...@googlegroups.com

Still no diagnoze, sorry. Running your request against code from
http://pastebin.com/v49QYrwB
gives proper response for me:

$ nc localhost 8081


GET /echo/368/cah8dfr1/websocket HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:10.0.2)
Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 8
Sec-WebSocket-Origin: http://localhost:8081
Sec-WebSocket-Key: 6U7LZSDrrhhlrzREdSh78A==
Cookie: JSESSIONID=dummy
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Sec-Websocket-Accept: Qy/XzIWK0ypzAnHKy5WEGqdCUs8=
Connection: Upgrade

�o

I'll try to verify the same thing on firefox.

But I'm running out of ideas. Can you repeat the netcat trick
as I did? (ie: run nc localhost 8081 and paste the request + newline)
and see what it responds?

What erlang version? What cowboy version? What sockjs version?

Marek

mprize

unread,
Feb 24, 2012, 7:46:24 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
what does the simple test return?
telnet localhost 8081

Denis F.

unread,
Feb 24, 2012, 7:52:50 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
majek,
Here is execution result (copypasted new headers after project rebuild with get-deps):
shizz@shizz-laptop:/projects/strata # nc localhost 8081
GET /echo/068/nwiv1ify/websocket HTTP/1.1

Host: localhost:8081
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 8
Sec-WebSocket-Origin: http://localhost:8081
Sec-WebSocket-Key: qbR1fFer+D4wS2KEaKoYcw==

Cookie: JSESSIONID=dummy
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

HTTP/1.1 400 Bad Request
Connection: keep-alive
Content-Length: 0
Date: Fri, 24 Feb 2012 12:42:52 GMT
Server: Cowboy

Cowboy issue?.. As i said before, sockjs_cowboy_handler:init/3 returns expected result {upgrade, protocol, cowboy_http_websocket}:
Modified sockjs_cowboy_handler:init/3 function:
init({_Any, http}, Req, Service) ->
    case sockjs_handler:is_valid_ws(Service, {cowboy, Req}) of
        {true, {cowboy, _Req1}, _Reason} ->
            io:format("Protocol upgrade: ok~n", []),
            {upgrade, protocol, cowboy_http_websocket};
        {false, {cowboy, Req1}, _Reason} ->
            io:format("Protocol upgrade: fail~n", []),
            {ok, Req1, Service}
    end.

Logs:
init()
handle()
terminate()
Protocol upgrade: fail // static page reply
GET /echo/info
Protocol upgrade: ok // <-- websocket upgrade
Protocol upgrade: fail // switch to xhr_streaming
POST /echo/604/mjx1tfpw/xhr_streaming
MSG: Conn: {sockjs_session,{<<"_4XNCcCHOVIRW98fcZLMFQ==">>,<0.170.0>}}, Data: init
Protocol upgrade: fail // incoming message (via xhr_send)
POST /echo/604/mjx1tfpw/xhr_send
MESG: Conn: {sockjs_session,{<<"_4XNCcCHOVIRW98fcZLMFQ==">>,<0.170.0>}}, Data: <<"type something here">>

Marek Majkowski

unread,
Feb 24, 2012, 8:01:03 AM2/24/12
to m...@shizz.ru, soc...@googlegroups.com, m...@shizz.ru
Hmm, I'd like to reproduce that.

What cowboy and sockjs revisions are you using? Erlang version?


Marek

Denis F.

unread,
Feb 24, 2012, 7:59:00 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
Erlang R14B03 (erts-5.8.4) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]

Denis F.

unread,
Feb 24, 2012, 8:03:53 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
Sorry, answered later:
Erlang R14B03, Cowboy 0.5.0, Sockjs 0.2.1

Marek Majkowski

unread,
Feb 24, 2012, 8:26:26 AM2/24/12
to m...@shizz.ru, soc...@googlegroups.com
On Fri, Feb 24, 2012 at 13:03, Denis F. <m...@shizz.ru> wrote:
> Sorry, answered later:
> Erlang R14B03, Cowboy 0.5.0, Sockjs 0.2.1

Am I missing something?
https://github.com/extend/cowboy/tags
doesn't show 0.5.0

The app file, says 0.5.0 indeed:
https://github.com/extend/cowboy/blob/master/src/cowboy.app.src
But that isn't pinned to any particular release.

What release specifically are you using?

Marek

Denis F.

unread,
Feb 24, 2012, 8:31:55 AM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
majek,
Here is my rebar.config:
{deps_dir, ["deps"]}.
{sub_dirs, ["rel","apps/strata"]}.
{erl_opts, [debug_info,fail_on_warning]}.
{deps, [
    {cowboy, ".*", {git, "https://github.com/extend/cowboy.git", "master"}},
    {sockjs, ".*", {git, "https://github.com/sockjs/sockjs-erlang.git", "master"}}
]}.

I'm using master branches. Is this the reason of this behavior?

Marek Majkowski

unread,
Feb 24, 2012, 9:04:20 AM2/24/12
to m...@shizz.ru, soc...@googlegroups.com

I still can't reproduce it.
I uploaded the code to gist: https://gist.github.com/1901073

Here's what I do, step by step. Please follow the steps carefully and
tell me if you get the same result:

git clone git://gist.github.com/1901073.git
cd 1901073
make

I'm using :
* erlang R14B01
* $ rebar -V --> rebar version: 2 date: 20120210_110111 vcs: git ebb2345
* Firefox 10.0.2 with no proxy settings and firebug 1.9.1

After pointing Firefox to localhost:8081 I see the message:
[*] Connected (using: websocket)

In right box and it all seems to be working.

Marek

Denis F.

unread,
Feb 24, 2012, 12:14:10 PM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
majek,
Sorry for the long wait, here is the result of execution:

shizz@shizz-laptop:/projects # git clone git://gist.github.com/1901073.git
Cloning into 1901073...
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 13 (delta 1), reused 10 (delta 1)
Receiving objects: 100% (13/13), done.
Resolving deltas: 100% (1/1), done.
shizz@shizz-laptop:/projects # cd 1901073/
shizz@shizz-laptop:/projects/1901073:master # make
rebar get-deps
==> 1901073 (get-deps)
Pulling cowboy from {git,"https://github.com/extend/cowboy.git","master"}
Cloning into cowboy...
Pulling sockjs from {git,"https://github.com/sockjs/sockjs-erlang.git",
                         "master"}
Cloning into sockjs...
==> cowboy (get-deps)
Pulling proper from {git,"git://github.com/manopapad/proper.git",{tag,"v1.0"}}
Cloning into proper...
==> proper (get-deps)
==> sockjs (get-deps)
rebar compile
<...compile routines here...>
erl -pa ebin deps/*/ebin -s wsbug

Erlang R14B03 (erts-5.8.4) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]

Eshell V5.8.4  (abort with ^G)
1> Running localhost:8081
init()
handle()
terminate()
GET /echo/info
GET /echo/457/ce86_4ns/websocket
MSG: Conn: {sockjs_session,{<<"OLuTVn1ws9d8-UR-zn0wRA==">>,<0.151.0>}}, Data: init
MESG: Conn: {sockjs_session,{<<"OLuTVn1ws9d8-UR-zn0wRA==">>,<0.151.0>}}, Data: <<"type something here">>

Websocket connection works now. This mean, that something wrong in my code.
I can push it into github project so you can check the code. I'll try to find difference myself.
Thanks!

Marek Majkowski

unread,
Feb 24, 2012, 12:29:38 PM2/24/12
to m...@shizz.ru, soc...@googlegroups.com
On Fri, Feb 24, 2012 at 17:14, Denis F. <m...@shizz.ru> wrote:
> majek,
> Sorry for the long wait, here is the result of execution:
>
> shizz@shizz-laptop:/projects # git clone git://gist.github.com/1901073.git
>
> Websocket connection works now. This mean, that something wrong in my code.
> I can push it into github project so you can check the code. I'll try to
> find difference myself.

My guess is that you might have been using old version of cowboy.

Whatever. I'm glad it's working for you now.

Cheers,
Marek

Denis F.

unread,
Feb 24, 2012, 12:42:57 PM2/24/12
to soc...@googlegroups.com, m...@shizz.ru
majek,
I was running the latest version of cowboy, last commit (git log) was today at 12:00 or something like that.
All the difference i found was manual applications (cowboy & sockjs) start. When starting this apps manually, websocket connection establishes successfully.
Some problem in rebar, i think (may be it's misconfigured), because my application starts with rebar generate & rel/node/bin/node start.
Here is my reltool.config: http://pastebin.com/Gi2ZpF1t
Here is my vm.args: http://pastebin.com/kpapcmbi
Perhaps this information will give you some ideas.
Thanks for help again!

пятница, 24 февраля 2012 г. 21:29:38 UTC+4 пользователь majek написал:

Marek Majkowski

unread,
Feb 24, 2012, 12:46:06 PM2/24/12
to m...@shizz.ru, soc...@googlegroups.com
On Fri, Feb 24, 2012 at 17:42, Denis F. <m...@shizz.ru> wrote:
> I was running the latest version of cowboy, last commit (git log) was today
> at 12:00 or something like that.
> All the difference i found was manual applications (cowboy & sockjs) start.
> When starting this apps manually, websocket connection establishes
> successfully.
> Some problem in rebar, i think (may be it's misconfigured), because my
> application starts with rebar generate & rel/node/bin/node start.
> Here is my reltool.config: http://pastebin.com/Gi2ZpF1t
> Here is my vm.args: http://pastebin.com/kpapcmbi
> Perhaps this information will give you some ideas.

Now, that's interesting!

Marek

Denis F.

unread,
Feb 27, 2012, 7:37:33 AM2/27/12
to soc...@googlegroups.com, m...@shizz.ru
majek,
Hello again. Did you found out the reason of such behavior? It's really interesting.

Marek Majkowski

unread,
Feb 27, 2012, 9:32:56 AM2/27/12
to m...@shizz.ru, soc...@googlegroups.com

Well, without doubt you do need to start sockjs and cowboy apps
before calling cowboy:start_listener.

I'm not a rebar expert so I can't comment on your reltool.config.

I would usually suggest to mention the dependencies in .app file.

Cheers,
Marek

Reply all
Reply to author
Forward
0 new messages