diff options
author | Jan Uhlig <[email protected]> | 2021-09-01 14:01:47 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2021-09-01 15:30:34 +0200 |
commit | 581b6954d344eaca2bfcdab663019796e852c778 (patch) | |
tree | a20ea9f96c9fbd9251fc8c570b4e0ff485bccb98 /examples/tcp_reverse/src/reverse_protocol.erl | |
parent | c7a7cfb9b93f0db9c99ed21c34f67e0b6adfcb62 (diff) | |
download | ranch-581b6954d344eaca2bfcdab663019796e852c778.tar.gz ranch-581b6954d344eaca2bfcdab663019796e852c778.tar.bz2 ranch-581b6954d344eaca2bfcdab663019796e852c778.zip |
Update docs and modernize examples
* Use the map form for transport options everywhere
* Remove mentions of the list form for transport options
* Use a state enter call instead of gen_statem:enter_loop/4 and
proc_lib:start_link/3 in the tcp_reverse example
* Take care of different EOLs in the tcp_reverse example
* Mention state enter calls, the next_event action, and {continue, ...}
in the docs for how to use gen_statem and gen_server
Diffstat (limited to 'examples/tcp_reverse/src/reverse_protocol.erl')
-rw-r--r-- | examples/tcp_reverse/src/reverse_protocol.erl | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/examples/tcp_reverse/src/reverse_protocol.erl b/examples/tcp_reverse/src/reverse_protocol.erl index d274b3a..73d7aff 100644 --- a/examples/tcp_reverse/src/reverse_protocol.erl +++ b/examples/tcp_reverse/src/reverse_protocol.erl @@ -16,28 +16,29 @@ -define(TIMEOUT, 60000). --record(state, {socket, transport}). +-record(state, {ref, transport, socket}). %% API. start_link(Ref, Transport, Opts) -> - {ok, proc_lib:spawn_link(?MODULE, init, [{Ref, Transport, Opts}])}. + gen_statem:start_link(?MODULE, {Ref, Transport, Opts}, []). %% gen_statem. callback_mode() -> - state_functions. + [state_functions, state_enter]. init({Ref, Transport, _Opts = []}) -> + {ok, connected, #state{ref=Ref, transport=Transport}, ?TIMEOUT}. + +connected(enter, connected, StateData=#state{ + ref=Ref, transport=Transport}) -> {ok, Socket} = ranch:handshake(Ref), ok = Transport:setopts(Socket, [{active, once}, {packet, line}]), - gen_statem:enter_loop(?MODULE, [], connected, - #state{socket=Socket, transport=Transport}, - [?TIMEOUT]). - + {keep_state, StateData#state{socket=Socket}}; connected(info, {tcp, Socket, Data}, _StateData=#state{ socket=Socket, transport=Transport}) - when byte_size(Data) > 1 -> + when byte_size(Data) >= 1 -> Transport:setopts(Socket, [{active, once}]), Transport:send(Socket, reverse_binary(Data)), {keep_state_and_data, ?TIMEOUT}; @@ -57,7 +58,7 @@ connected(_EventType, _Msg, _StateData) -> terminate(Reason, StateName, StateData=#state{ socket=Socket, transport=Transport}) - when Socket=/=undefined andalso Transport=/=undefined -> + when Socket=/=undefined, Transport=/=undefined -> catch Transport:close(Socket), terminate(Reason, StateName, StateData#state{socket=undefined, transport=undefined}); @@ -69,7 +70,18 @@ code_change(_OldVsn, StateName, StateData, _Extra) -> %% Internal. -reverse_binary(B) when is_binary(B) -> - [list_to_binary(lists:reverse(binary_to_list( - binary:part(B, {0, byte_size(B)-2}) - ))), "\r\n"]. +reverse_binary(B0) when is_binary(B0) -> + Size = bit_size(B0), + <<B1:Size/integer-little>> = B0, + case <<B1:Size/integer-big>> of + %% Take care of different possible line terminators. + <<$\n, $\r, B2/binary>> -> + %% CR/LF (Windows) + <<B2/binary, $\r, $\n>>; + <<$\n, B2/binary>> -> + %% LF (Linux, Mac OS X and later) + <<B2/binary, $\n>>; + <<$\r, B2/binary>> -> + %% CR (Mac Classic, ie prior to Mac OS X) + <<B2/binary, $\r>> + end. |