Packages
mist
1.0.0
6.0.3
6.0.2
6.0.1
6.0.0
5.0.4
5.0.3
5.0.2
5.0.1
5.0.0
5.0.0-rc1
4.0.7
4.0.6
4.0.5
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
3.0.0
2.0.0
1.2.0
1.1.0
1.0.0
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
0.17.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.3
a misty Gleam web server
Current section
Files
Jump to
Current section
Files
src/mist@internal@http2@stream.erl
-module(mist@internal@http2@stream).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([make_request/2, new/5, receive_data/2]).
-export_type([message/0, stream_state/0, state/0, internal_state/0]).
-type message() :: ready | {data, bitstring(), boolean()} | done.
-type stream_state() :: open | remote_closed | local_closed | closed.
-type state() :: {state,
mist@internal@http2@frame:stream_identifier(mist@internal@http2@frame:frame()),
stream_state(),
gleam@erlang@process:subject(message()),
integer(),
integer(),
gleam@option:option(integer())}.
-type internal_state() :: {internal_state,
gleam@erlang@process:selector(message()),
gleam@erlang@process:subject(message()),
boolean(),
gleam@option:option(gleam@http@response:response(mist@internal@http:response_data())),
bitstring()}.
-spec make_request(
list({binary(), binary()}),
gleam@http@request:request(mist@internal@http:connection())
) -> {ok, gleam@http@request:request(mist@internal@http:connection())} |
{error, nil}.
make_request(Headers, Req) ->
case Headers of
[] ->
{ok, Req};
[{<<"method"/utf8>>, Method} | Rest] ->
_pipe = Method,
_pipe@1 = gleam@dynamic:from(_pipe),
_pipe@2 = gleam@http:method_from_dynamic(_pipe@1),
_pipe@3 = gleam@result:replace_error(_pipe@2, nil),
_pipe@4 = gleam@result:map(
_pipe@3,
fun(_capture) ->
gleam@http@request:set_method(Req, _capture)
end
),
gleam@result:then(
_pipe@4,
fun(_capture@1) -> make_request(Rest, _capture@1) end
);
[{<<"scheme"/utf8>>, Scheme} | Rest@1] ->
_pipe@5 = Scheme,
_pipe@6 = gleam@http:scheme_from_string(_pipe@5),
_pipe@7 = gleam@result:replace_error(_pipe@6, nil),
_pipe@8 = gleam@result:map(
_pipe@7,
fun(_capture@2) ->
gleam@http@request:set_scheme(Req, _capture@2)
end
),
gleam@result:then(
_pipe@8,
fun(_capture@3) -> make_request(Rest@1, _capture@3) end
);
[{<<"authority"/utf8>>, _} | Rest@2] ->
make_request(Rest@2, Req);
[{<<"path"/utf8>>, Path} | Rest@3] ->
_pipe@9 = Path,
_pipe@10 = gleam@string:split_once(_pipe@9, <<"?"/utf8>>),
_pipe@14 = gleam@result:map(
_pipe@10,
fun(Split) ->
gleam@pair:map_second(Split, fun(Query) -> _pipe@11 = Query,
_pipe@12 = gleam@uri:parse_query(_pipe@11),
_pipe@13 = gleam@result:map(
_pipe@12,
fun(Field@0) -> {some, Field@0} end
),
gleam@result:unwrap(_pipe@13, none) end)
end
),
_pipe@15 = gleam@result:unwrap(_pipe@14, {Path, none}),
(fun(Tup) -> _pipe@18 = case erlang:element(2, Tup) of
{some, Query@1} ->
_pipe@16 = Req,
_pipe@17 = gleam@http@request:set_path(
_pipe@16,
erlang:element(1, Tup)
),
gleam@http@request:set_query(_pipe@17, Query@1);
_ ->
gleam@http@request:set_path(Req, erlang:element(1, Tup))
end,
make_request(Rest@3, _pipe@18) end)(_pipe@15);
[{Key, Value} | Rest@4] ->
_pipe@19 = Req,
_pipe@20 = gleam@http@request:set_header(_pipe@19, Key, Value),
make_request(Rest@4, _pipe@20)
end.
-spec new(
fun((gleam@http@request:request(mist@internal@http:connection())) -> gleam@http@response:response(mist@internal@http:response_data())),
list({binary(), binary()}),
mist@internal@http:connection(),
fun((gleam@http@response:response(mist@internal@http:response_data())) -> any()),
boolean()
) -> {ok, gleam@erlang@process:subject(message())} |
{error, gleam@otp@actor:start_error()}.
new(Handler, Headers, Connection, Send, End) ->
gleam@otp@actor:start_spec(
{spec,
fun() ->
Data_subj = gleam@erlang@process:new_subject(),
Data_selector = begin
_pipe = gleam_erlang_ffi:new_selector(),
gleam@erlang@process:selecting(
_pipe,
Data_subj,
fun gleam@function:identity/1
)
end,
{ready,
{internal_state, Data_selector, Data_subj, End, none, <<>>},
Data_selector}
end,
1000,
fun(Msg, State) -> case {Msg, erlang:element(4, State)} of
{ready, _} ->
Content_length = begin
_pipe@1 = Headers,
_pipe@2 = gleam@list:key_find(
_pipe@1,
<<"content-length"/utf8>>
),
_pipe@3 = gleam@result:then(
_pipe@2,
fun gleam@int:parse/1
),
gleam@result:unwrap(_pipe@3, 0)
end,
Conn = erlang:setelement(
2,
Connection,
{stream,
gleam_erlang_ffi:map_selector(
erlang:element(2, State),
fun(Val) ->
{data, Bits, _} = case Val of
{data, _, _} -> Val;
_assert_fail ->
erlang:error(
#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"mist/internal/http2/stream"/utf8>>,
function => <<"new"/utf8>>,
line => 89}
)
end,
Bits
end
),
<<>>,
Content_length,
0}
),
_pipe@4 = gleam@http@request:new(),
_pipe@5 = gleam@http@request:set_body(_pipe@4, Conn),
_pipe@6 = make_request(Headers, _pipe@5),
_pipe@7 = gleam@result:map(_pipe@6, Handler),
_pipe@8 = gleam@result:map(
_pipe@7,
fun(Resp) ->
gleam@erlang@process:send(
erlang:element(3, State),
done
),
gleam@otp@actor:continue(
erlang:setelement(5, State, {some, Resp})
)
end
),
_pipe@9 = gleam@result:map_error(
_pipe@8,
fun(Err) ->
{stop,
{abnormal,
<<"Failed to respond to request: "/utf8,
(gleam@erlang:format(Err))/binary>>}}
end
),
gleam@result:unwrap_both(_pipe@9);
{done, true} ->
_assert_subject = erlang:element(5, State),
{some, Resp@1} = case _assert_subject of
{some, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"mist/internal/http2/stream"/utf8>>,
function => <<"new"/utf8>>,
line => 116})
end,
Send(Resp@1),
gleam@otp@actor:continue(State);
{{data, Bits@1, true}, _} ->
gleam@erlang@process:send(
erlang:element(3, State),
done
),
gleam@otp@actor:continue(
erlang:setelement(
6,
erlang:setelement(4, State, true),
<<(erlang:element(6, State))/bitstring,
Bits@1/bitstring>>
)
);
{{data, Bits@2, _}, _} ->
gleam@otp@actor:continue(
erlang:setelement(
6,
State,
<<(erlang:element(6, State))/bitstring,
Bits@2/bitstring>>
)
);
{_, _} ->
gleam@otp@actor:continue(State)
end end}
).
-spec receive_data(state(), integer()) -> {state(), integer()}.
receive_data(State, Size) ->
_assert_subject = mist@internal@http2@flow_control:compute_receive_window(
erlang:element(5, State),
Size
),
{New_window_size, Increment} = case _assert_subject of
{_, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"mist/internal/http2/stream"/utf8>>,
function => <<"receive_data"/utf8>>,
line => 202})
end,
New_state = erlang:setelement(
7,
erlang:setelement(5, State, New_window_size),
gleam@option:map(erlang:element(7, State), fun(Val) -> Val - Size end)
),
{New_state, Increment}.