File: 0003-websocket-subprotocol

package info (click to toggle)
rabbitmq-server 3.3.5-1.1
  • links: PTS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 12,004 kB
  • sloc: erlang: 78,203; python: 3,187; xml: 2,843; makefile: 903; sh: 831; java: 660; perl: 64; ruby: 63
file content (93 lines) | stat: -rw-r--r-- 4,113 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
diff --git a/src/sockjs_cowboy_handler.erl b/src/sockjs_cowboy_handler.erl
index 3b1ffe3..d2f05ae 100644
--- a/src/sockjs_cowboy_handler.erl
+++ b/src/sockjs_cowboy_handler.erl
@@ -30,21 +30,35 @@ terminate(_Req, _Service) ->
 
 %% --------------------------------------------------------------------------
 
-websocket_init(_TransportName, Req, Service = #service{logger = Logger}) ->
-    Req0 = Logger(Service, {cowboy, Req}, websocket),
+websocket_init(_TransportName, Req,
+               Service = #service{logger        = Logger,
+                                  subproto_pref = SubProtocolPref}) ->
+    Req3 = case cowboy_http_req:header(<<"Sec-Websocket-Protocol">>, Req) of
+               {undefined, Req1} ->
+                   Req1;
+               {SubProtocols, Req1} ->
+                   SelectedSubProtocol =
+                     choose_subprotocol_bin(SubProtocols, SubProtocolPref),
+                   {ok, Req2} = cowboy_http_req:set_resp_header(
+                                  <<"Sec-Websocket-Protocol">>,
+                                  SelectedSubProtocol, Req1),
+                   Req2
+           end,
+
+    Req4 = Logger(Service, {cowboy, Req3}, websocket),
 
     Service1 = Service#service{disconnect_delay = 5*60*1000},
 
-    {Info, Req1} = sockjs_handler:extract_info(Req0),
+    {Info, Req5} = sockjs_handler:extract_info(Req4),
     SessionPid = sockjs_session:maybe_create(undefined, Service1, Info),
-    {RawWebsocket, {cowboy, Req3}} =
-        case sockjs_handler:get_action(Service, Req1) of
-            {{match, WS}, Req2} when WS =:= websocket orelse
+    {RawWebsocket, {cowboy, Req7}} =
+        case sockjs_handler:get_action(Service, Req5) of
+            {{match, WS}, Req6} when WS =:= websocket orelse
                                      WS =:= rawwebsocket ->
-                {WS, Req2}
+                {WS, Req6}
         end,
     self() ! go,
-    {ok, Req3, {RawWebsocket, SessionPid}}.
+    {ok, Req7, {RawWebsocket, SessionPid}}.
 
 websocket_handle({text, Data}, Req, {RawWebsocket, SessionPid} = S) ->
     case sockjs_ws_handler:received(RawWebsocket, SessionPid, Data) of
@@ -69,3 +83,15 @@ websocket_info(shutdown, Req, S) ->
 websocket_terminate(_Reason, _Req, {RawWebsocket, SessionPid}) ->
     sockjs_ws_handler:close(RawWebsocket, SessionPid),
     ok.
+
+%% --------------------------------------------------------------------------
+
+choose_subprotocol_bin(SubProtocols, Pref) ->
+    choose_subprotocol(re:split(SubProtocols, ", *"), Pref).
+choose_subprotocol(SubProtocols, undefined) ->
+    erlang:hd(lists:reverse(lists:sort(SubProtocols)));
+choose_subprotocol(SubProtocols, Pref) ->
+    case lists:filter(fun (E) -> lists:member(E, SubProtocols) end, Pref) of
+        [Hd | _] -> Hd;
+        []       -> choose_subprotocol(SubProtocols, undefined)
+    end.
diff --git a/src/sockjs_handler.erl b/src/sockjs_handler.erl
index b706453..81d4ef7 100644
--- a/src/sockjs_handler.erl
+++ b/src/sockjs_handler.erl
@@ -29,7 +29,9 @@ init_state(Prefix, Callback, State, Options) ->
              response_limit =
                  proplists:get_value(response_limit, Options, 128*1024),
              logger =
-                 proplists:get_value(logger, Options, fun default_logger/3)
+                 proplists:get_value(logger, Options, fun default_logger/3),
+             subproto_pref =
+                 proplists:get_value(subproto_pref, Options)
             }.
 
 %% --------------------------------------------------------------------------
diff --git a/src/sockjs_internal.hrl b/src/sockjs_internal.hrl
index 629b2fe..eed5597 100644
--- a/src/sockjs_internal.hrl
+++ b/src/sockjs_internal.hrl
@@ -15,7 +15,8 @@
                   disconnect_delay , %%  non_neg_integer()
                   heartbeat_delay  , %%  non_neg_integer()
                   response_limit   , %%  non_neg_integer()
-                  logger            %%  logger()
+                  logger           , %%  logger()
+                  subproto_pref      %%  [binary()]
                   }).
 
 %% -type(service() :: #service{}).