Skip to content

Commit

Permalink
formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
alpha.ferry committed Feb 8, 2021
1 parent 1842bbe commit 921b5e2
Show file tree
Hide file tree
Showing 5 changed files with 465 additions and 301 deletions.
3 changes: 1 addition & 2 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
]}.

{deps, [
{cowboy, "2.8.0",{git, "https://github.com/ninenines/cowboy.git", {tag, "2.8.0"}}}
]}.
{cowboy, "2.8.0", {git, "https://github.com/ninenines/cowboy.git", {tag, "2.8.0"}}}
]}.

{project_plugins, [erlfmt]}.
167 changes: 107 additions & 60 deletions src/sockjs_cowboy_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,82 +6,126 @@
-export([init/2, terminate/3]).

%% Cowboy ws callbacks
-export([websocket_handle/3, websocket_info/3,
websocket_init/3, websocket_terminate/3]).
-export([
websocket_handle/3,
websocket_info/3,
websocket_init/3,
websocket_terminate/3
]).

-include("sockjs_internal.hrl").

%% --------------------------------------------------------------------------

init(#{ref := http} = Req, Service) ->
case sockjs_handler:is_valid_ws(Service, {cowboy, Req})
of
{true, _Reason} ->
{upgrade, protocol, cowboy_websocket};
{false, _Reason} -> {ok, Req, Service}
case sockjs_handler:is_valid_ws(Service, {cowboy, Req}) of
{true, _Reason} ->
{upgrade, protocol, cowboy_websocket};
{false, _Reason} ->
{ok, Req, Service}
end.

terminate(_Reason, _Req, _Service) -> ok.

%% --------------------------------------------------------------------------

websocket_init(_TransportName, Req,
Service = #service{logger = Logger,
subproto_pref = SubProtocolPref}) ->
Req1 = case cowboy_req:header('Sec-Websocket-Protocol',
Req)
of
undefined -> Req;
SubProtocols ->
SelectedSubProtocol =
choose_subprotocol_bin(SubProtocols, SubProtocolPref),
cowboy_req:set_resp_header(#{<<"Sec-Websocket-Protocol">>
=> SelectedSubProtocol},
Req)
end,
websocket_init(
_TransportName,
Req,
Service = #service{
logger = Logger,
subproto_pref = SubProtocolPref
}
) ->
Req1 =
case
cowboy_req:header(
'Sec-Websocket-Protocol',
Req
)
of
undefined ->
Req;
SubProtocols ->
SelectedSubProtocol =
choose_subprotocol_bin(SubProtocols, SubProtocolPref),
cowboy_req:set_resp_header(
#{
<<"Sec-Websocket-Protocol">> =>
SelectedSubProtocol
},
Req
)
end,
Logger(Service, {cowboy, Req1}, websocket),
Service1 = Service#service{disconnect_delay =
5 * 60 * 1000},
Service1 = Service#service{
disconnect_delay =
5 * 60 * 1000
},
Info = sockjs_handler:extract_info(Req1),
SessionPid = sockjs_session:maybe_create(undefined,
Service1, Info),
RawWebsocket = case sockjs_handler:get_action(Service,
Req1)
of
{match, WS}
when WS =:= websocket orelse WS =:= rawwebsocket ->
WS
end,
SessionPid = sockjs_session:maybe_create(
undefined,
Service1,
Info
),
RawWebsocket =
case
sockjs_handler:get_action(
Service,
Req1
)
of
{match, WS} when WS =:= websocket orelse WS =:= rawwebsocket ->
WS
end,
self() ! go,
{ok, Req1, {RawWebsocket, SessionPid}}.

websocket_handle({text, Data}, Req,
{RawWebsocket, SessionPid} = S) ->
case sockjs_ws_handler:received(RawWebsocket,
SessionPid, Data)
of
ok -> {ok, Req, S};
shutdown -> {shutdown, Req, S}
websocket_handle(
{text, Data},
Req,
{RawWebsocket, SessionPid} = S
) ->
case
sockjs_ws_handler:received(
RawWebsocket,
SessionPid,
Data
)
of
ok -> {ok, Req, S};
shutdown -> {shutdown, Req, S}
end;
websocket_handle(_Unknown, Req, S) ->
{shutdown, Req, S}.

websocket_info(go, Req,
{RawWebsocket, SessionPid} = S) ->
case sockjs_ws_handler:reply(RawWebsocket, SessionPid)
of
wait -> {ok, Req, S};
{ok, Data} ->
self() ! go, {reply, {text, Data}, Req, S};
{close, <<>>} -> {shutdown, Req, S};
{close, Data} ->
self() ! shutdown, {reply, {text, Data}, Req, S}
websocket_info(
go,
Req,
{RawWebsocket, SessionPid} = S
) ->
case sockjs_ws_handler:reply(RawWebsocket, SessionPid) of
wait ->
{ok, Req, S};
{ok, Data} ->
self() ! go,
{reply, {text, Data}, Req, S};
{close, <<>>} ->
{shutdown, Req, S};
{close, Data} ->
self() ! shutdown,
{reply, {text, Data}, Req, S}
end;
websocket_info(shutdown, Req, S) -> {shutdown, Req, S}.
websocket_info(shutdown, Req, S) ->
{shutdown, Req, S}.

