Packages
mist
4.0.4
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@handler.erl
-module(mist@internal@handler).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new_state/1, init/1, with_func/1]).
-export_type([handler_error/0, state/0]).
-type handler_error() :: {invalid_request, mist@internal@http:decode_error()} |
not_found.
-type state() :: {http1,
mist@internal@http@handler:state(),
gleam@erlang@process:subject(mist@internal@http2@handler:message())} |
{http2, mist@internal@http2@handler:state()}.
-file("/home/alex/gleams/mist/src/mist/internal/handler.gleam", 29).
-spec new_state(
gleam@erlang@process:subject(mist@internal@http2@handler:message())
) -> state().
new_state(Subj) ->
{http1, mist@internal@http@handler:initial_state(), Subj}.
-file("/home/alex/gleams/mist/src/mist/internal/handler.gleam", 33).
-spec init(any()) -> {state(),
gleam@option:option(gleam@erlang@process:selector(mist@internal@http2@handler:message()))}.
init(_) ->
Subj = gleam@erlang@process:new_subject(),
Selector = begin
_pipe = gleam_erlang_ffi:new_selector(),
gleam@erlang@process:selecting(
_pipe,
Subj,
fun gleam@function:identity/1
)
end,
{new_state(Subj), {some, Selector}}.
-file("/home/alex/gleams/mist/src/mist/internal/handler.gleam", 42).
-spec with_func(
fun((gleam@http@request:request(mist@internal@http:connection())) -> gleam@http@response:response(mist@internal@http:response_data()))
) -> fun((glisten:message(mist@internal@http2@handler:message()), state(), glisten:connection(mist@internal@http2@handler:message())) -> gleam@otp@actor:next(glisten:message(mist@internal@http2@handler:message()), state())).
with_func(Handler) ->
fun(Msg, State, Conn) ->
Sender = erlang:element(4, Conn),
Conn@1 = {connection,
{initial, <<>>},
erlang:element(2, Conn),
erlang:element(3, Conn)},
_pipe@12 = case {Msg, State} of
{{user, {send, _, _}}, {http1, _, _}} ->
{error,
{abnormal,
<<"Attempted to send HTTP/2 response without upgrade"/utf8>>}};
{{user, {send, Id, Resp}}, {http2, State@1}} ->
_pipe@2 = case erlang:element(4, Resp) of
{bytes, Bytes} ->
_pipe = Resp,
_pipe@1 = gleam@http@response:set_body(_pipe, Bytes),
mist@internal@http2:send_bytes_tree(
_pipe@1,
Conn@1,
erlang:element(7, State@1),
Id
);
{file, _, _, _} ->
{error,
{abnormal,
<<"File sending unsupported over HTTP/2"/utf8>>}};
{websocket, _} ->
{error,
{abnormal,
<<"WebSocket unsupported for HTTP/2"/utf8>>}};
{chunked, _} ->
{error,
{abnormal,
<<"Chunked encoding not supported for HTTP/2"/utf8>>}};
{server_sent_events, _} ->
{error,
{abnormal,
<<"Server-Sent Events unsupported for HTTP/2"/utf8>>}}
end,
_pipe@3 = gleam@result:map(
_pipe@2,
fun(Context) ->
{http2,
mist@internal@http2@handler:send_hpack_context(
State@1,
Context
)}
end
),
gleam@result:map_error(
_pipe@3,
fun(Err) ->
logging:log(
debug,
<<"Error sending HTTP/2 data: "/utf8,
(gleam@string:inspect(Err))/binary>>
),
Err
end
);
{{packet, Msg@1}, {http1, State@2, Self}} ->
_ = case erlang:element(2, State@2) of
{some, T} ->
gleam@erlang@process:cancel_timer(T);
_ ->
timer_not_found
end,
_pipe@4 = Msg@1,
_pipe@5 = mist@internal@http:parse_request(_pipe@4, Conn@1),
_pipe@6 = gleam@result:map_error(
_pipe@5,
fun(Err@1) -> case Err@1 of
discard_packet ->
normal;
_ ->
logging:log(error, gleam@string:inspect(Err@1)),
_ = glisten@transport:close(
erlang:element(4, Conn@1),
erlang:element(3, Conn@1)
),
{abnormal, <<"Received invalid request"/utf8>>}
end end
),
gleam@result:then(_pipe@6, fun(Req) -> case Req of
{http1_request, Req@1, Version} ->
_pipe@7 = mist@internal@http@handler:call(
Req@1,
Handler,
Conn@1,
Sender,
Version
),
gleam@result:map(
_pipe@7,
fun(New_state) ->
{http1, New_state, Self}
end
);
{upgrade, Data} ->
_pipe@8 = mist@internal@http2@handler:upgrade(
Data,
Conn@1,
Self
),
gleam@result:map(
_pipe@8,
fun(Field@0) -> {http2, Field@0} end
)
end end);
{{packet, Msg@2}, {http2, State@3}} ->
_pipe@9 = State@3,
_pipe@10 = mist@internal@http2@handler:append_data(
_pipe@9,
Msg@2
),
_pipe@11 = mist@internal@http2@handler:call(
_pipe@10,
Conn@1,
Handler
),
gleam@result:map(_pipe@11, fun(Field@0) -> {http2, Field@0} end)
end,
_pipe@13 = gleam@result:map(_pipe@12, fun gleam@otp@actor:continue/1),
_pipe@14 = gleam@result:map_error(
_pipe@13,
fun(Field@0) -> {stop, Field@0} end
),
gleam@result:unwrap_both(_pipe@14)
end.