aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http2.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/cowboy_http2.erl')
-rw-r--r--src/cowboy_http2.erl53
1 files changed, 44 insertions, 9 deletions
diff --git a/src/cowboy_http2.erl b/src/cowboy_http2.erl
index 6018461..42d8ba5 100644
--- a/src/cowboy_http2.erl
+++ b/src/cowboy_http2.erl
@@ -86,8 +86,7 @@ init(Parent, Ref, Socket, Transport, Opts, Handler) ->
before_loop(State, Buffer) ->
loop(State, Buffer).
-loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
- handler=Handler, children=Children}, Buffer) ->
+loop(State=#state{parent=Parent, socket=Socket, transport=Transport, children=Children}, Buffer) ->
Transport:setopts(Socket, [{active, once}]),
{OK, Closed, Error} = Transport:messages(),
receive
@@ -104,7 +103,7 @@ loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent, ?MODULE, [], {State, Buffer});
%% Messages pertaining to a stream.
- {{Handler, StreamID}, Msg} ->
+ {{Pid, StreamID}, Msg} when Pid =:= self() ->
loop(info(State, StreamID, Msg), Buffer);
%% Exit signal from children.
Msg = {'EXIT', Pid, _} ->
@@ -328,8 +327,8 @@ commands(State0=#state{socket=Socket, transport=Transport, server_streamid=Promi
commands(State, StreamID, [{flow, _Size}|Tail]) ->
commands(State, StreamID, Tail);
%% Supervise a child process.
-commands(State=#state{children=Children}, StreamID, [{spawn, Pid}|Tail]) ->
- commands(State#state{children=[{Pid, StreamID}|Children]}, StreamID, Tail);
+commands(State=#state{children=Children}, StreamID, [{spawn, Pid, _Shutdown}|Tail]) -> %% @todo Shutdown
+ commands(State#state{children=[{Pid, StreamID}|Children]}, StreamID, Tail);
%% Upgrade to a new protocol.
%%
%% @todo Implementation.
@@ -357,7 +356,7 @@ terminate_all_streams([#stream{id=StreamID, state=StreamState}|Tail], Reason, Ha
%% Stream functions.
-stream_init(State0=#state{socket=Socket, transport=Transport, handler=Handler,
+stream_init(State0=#state{ref=Ref, socket=Socket, transport=Transport, handler=Handler, opts=Opts,
streams=Streams0, decode_state=DecodeState0}, StreamID, IsFin, HeaderBlock) ->
%% @todo Add clause for CONNECT requests (no scheme/path).
try headers_decode(HeaderBlock, DecodeState0) of
@@ -365,10 +364,46 @@ stream_init(State0=#state{socket=Socket, transport=Transport, handler=Handler,
<<":method">> := Method,
<<":scheme">> := Scheme,
<<":authority">> := Authority,
- <<":path">> := Path}, DecodeState} ->
+ <<":path">> := PathWithQs}, DecodeState} ->
State = State0#state{decode_state=DecodeState},
Headers = maps:without([<<":method">>, <<":scheme">>, <<":authority">>, <<":path">>], Headers0),
- try Handler:init(StreamID, IsFin, Method, Scheme, Authority, Path, Headers) of
+ %% @todo We need to parse the port out of :authority.
+ %% @todo We need to parse the query string out of :path.
+ %% @todo We need to give a way to get the socket infos.
+
+ Host = Authority, %% @todo
+ Port = todo, %% @todo
+ Path = PathWithQs, %% @todo
+ Qs = todo, %% @todo
+
+ Req = #{
+ ref => Ref,
+ pid => self(),
+ streamid => StreamID,
+
+ %% @todo peer
+ %% @todo sockname
+ %% @todo ssl client cert?
+
+ method => Method,
+ scheme => Scheme,
+ host => Host,
+ %% host_info (cowboy_router)
+ port => Port,
+ path => Path,
+ %% path_info (cowboy_router)
+ %% bindings (cowboy_router)
+ qs => Qs,
+ version => 'HTTP/2',
+ headers => Headers,
+
+ has_body => IsFin =:= nofin
+ %% @todo multipart? keep state separate
+
+ %% meta values (cowboy_websocket, cowboy_rest)
+ },
+
+ try Handler:init(StreamID, Req, Opts) of
{Commands, StreamState} ->
Streams = [#stream{id=StreamID, state=StreamState}|Streams0],
commands(State#state{streams=Streams}, StreamID, Commands)
@@ -377,7 +412,7 @@ stream_init(State0=#state{socket=Socket, transport=Transport, handler=Handler,
"with reason ~p:~p.",
[Handler, StreamID, IsFin, Method, Scheme, Authority, Path, Headers, Class, Reason]),
stream_reset(State, StreamID, {internal_error, {Class, Reason},
- 'Exception occurred in StreamHandler:init/7 call.'})
+ 'Exception occurred in StreamHandler:init/7 call.'}) %% @todo Check final arity.
end;
{_, DecodeState} ->
Transport:send(Socket, cow_http2:rst_stream(StreamID, protocol_error)),