Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/chatterbox_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ init([]) ->

Http2Settings = chatterbox:settings(server),

{ok, StatemOptions} = application:get_env(chatterbox, statem_server_options, []),

spawn_link(fun empty_listeners/0),
{ok, ListenSocket} = gen_tcp:listen(Port, Options),
Restart = {simple_one_for_one, 60, 3600},
Children = [{socket,
{h2_connection, start_server_link, [{Transport, ListenSocket}, SSLOptions, Http2Settings]},
{h2_connection, start_server_link, [{Transport, ListenSocket}, SSLOptions, Http2Settings, StatemOptions]},
temporary, 1000, worker, [h2_connection]}],
{ok, {Restart, Children}}.

Expand Down
38 changes: 30 additions & 8 deletions src/h2_client.erl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
start_link/2,
start_link/3,
start_link/4,
start_link/5,
start/4,
start_ssl_upgrade_link/4,
start_ssl_upgrade_link/5,
stop/1,
send_request/3,
send_ping/1,
Expand Down Expand Up @@ -90,6 +92,17 @@ start_link(https, Host, SSLOptions)
start_link(https, Host, 443, SSLOptions).


-spec start_link(http | https,
string(),
non_neg_integer(),
[ssl:ssl_option()]) ->
{ok, pid()}
| ignore
| {error, term()}.

start_link(Transport, Host, Port, SSLOptions) ->
start_link(Transport, Host, Port, SSLOptions, []).

