mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 04:10:24 +00:00
WIP fixes for Chromium
This commit is contained in:
parent
ee534f4e2b
commit
46c53cd4fb
6 changed files with 94 additions and 7 deletions
|
@ -95,8 +95,12 @@ start_quic(Ref, TransOpts, ProtoOpts) ->
|
|||
end,
|
||||
SocketOpts = [
|
||||
{alpn, ["h3"]}, %% @todo Why not binary?
|
||||
{peer_unidi_stream_count, 3}, %% We only need control and QPACK enc/dec.
|
||||
{peer_bidi_stream_count, 100}
|
||||
{peer_unidi_stream_count, 100}, %% We only need control and QPACK enc/dec.
|
||||
{peer_bidi_stream_count, 100},
|
||||
%% For WebTransport. @todo Also increase default unidi stream count.
|
||||
%% @todo We probably don't want it enabled if WT isn't used.
|
||||
{datagram_send_enabled, 1},
|
||||
{datagram_receive_enabled, 1}
|
||||
|SocketOpts2],
|
||||
_ListenerPid = spawn(fun() ->
|
||||
{ok, Listener} = quicer:listen(Port, SocketOpts),
|
||||
|
|
|
@ -716,9 +716,10 @@ commands(State, Stream, [Error = {internal_error, _, _}|_Tail]) ->
|
|||
reset_stream(State, Stream, Error);
|
||||
%% Use a different protocol within the stream (CONNECT :protocol).
|
||||
%% @todo Make sure we error out when the feature is disabled.
|
||||
commands(State0=#state{http3_machine=HTTP3Machine0}, Stream0=#stream{id=StreamID},
|
||||
commands(State0, Stream0=#stream{id=StreamID},
|
||||
[{switch_protocol, Headers, cowboy_webtransport, WTState=#{}}|Tail]) ->
|
||||
State = info(stream_store(State0, Stream0), StreamID, {headers, 200, Headers}),
|
||||
#state{http3_machine=HTTP3Machine0} = State,
|
||||
Stream1 = #stream{state=StreamState} = stream_get(State, StreamID),
|
||||
%% The stream becomes a WT session at that point. It is the
|
||||
%% parent stream of all streams in this WT session. The
|
||||
|
@ -864,7 +865,7 @@ webtransport_event(State, SessionID, Event) ->
|
|||
ok.
|
||||
|
||||
webtransport_commands(State, SessionID, Commands) ->
|
||||
Session = #stream{status=webtransport_session} = stream_get(SessionID, State),
|
||||
Session = #stream{status=webtransport_session} = stream_get(State, SessionID),
|
||||
wt_commands(State, Session, Commands).
|
||||
|
||||
wt_commands(State, _, []) ->
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
-export_type([opts/0]).
|
||||
|
||||
-record(state, {
|
||||
id :: cow_http3:stream_id(),
|
||||
parent :: pid(),
|
||||
opts = #{} :: opts(),
|
||||
handler :: module(),
|
||||
|
@ -72,7 +73,7 @@ upgrade(Req=#{version := 'HTTP/3', pid := Pid, streamid := StreamID}, Env, Handl
|
|||
FilterFun -> FilterFun(Req)
|
||||
end,
|
||||
%% @todo add parent, ref, streamid here directly
|
||||
State = #state{parent=Pid, opts=Opts, handler=Handler, req=FilteredReq},
|
||||
State = #state{id=StreamID, parent=Pid, opts=Opts, handler=Handler, req=FilteredReq},
|
||||
|
||||
%% @todo Must check is_upgrade_request (rename, not an upgrade)
|
||||
%% and also ensure that all the relevant settings are enabled (quic and h3)
|
||||
|
@ -179,8 +180,8 @@ handler_call_result(State0, HandlerState, Commands) ->
|
|||
|
||||
commands([], State, []) ->
|
||||
{ok, State};
|
||||
commands([], State=#state{parent=Pid}, Commands) ->
|
||||
Pid ! {'$webtransport_commands', lists:reverse(Commands)},
|
||||
commands([], State=#state{id=SessionID, parent=Pid}, Commands) ->
|
||||
Pid ! {'$webtransport_commands', SessionID, lists:reverse(Commands)},
|
||||
{ok, State};
|
||||
%% {open_stream, OpenStreamRef, StreamType, InitialData}.
|
||||
commands([Command={open_stream, _, _, _}|Tail], State, Acc) ->
|
||||
|
|
|
@ -53,6 +53,7 @@ init_http3(Ref, ProtoOpts, Config) ->
|
|||
},
|
||||
{ok, Listener} = cowboy:start_quic(Ref, TransOpts, ProtoOpts),
|
||||
{ok, {_, Port}} = quicer:sockname(Listener),
|
||||
ct:pal("port ~p", [Port]),
|
||||
%% @todo Keep listener information around in a better place.
|
||||
persistent_term:put({cowboy_test_quic, Ref}, Listener),
|
||||
[{ref, Ref}, {type, quic}, {protocol, http3}, {port, Port}, {opts, TransOpts}|Config].
|
||||
|
|
59
test/draft_h3_webtransport_SUITE.erl
Normal file
59
test/draft_h3_webtransport_SUITE.erl
Normal file
|
@ -0,0 +1,59 @@
|
|||
%% Copyright (c) Loïc Hoguin <essen@ninenines.eu>
|
||||
%%
|
||||
%% Permission to use, copy, modify, and/or distribute this software for any
|
||||
%% purpose with or without fee is hereby granted, provided that the above
|
||||
%% copyright notice and this permission notice appear in all copies.
|
||||
%%
|
||||
%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
-module(draft_h3_webtransport_SUITE).
|
||||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
|
||||
-import(ct_helper, [config/2]).
|
||||
-import(ct_helper, [doc/1]).
|
||||
|
||||
all() ->
|
||||
[{group, enabled}].
|
||||
|
||||
groups() ->
|
||||
Tests = ct_helper:all(?MODULE),
|
||||
[{enabled, [], Tests}]. %% @todo Enable parallel when all is better.
|
||||
|
||||
init_per_group(Name = enabled, Config) ->
|
||||
cowboy_test:init_http3(Name, #{
|
||||
enable_connect_protocol => true,
|
||||
h3_datagram => true,
|
||||
enable_webtransport => true, %% For compatibility with draft-02.
|
||||
webtransport_max_sessions => 10,
|
||||
env => #{dispatch => cowboy_router:compile(init_routes(Config))}
|
||||
}, Config).
|
||||
|
||||
end_per_group(Name, _) ->
|
||||
cowboy_test:stop_group(Name).
|
||||
|
||||
init_routes(_) -> [
|
||||
{"localhost", [
|
||||
{"/wt", wt_echo_h, []}
|
||||
]}
|
||||
].
|
||||
|
||||
%% Temporary.
|
||||
|
||||
%% To start Chromium the command line is roughly:
|
||||
%% chromium --ignore-certificate-errors-spki-list=LeLykt63i2FRAm+XO91yBoSjKfrXnAFygqe5xt0zgDA= --ignore-certificate-errors --user-data-dir=/tmp/chromium-wt --allow-insecure-localhost --webtransport-developer-mode --enable-quic https://googlechrome.github.io/samples/webtransport/client.html
|
||||
%%
|
||||
%% To find the SPKI the command is roughly:
|
||||
%% openssl x509 -in ~/ninenines/cowboy/test/rfc9114_SUITE_data/server.pem -pubkey -noout | \
|
||||
%% openssl pkey -pubin -outform der | \
|
||||
%% openssl dgst -sha256 -binary | \
|
||||
%% openssl enc -base64
|
||||
|
||||
run(_Config) ->
|
||||
timer:sleep(infinity).
|
21
test/handlers/wt_echo_h.erl
Normal file
21
test/handlers/wt_echo_h.erl
Normal file
|
@ -0,0 +1,21 @@
|
|||
%% This module echoes client events back,
|
||||
%% including creating new streams.
|
||||
|
||||
-module(wt_echo_h).
|
||||
%% @todo -behavior(cowboy_webtransport).
|
||||
|
||||
-export([init/2]).
|
||||
-export([webtransport_handle/2]).
|
||||
|
||||
init(Req, _) ->
|
||||
{cowboy_webtransport, Req, undefined}.
|
||||
|
||||
%% @todo WT handle {stream_open,4,bidi}
|
||||
%% @todo WT handle {stream_data,4,nofin,<<>>} %% skip?
|
||||
|
||||
webtransport_handle(Event = {stream_data, StreamID, IsFin, Data}, HandlerState) ->
|
||||
ct:pal("WT handle ~p~n", [Event]),
|
||||
{[{send, StreamID, Data}], HandlerState};
|
||||
webtransport_handle(Event, HandlerState) ->
|
||||
ct:pal("WT handle ~p~n", [Event]),
|
||||
{[], HandlerState}.
|
Loading…
Add table
Add a link
Reference in a new issue