Skip to content

Commit

Permalink
More todos and types/Dialyzer fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
essen committed Mar 5, 2024
1 parent 07edd6c commit 4c95816
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 17 deletions.
8 changes: 5 additions & 3 deletions src/cowboy_http3.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

%% Whether the stream is currently in a special state.
status :: header | {unidi, control | encoder | decoder}
| normal | {data, non_neg_integer()} | stopping,
| normal | {data | ignore, non_neg_integer()} | stopping,

%% Stream buffer.
buffer = <<>> :: binary(),
Expand Down Expand Up @@ -465,7 +465,7 @@ early_error(State0=#state{opts=Opts, peer=Peer},
Class, Exception, Stacktrace), Opts),
%% We still need to send an error response, so send what we initially
%% wanted to send. It's better than nothing.
send_headers(State0, StreamID, fin, StatusCode0, RespHeaders0)
send_headers(State0, Stream, fin, StatusCode0, RespHeaders0)
end.


Expand Down Expand Up @@ -842,9 +842,11 @@ stream_abort_receive(State=#state{conn=Conn}, Stream=#stream{id=StreamID}, Reaso

%% @todo Graceful connection shutdown.
%% We terminate the connection immediately if it hasn't fully been initialized.
-spec goaway(#state{}, {goaway, _}) -> no_return().
goaway(State, {goaway, _}) ->
terminate(State, {stop, goaway, 'The connection is going away.'}).

-spec terminate(#state{}, _) -> no_return().
terminate(State=#state{conn=Conn, %http3_status=Status,
%http3_machine=HTTP3Machine,
streams=Streams, children=Children}, Reason) ->
Expand All @@ -860,7 +862,7 @@ terminate(State=#state{conn=Conn, %http3_status=Status,
terminate_all_streams(State, maps:to_list(Streams), Reason),
cowboy_children:terminate(Children),
% terminate_linger(State),
cowboy_quicer:shutdown(Conn, cow_http3:error_to_code(terminate_reason(Reason))),
_ = cowboy_quicer:shutdown(Conn, cow_http3:error_to_code(terminate_reason(Reason))),
exit({shutdown, Reason}).

terminate_reason({connection_error, Reason, _}) -> Reason;
Expand Down
73 changes: 59 additions & 14 deletions src/cowboy_quicer.erl
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,58 @@

-ifndef(COWBOY_QUICER).

%% @todo Error out on all callbacks.
-spec peername(_) -> no_return().
peername(_) -> no_quicer().

-spec sockname(_) -> no_return().
sockname(_) -> no_quicer().

-spec shutdown(_, _) -> no_return().
shutdown(_, _) -> no_quicer().

-spec start_unidi_stream(_, _) -> no_return().
start_unidi_stream(_, _) -> no_quicer().

-spec send(_, _, _) -> no_return().
send(_, _, _) -> no_quicer().

-spec send(_, _, _, _) -> no_return().
send(_, _, _, _) -> no_quicer().

-spec shutdown_stream(_, _, _, _) -> no_return().
shutdown_stream(_, _, _, _) -> no_quicer().

-spec handle(_) -> no_return().
handle(_) -> no_quicer().

no_quicer() ->
error({no_quicer,
"Cowboy must be compiled with environment variable COWBOY_QUICER=1 "
"or with compilation flag -D COWBOY_QUICER=1 in order to enable "
"QUIC support using the emqx/quic NIF"}).

-else.

-include_lib("quicer/include/quicer.hrl").

%% Connection.

-spec peername(_) -> _. %% @todo
-spec peername(quicer:connection_handle())
-> {ok, {inet:ip_address(), inet:port_number()}}
| {error, any()}.

peername(Conn) ->
quicer:peername(Conn).

-spec sockname(_) -> _. %% @todo
-spec sockname(quicer:connection_handle())
-> {ok, {inet:ip_address(), inet:port_number()}}
| {error, any()}.

sockname(Conn) ->
quicer:sockname(Conn).

-spec shutdown(_, _) -> _. %% @todo
-spec shutdown(quicer:connection_handle(), quicer:app_errno())
-> ok | {error, any()}.

shutdown(Conn, ErrorCode) ->
quicer:shutdown_connection(Conn,
Expand All @@ -61,22 +94,27 @@ shutdown(Conn, ErrorCode) ->

%% Streams.

-spec start_unidi_stream(_, _) -> _. %% @todo
-spec start_unidi_stream(quicer:connection_handle(), iodata())
-> {ok, cow_http3:stream_id()}.

start_unidi_stream(Conn, HeaderData) ->
{ok, StreamRef} = quicer:start_stream(Conn,
#{open_flag => ?QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL}),
{ok, StreamRef} = quicer:start_stream(Conn, #{
active => true,
open_flag => ?QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL
}),
{ok, _} = quicer:send(StreamRef, HeaderData),
{ok, StreamID} = quicer:get_stream_id(StreamRef),
put({quicer_stream, StreamID}, StreamRef),
{ok, StreamID}.

-spec send(_, _, _) -> _. %% @todo
-spec send(quicer:connection_handle(), cow_http3:stream_id(), iodata())
-> ok | {error, any()}.

send(Conn, StreamID, Data) ->
send(Conn, StreamID, Data, nofin).

-spec send(_, _, _, _) -> _. %% @todo
-spec send(quicer:connection_handle(), cow_http3:stream_id(), iodata(), cow_http:fin())
-> ok | {error, any()}.

send(_Conn, StreamID, Data, IsFin) ->
StreamRef = get({quicer_stream, StreamID}),
Expand All @@ -89,11 +127,13 @@ send(_Conn, StreamID, Data, IsFin) ->
send_flag(nofin) -> ?QUIC_SEND_FLAG_NONE;
send_flag(fin) -> ?QUIC_SEND_FLAG_FIN.

-spec shutdown_stream(_, _, _, _) -> _. %% @todo
-spec shutdown_stream(quicer:connection_handle(),
cow_http3:stream_id(), both | receiving, quicer:app_errno())
-> ok.

shutdown_stream(_Conn, StreamID, Dir, ErrorCode) ->
StreamRef = get({quicer_stream, StreamID}),
quicer:shutdown_stream(StreamRef, shutdown_flag(Dir), ErrorCode, infinity),
_ = quicer:shutdown_stream(StreamRef, shutdown_flag(Dir), ErrorCode, infinity),
% ct:pal("~p shutdown_stream res ~p", [self(), Res]),
ok.

Expand All @@ -102,8 +142,13 @@ shutdown_flag(receiving) -> ?QUIC_STREAM_SHUTDOWN_FLAG_ABORT_RECEIVE.

%% Messages.

%% @todo Probably should have the Conn given too?
-spec handle(_) -> _. %% @todo
%% @todo Probably should have the Conn given as argument too?
-spec handle({quic, _, _, _})
-> {data, cow_http3:stream_id(), cow_http:fin(), binary()}
| {stream_started, cow_http3:stream_id(), unidi | bidi}
| {stream_closed, cow_http3:stream_id(), quicer:app_errno()}
| closed
| ok.

handle({quic, Data, StreamRef, #{flags := Flags}}) when is_binary(Data) ->
{ok, StreamID} = quicer:get_stream_id(StreamRef),
Expand All @@ -128,7 +173,7 @@ handle({quic, stream_closed, StreamRef, #{error := ErrorCode}}) ->
{stream_closed, StreamID, ErrorCode};
%% QUIC_CONNECTION_EVENT_SHUTDOWN_COMPLETE.
handle({quic, closed, Conn, _Flags}) ->
quicer:close_connection(Conn),
_ = quicer:close_connection(Conn),
closed;
%% The following events are currently ignored either because
%% I do not know what they do or because we do not need to
Expand Down

0 comments on commit 4c95816

Please sign in to comment.