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{}).
|