websocket_terminate(_Reason, _Req,
{RawWebsocket, SessionPid}) ->
sockjs_ws_handler:close(RawWebsocket, SessionPid), ok.
websocket_terminate(
_Reason,
_Req,
{RawWebsocket, SessionPid}
) ->
sockjs_ws_handler:close(RawWebsocket, SessionPid),
ok.

%% --------------------------------------------------------------------------

Expand All @@ -91,11 +135,14 @@ choose_subprotocol_bin(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)
case
lists:filter(
fun(E) ->
lists:member(E, SubProtocols)
end,
Pref
)
of
[Hd | _] -> Hd;
[] -> choose_subprotocol(SubProtocols, undefined)
end.
99 changes: 59 additions & 40 deletions src/sockjs_filters.erl
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
-module(sockjs_filters).

-export([cache_for/2, h_no_cache/2, h_sid/2, xhr_cors/2,
xhr_options_get/2, xhr_options_post/2]).
-export([
cache_for/2,
h_no_cache/2,
h_sid/2,
xhr_cors/2,
xhr_options_get/2,
xhr_options_post/2
]).

-include("sockjs_internal.hrl").

Expand All @@ -13,11 +19,14 @@

cache_for(Req, Headers) ->
Expires =
calendar:gregorian_seconds_to_datetime(calendar:datetime_to_gregorian_seconds(calendar:now_to_datetime(now()))
+ (?YEAR)),
H = [{"Cache-Control",
"public, max-age=" ++ integer_to_list(?YEAR)},
{"Expires", httpd_util:rfc1123_date(Expires)}],
calendar:gregorian_seconds_to_datetime(
calendar:datetime_to_gregorian_seconds(calendar:now_to_datetime(now())) +
(?YEAR)
),
H = [
{"Cache-Control", "public, max-age=" ++ integer_to_list(?YEAR)},
{"Expires", httpd_util:rfc1123_date(Expires)}
],
{H ++ Headers, Req}.

-spec h_sid(req(), headers()) -> {headers(), req()}.
Expand All @@ -28,60 +37,70 @@ h_sid(Req, Headers) ->
%% set it to a dumb value. It doesn't really matter what, as
%% session information is usually added by the load balancer.
C = sockjs_http:jsessionid(Req),
H = case C of
undefined ->
[{"Set-Cookie", "JSESSIONID=dummy; path=/"}];
Jsid ->
[{"Set-Cookie", "JSESSIONID=" ++ Jsid ++ "; path=/"}]
end,
H =
case C of
undefined ->
[{"Set-Cookie", "JSESSIONID=dummy; path=/"}];
Jsid ->
[{"Set-Cookie", "JSESSIONID=" ++ Jsid ++ "; path=/"}]
end,
H ++ Headers.

-spec h_no_cache(req(), headers()) -> {headers(),
req()}.
-spec h_no_cache(req(), headers()) -> {headers(), req()}.

h_no_cache(Req, Headers) ->
H = [{"Cache-Control",
"no-store, no-cache, must-revalidate, "
"max-age=0"}],
H = [
{"Cache-Control",
"no-store, no-cache, must-revalidate, "
"max-age=0"}
],
{H ++ Headers, Req}.

-spec xhr_cors(req(), headers()) -> {headers(), req()}.

xhr_cors(Req, Headers) ->
{OriginH, Req1} = sockjs_http:header(origin, Req),
Origin = case OriginH of
"null" -> "*";
undefined -> "*";
O -> O
end,
Origin =
case OriginH of
"null" -> "*";
undefined -> "*";
O -> O
end,
{HeadersH, Req2} =
sockjs_http:header('access-control-request-headers',
Req1),
AllowHeaders = case HeadersH of
undefined -> [];
V -> [{"Access-Control-Allow-Headers", V}]
end,
H = [{"Access-Control-Allow-Origin", Origin},
{"Access-Control-Allow-Credentials", "true"}],
sockjs_http:header(
'access-control-request-headers',
Req1
),
AllowHeaders =
case HeadersH of
undefined -> [];
V -> [{"Access-Control-Allow-Headers", V}]
end,
H = [
{"Access-Control-Allow-Origin", Origin},
{"Access-Control-Allow-Credentials", "true"}
],
{H ++ AllowHeaders ++ Headers, Req2}.

-spec xhr_options_post(req(), headers()) -> {headers(),
req()}.
-spec xhr_options_post(req(), headers()) -> {headers(), req()}.

xhr_options_post(Req, Headers) ->
xhr_options(Req, Headers, ["OPTIONS", "POST"]).

-spec xhr_options_get(req(), headers()) -> {headers(),
req()}.
-spec xhr_options_get(req(), headers()) -> {headers(), req()}.

xhr_options_get(Req, Headers) ->
xhr_options(Req, Headers, ["OPTIONS", "GET"]).

-spec xhr_options(req(), headers(),
[string()]) -> {headers(), req()}.
-spec xhr_options(
req(),
headers(),
[string()]
) -> {headers(), req()}.

xhr_options(Req, Headers, Methods) ->
H = [{"Access-Control-Allow-Methods",
string:join(Methods, ", ")},
{"Access-Control-Max-Age", integer_to_list(?YEAR)}],
H = [
{"Access-Control-Allow-Methods", string:join(Methods, ", ")},
{"Access-Control-Max-Age", integer_to_list(?YEAR)}
],
{H ++ Headers, Req}.
Loading

0 comments on commit 921b5e2

Please sign in to comment.