%% Here's your all access client starter. MAXIMUM TUNABLES! Scheme,
%% Hostname, Port and SSLOptions. All of the start_link/* calls come
%% through here eventually, so this is where we turn 'http' and
Expand All @@ -98,33 +111,42 @@ start_link(https, Host, SSLOptions)
-spec start_link(http | https,
string(),
non_neg_integer(),
[ssl:ssl_option()]) ->
[ssl:ssl_option()],
[gen_statem:start_opt()]) ->
{ok, pid()}
| ignore
| {error, term()}.
start_link(Transport, Host, Port, SSLOptions) ->

start_link(Transport, Host, Port, SSLOptions, StatemOptions) ->
NewT = case Transport of
http -> gen_tcp;
https -> ssl
end,
h2_connection:start_client_link(NewT, Host, Port, SSLOptions, chatterbox:settings(client)).
h2_connection:start_client_link(NewT, Host, Port, SSLOptions, chatterbox:settings(client), StatemOptions).

-spec start(http | https,
string(),
non_neg_integer(),
[ssl:ssl_option()]) ->
string(),
non_neg_integer(),
[ssl:ssl_option()],
[gen_statem:start_opt()]) ->
{ok, pid()}
| ignore
| {error, term()}.
start(Transport, Host, Port, SSLOptions) ->
start(Transport, Host, Port, SSLOptions, []).

start(Transport, Host, Port, SSLOptions, StatemOptions) ->
NewT = case Transport of
http -> gen_tcp;
https -> ssl
end,
h2_connection:start_client(NewT, Host, Port, SSLOptions, chatterbox:settings(client)).
h2_connection:start_client(NewT, Host, Port, SSLOptions, chatterbox:settings(client), StatemOptions).

start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions) ->
h2_connection:start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions, chatterbox:settings(client)).
start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions, []).

start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions, StatemOptions) ->
h2_connection:start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions, chatterbox:settings(client), StatemOptions).

-spec stop(pid()) -> ok.
stop(Pid) ->
Expand Down
112 changes: 97 additions & 15 deletions src/h2_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
%% Start/Stop API
-export([
start_client/2,
start_client/3,
start_client/5,
start_client/6,
start_client_link/2,
start_client_link/3,
start_client_link/5,
start_client_link/6,
start_ssl_upgrade_link/5,
start_ssl_upgrade_link/6,
start_server_link/3,
start_server_link/4,
become/1,
become/2,
become/3,
Expand Down Expand Up @@ -82,6 +88,7 @@
-record(connection, {
type = undefined :: client | server | undefined,
ssl_options = [],
statem_options = [] :: [gen_statem:start_opt()],
listen_ref :: non_neg_integer() | undefined,
socket = undefined :: sock:socket(),
peer_settings = #settings{} :: settings(),
Expand Down Expand Up @@ -122,7 +129,20 @@
) ->
{ok, pid()} | ignore | {error, term()}.
start_client_link(Transport, Host, Port, SSLOptions, Http2Settings) ->
gen_statem:start_link(?MODULE, {client, Transport, Host, Port, SSLOptions, Http2Settings}, []).
start_client_link(Transport, Host, Port, SSLOptions, Http2Settings, []).

-spec start_client_link(gen_tcp | ssl,
inet:ip_address() | inet:hostname(),
inet:port_number(),
[ssl:ssl_option()],
settings(),
[gen_statem:start_opt()]
) ->
{ok, pid()} | ignore | {error, term()}.
start_client_link(Transport, Host, Port, SSLOptions, Http2Settings, StatemOptions) ->
gen_statem:start_link(?MODULE,
{client, Transport, Host, Port, SSLOptions, Http2Settings},
StatemOptions).

-spec start_client(gen_tcp | ssl,
inet:ip_address() | inet:hostname(),
Expand All @@ -132,21 +152,54 @@ start_client_link(Transport, Host, Port, SSLOptions, Http2Settings) ->
) ->
{ok, pid()} | ignore | {error, term()}.
start_client(Transport, Host, Port, SSLOptions, Http2Settings) ->
gen_statem:start(?MODULE, {client, Transport, Host, Port, SSLOptions, Http2Settings}, []).
start_client(Transport, Host, Port, SSLOptions, Http2Settings, []).

-spec start_client(gen_tcp | ssl,
inet:ip_address() | inet:hostname(),
inet:port_number(),
[ssl:ssl_option()],
settings(),
[gen_statem:start_opt()]
) ->
{ok, pid()} | ignore | {error, term()}.
start_client(Transport, Host, Port, SSLOptions, Http2Settings, StatemOptions) ->
gen_statem:start(?MODULE,
{client, Transport, Host, Port, SSLOptions, Http2Settings},
StatemOptions).

-spec start_client_link(socket(),
settings()
) ->
{ok, pid()} | ignore | {error, term()}.
start_client_link({Transport, Socket}, Http2Settings) ->
gen_statem:start_link(?MODULE, {client, {Transport, Socket}, Http2Settings}, []).
start_client_link({Transport, Socket}, Http2Settings, []).

-spec start_client(socket(),
settings()
-spec start_client_link(socket(),
settings(),
[gen_statem:start_opt()]
) ->
{ok, pid()} | ignore | {error, term()}.
start_client_link({Transport, Socket}, Http2Settings, StatemOptions) ->
gen_statem:start_link(?MODULE,
{client, {Transport, Socket}, Http2Settings},
StatemOptions).

-spec start_client(socket(),
settings()
) ->
{ok, pid()} | ignore | {error, term()}.
start_client({Transport, Socket}, Http2Settings) ->
gen_statem:start(?MODULE, {client, {Transport, Socket}, Http2Settings}, []).
start_client({Transport, Socket}, Http2Settings, []).

-spec start_client(socket(),
settings(),
[gen_statem:start_opt()]
) ->
{ok, pid()} | ignore | {error, term()}.
start_client({Transport, Socket}, Http2Settings, StatemOptions) ->
gen_statem:start(?MODULE,
{client, {Transport, Socket}, Http2Settings},
StatemOptions).

-spec start_ssl_upgrade_link(inet:ip_address() | inet:hostname(),
inet:port_number(),
Expand All @@ -156,14 +209,37 @@ start_client({Transport, Socket}, Http2Settings) ->
) ->
{ok, pid()} | ignore | {error, term()}.
start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions, Http2Settings) ->
gen_statem:start_link(?MODULE, {client_ssl_upgrade, Host, Port, InitialMessage, SSLOptions, Http2Settings}, []).
start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions, Http2Settings, []).

-spec start_ssl_upgrade_link(inet:ip_address() | inet:hostname(),
inet:port_number(),
binary(),
[ssl:ssl_option()],
settings(),
[gen_statem:start_opt()]
) ->
{ok, pid()} | ignore | {error, term()}.
start_ssl_upgrade_link(Host, Port, InitialMessage, SSLOptions, Http2Settings, StatemOptions) ->
gen_statem:start_link(?MODULE,
{client_ssl_upgrade, Host, Port, InitialMessage, SSLOptions, Http2Settings},
StatemOptions).

-spec start_server_link(socket(),
[ssl:ssl_option()],
#settings{}) ->
settings()) ->
{ok, pid()} | ignore | {error, term()}.
start_server_link({Transport, ListenSocket}, SSLOptions, Http2Settings) ->
gen_statem:start_link(?MODULE, {server, {Transport, ListenSocket}, SSLOptions, Http2Settings}, []).
start_server_link({Transport, ListenSocket}, SSLOptions, Http2Settings, []).

-spec start_server_link(socket(),
[ssl:ssl_option()],
settings(),
[gen_statem:start_opt()]) ->
{ok, pid()} | ignore | {error, term()}.
start_server_link({Transport, ListenSocket}, SSLOptions, Http2Settings, StatemOptions) ->
gen_statem:start_link(?MODULE,
{server, {Transport, ListenSocket}, SSLOptions, Http2Settings},
StatemOptions).

-spec become(socket()) -> no_return().
become(Socket) ->
Expand All @@ -185,7 +261,8 @@ become({Transport, Socket}, Http2Settings, ConnectionSettings) ->
maps:get(stream_callback_opts, ConnectionSettings,
application:get_env(chatterbox, stream_callback_opts, [])),
streams = h2_stream_set:new(server),
socket = {Transport, Socket}
socket = {Transport, Socket},
statem_options = application:get_env(chatterbox, statem_server_options, [])
}) of
{_, handshake, NewState} ->
gen_statem:enter_loop(?MODULE,
Expand Down Expand Up @@ -214,7 +291,8 @@ init({client, {Transport, Socket}, Http2Settings}) ->
streams = h2_stream_set:new(client),
socket = {Transport, Socket},
next_available_stream_id=1,
flow_control=application:get_env(chatterbox, client_flow_control, auto)
flow_control=application:get_env(chatterbox, client_flow_control, auto),
statem_options=application:get_env(chatterbox, statem_client_options, [])
},
{ok,
handshake,
Expand Down Expand Up @@ -660,7 +738,8 @@ route_frame({#frame_header{type=?HEADERS}=FH, _Payload}=Frame,
Conn#connection.socket,
(Conn#connection.peer_settings)#settings.initial_window_size,
(Conn#connection.self_settings)#settings.initial_window_size,
Streams) of
Streams,
Conn#connection.statem_options) of
{error, ErrorCode, NewStream} ->
rst_stream(NewStream, ErrorCode, Conn),
{none, Conn};
Expand Down Expand Up @@ -769,7 +848,8 @@ route_frame({H=#frame_header{
Conn#connection.socket,
(Conn#connection.peer_settings)#settings.initial_window_size,
(Conn#connection.self_settings)#settings.initial_window_size,
Streams),
Streams,
Conn#connection.statem_options),

Continuation = #continuation_state{
stream_id=StreamId,
Expand Down Expand Up @@ -1170,7 +1250,8 @@ handle_event({call, From}, {new_stream, NotifyPid},
Conn#connection.socket,
Conn#connection.peer_settings#settings.initial_window_size,
Conn#connection.self_settings#settings.initial_window_size,
Streams)
Streams,
Conn#connection.statem_options)
of
{error, Code, _NewStream} ->
%% TODO: probably want to have events like this available for metrics
Expand Down Expand Up @@ -1681,7 +1762,8 @@ send_request(NextId, NotifyPid, Conn, Streams, Headers, Body) ->
Conn#connection.socket,
Conn#connection.peer_settings#settings.initial_window_size,
Conn#connection.self_settings#settings.initial_window_size,
Streams)
Streams,
Conn#connection.statem_options)
of
{error, Code, _NewStream} ->
%% error creating new stream
Expand Down
15 changes: 14 additions & 1 deletion src/h2_stream.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
%% Public API
-export([
start_link/5,
start_link/6,
send_event/2,
send_pp/2,
send_data/2,
Expand Down Expand Up @@ -105,13 +106,25 @@
) ->
{ok, pid()} | ignore | {error, term()}.
start_link(StreamId, Connection, CallbackModule, CallbackOptions, Socket) ->
start_link(StreamId, Connection, CallbackModule, CallbackOptions, Socket, []).

-spec start_link(
StreamId :: stream_id(),
Connection :: pid(),
CallbackModule :: module(),
CallbackOptions :: list(),
Socket :: sock:socket(),
[gen_statem:start_opt()]
) ->
{ok, pid()} | ignore | {error, term()}.
start_link(StreamId, Connection, CallbackModule, CallbackOptions, Socket, StatemOptions) ->
gen_statem:start_link(?MODULE,
[StreamId,
Connection,
CallbackModule,
CallbackOptions,
Socket],
[]).
StatemOptions).

send_event(Pid, Event) ->
gen_statem:cast(Pid, Event).
Expand Down
Loading