Skip to content

Commit

Permalink
Merge pull request #4 from etxemag75/etxemag75-patch-3
Browse files Browse the repository at this point in the history
Cowboy 2.x support
  • Loading branch information
etxemag75 authored Sep 18, 2018
2 parents cc4213b + 6a4178f commit fbcad87
Showing 1 changed file with 66 additions and 63 deletions.
129 changes: 66 additions & 63 deletions src/cowboy_bridge_modules/cowboy_simple_bridge_anchor.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,97 +2,100 @@

-module(cowboy_simple_bridge_anchor).
-export([
init/3,
init/2,
handle/2,
terminate/3,
websocket_init/3,
websocket_handle/3,
websocket_info/3,
websocket_terminate/3
terminate/2,
websocket_init/1,
websocket_handle/2,
websocket_info/2,
websocket_terminate/2
]).

-record(ws_state, {handler, keepalive_interval, bridge, state}).
-record(ws_state, {handler, keepalive_interval, bridge, state, init_req}).

init(_Transport, Req, _Opts) ->
{Upgrade, _} = cowboy_req:header(<<"upgrade">>, Req),
init(Req, State) ->
Upgrade = cowboy_req:header(<<"upgrade">>, Req),
Upgrade2 = case Upgrade of
undefined -> undefined;
Other -> simple_bridge_util:binarize_header(Other)
end,

undefined -> undefined;
Other -> simple_bridge_util:binarize_header(Other)
end,
case Upgrade2 == <<"websocket">> of
true ->
{upgrade, protocol, cowboy_websocket};
false ->
{ok, Req, []}
end.
true ->
%% Keepalive stuff
{KAInterval, KATimeout} = simple_bridge_util:get_websocket_keepalive_interval_timeout(cowboy),
CowboyTimeout = simple_bridge_websocket:keepalive_timeout(KAInterval, KATimeout),

%% START YOUR ENGINES, FOLKS!
WSState = #ws_state{init_req = Req,
keepalive_interval=KAInterval},
{cowboy_websocket, Req, WSState, #{idle_timeout => CowboyTimeout}};
false ->
DocRoot = simple_bridge_util:get_env(document_root),
Handler = simple_bridge_util:get_env(handler),
Bridge = simple_bridge:make(cowboy, {Req, DocRoot}),
{ok, NewReq} = Handler:run(Bridge),
{ok, NewReq, State}
end.


handle(Req, State) ->
DocRoot = simple_bridge_util:get_env(document_root),
Handler = simple_bridge_util:get_env(handler),
Bridge = simple_bridge:make(cowboy, {Req, DocRoot}),
{ok, NewReq} = Handler:run(Bridge),
{ok, NewReq, State}.
{ok, Req, State}.

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

websocket_init(_Transport, Req, _Opts) ->
%% Init stuff
{ok, Handler} = application:get_env(simple_bridge, handler),
Bridge = simple_bridge:make(cowboy, {Req, ""}),
UserState = simple_bridge_websocket:call_init(Handler, Bridge),
websocket_init(State) ->

%% Keepalive stuff
{KAInterval, KATimeout} = simple_bridge_util:get_websocket_keepalive_interval_timeout(cowboy),
CowboyTimeout = simple_bridge_websocket:keepalive_timeout(KAInterval, KATimeout),
simple_bridge_websocket:schedule_keepalive_msg(KAInterval),
{ok, Handler} = application:get_env(simple_bridge, handler),
Bridge = simple_bridge:make(cowboy, {State#ws_state.init_req, ""}),

UserState = simple_bridge_websocket:call_init(Handler, Bridge),
simple_bridge_websocket:schedule_keepalive_msg(State#ws_state.keepalive_interval),

%% START YOUR ENGINES, FOLKS!
WSState = #ws_state{bridge=Bridge,
keepalive_interval=KAInterval,
handler=Handler,
state=UserState},
{ok, Req, WSState, CowboyTimeout}.
WSState = State#ws_state{state=UserState,
init_req = undefined,
bridge=Bridge,
handler=Handler
},
{ok, WSState}.

websocket_handle({ping, _Data}, Req, WSState) ->
websocket_handle({ping, _Data}, WSState) ->
%% We don't need to pong, cowboy does that automatically. So just carry on!
{ok, Req, WSState};
websocket_handle({pong, _PongMsg}, Req, WSState) ->
{ok, Req, WSState};
websocket_handle(Data, Req, WSState) ->
{ok, WSState};
websocket_handle({pong, _PongMsg}, WSState) ->
{ok, WSState};
websocket_handle(Data, WSState) ->
#ws_state{handler=Handler, bridge=Bridge, state=State} = WSState,
Result = Handler:ws_message(Data, Bridge, State),
massage_reply(Result, Req, WSState).
massage_reply(Result, WSState).

websocket_info(simple_bridge_send_ping, Req, WSState=#ws_state{keepalive_interval=KAInterval}) ->
websocket_info(simple_bridge_send_ping, WSState=#ws_state{keepalive_interval=KAInterval}) ->
simple_bridge_websocket:schedule_keepalive_msg(KAInterval),
{reply, {ping, <<"Simple Bridge Ping">>}, Req, WSState};
{reply, {ping, <<"Simple Bridge Ping">>}, WSState};

websocket_info(Data, Req, WSState) ->
websocket_info(Data, WSState) ->
#ws_state{handler=Handler, bridge=Bridge, state=State} = WSState,
Result = Handler:ws_info(Data, Bridge, State),
massage_reply(Result, Req, WSState).
massage_reply(Result, WSState).

websocket_terminate(Reason, _Req, #ws_state{bridge=Bridge, handler=Handler, state=State}) ->
websocket_terminate(Reason, #ws_state{bridge=Bridge, handler=Handler, state=State}) ->
ok = Handler:ws_terminate(Reason, Bridge, State).


%% MASSAGE_REPLY reformats a simple_bridge return value into something that can
%% be handled by cowboy.
massage_reply({reply, {Type, Data}, NewState}, Req, WSState)
massage_reply({reply, {Type, Data}, NewState}, WSState)
when Type==binary orelse Type==text ->
{reply, {Type, iolist_to_binary(Data)}, Req, WSState#ws_state{state=NewState}};
massage_reply({reply, List, NewState}, Req, WSState) ->
{reply, {Type, iolist_to_binary(Data)}, WSState#ws_state{state=NewState}};
massage_reply({reply, List, NewState}, WSState) ->
FixedList = [{Type, iolist_to_binary(Data)} || {Type, Data} <- List],
{reply, FixedList, Req, WSState#ws_state{state=NewState}};
massage_reply({reply, Reply}, Req, WSState) ->
massage_reply({reply, Reply, WSState#ws_state.state}, Req, WSState);
massage_reply({noreply, NewState}, Req, WSState) ->
{ok, Req, WSState#ws_state{state=NewState}};
massage_reply(noreply, Req, WSState) ->
{ok, Req, WSState};
massage_reply({close, _Reason}, Req, WSState) ->
{shutdown, Req, WSState};
massage_reply(close, Req, WSState) ->
{shutdown, Req, WSState}.
{reply, FixedList, WSState#ws_state{state=NewState}};
massage_reply({reply, Reply}, WSState) ->
massage_reply({reply, Reply, WSState#ws_state.state}, WSState);
massage_reply({noreply, NewState}, WSState) ->
{ok, WSState#ws_state{state=NewState}};
massage_reply({remote, _Reason}, WSState) ->
{stop, WSState};
massage_reply(stop, WSState) ->
{stop, WSState}.

0 comments on commit fbcad87

Please sign in to comment.