Packages
🐑 a fluffy Gleam web server
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
src/ewe@internal@stream@chunked.erl
-module(ewe@internal@stream@chunked).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/ewe/internal/stream/chunked.gleam").
-export([send_response/3, start/5, send_chunk/3]).
-export_type([chunked_body/0, chunked_next/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type chunked_body() :: {chunked_body,
glisten@transport:transport(),
glisten@socket:socket()}.
-type chunked_next(MJG) :: {continue, MJG} |
normal_stop |
{abnormal_stop, binary()}.
-file("src/ewe/internal/stream/chunked.gleam", 16).
?DOC(false).
-spec send_response(
gleam@http@response:response(any()),
glisten@transport:transport(),
glisten@socket:socket()
) -> {ok, nil} | {error, nil}.
send_response(Resp, Transport, Socket) ->
_pipe = case gleam@http@response:get_header(
Resp,
<<"transfer-encoding"/utf8>>
) of
{ok, <<"chunked"/utf8>>} ->
Resp;
_ ->
gleam@http@response:set_header(
Resp,
<<"transfer-encoding"/utf8>>,
<<"chunked"/utf8>>
)
end,
_pipe@1 = ewe@internal@encoder:encode_response_partially(_pipe),
_pipe@2 = glisten@transport:send(Transport, Socket, _pipe@1),
gleam@result:replace_error(_pipe@2, nil).
-file("src/ewe/internal/stream/chunked.gleam", 107).
?DOC(false).
-spec after_start(
gleam@otp@actor:started(gleam@erlang@process:subject(any())),
glisten@transport:transport(),
glisten@socket:socket()
) -> gleam@otp@actor:started(nil).
after_start(Started, Transport, Socket) ->
Pid@1 = case gleam@erlang@process:subject_owner(erlang:element(3, Started)) of
{ok, Pid} -> Pid;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"ewe/internal/stream/chunked"/utf8>>,
function => <<"after_start"/utf8>>,
line => 112,
value => _assert_fail,
start => 2994,
'end' => 3050,
pattern_start => 3005,
pattern_end => 3012})
end,
_ = glisten@transport:controlling_process(Transport, Socket, Pid@1),
{started, erlang:element(2, Started), nil}.
-file("src/ewe/internal/stream/chunked.gleam", 120).
?DOC(false).
-spec send_end(glisten@transport:transport(), glisten@socket:socket()) -> {ok,
nil} |
{error, glisten@socket:socket_reason()}.
send_end(Transport, Socket) ->
glisten@transport:send(
Transport,
Socket,
gleam@bytes_tree:from_bit_array(<<"0\r\n\r\n"/utf8>>)
).
-file("src/ewe/internal/stream/chunked.gleam", 46).
?DOC(false).
-spec start(
glisten@transport:transport(),
glisten@socket:socket(),
fun((gleam@erlang@process:subject(MJL)) -> MJN),
fun((chunked_body(), MJN, MJL) -> chunked_next(MJN)),
fun((chunked_body(), MJN) -> nil)
) -> {ok, gleam@otp@actor:started(nil)} | {error, gleam@otp@actor:start_error()}.
start(Transport, Socket, On_init, Handler, On_close) ->
_pipe@4 = gleam@otp@actor:new_with_initialiser(
1000,
fun(_) ->
Subject = gleam@erlang@process:new_subject(),
State = On_init(Subject),
Selector = begin
_pipe = gleam_erlang_ffi:new_selector(),
gleam@erlang@process:select(_pipe, Subject)
end,
_pipe@1 = gleam@otp@actor:initialised(State),
_pipe@2 = gleam@otp@actor:returning(_pipe@1, Subject),
_pipe@3 = gleam@otp@actor:selecting(_pipe@2, Selector),
{ok, _pipe@3}
end
),
_pipe@5 = gleam@otp@actor:on_message(
_pipe@4,
fun(State@1, Message) ->
Conn = {chunked_body, Transport, Socket},
case Handler(Conn, State@1, Message) of
{continue, New_state} ->
gleam@otp@actor:continue(New_state);
normal_stop ->
case send_end(Transport, Socket) of
{ok, nil} ->
On_close(Conn, State@1),
gleam@otp@actor:stop();
{error, Socket_reason} ->
logging:log(
error,
<<"Failed to send end of chunked response: "/utf8,
(gleam@string:inspect(Socket_reason))/binary>>
),
On_close(Conn, State@1),
gleam@otp@actor:stop_abnormal(
<<"Failed to send end of chunked response: "/utf8,
(gleam@string:inspect(Socket_reason))/binary>>
)
end;
{abnormal_stop, Reason} ->
logging:log(
error,
<<"Chunked response stopped abnormally: "/utf8,
Reason/binary>>
),
On_close(Conn, State@1),
gleam@otp@actor:stop_abnormal(Reason)
end
end
),
_pipe@6 = gleam@otp@actor:start(_pipe@5),
gleam@result:map(
_pipe@6,
fun(_capture) -> after_start(_capture, Transport, Socket) end
).
-file("src/ewe/internal/stream/chunked.gleam", 144).
?DOC(false).
-spec to_hex_string(integer()) -> binary().
to_hex_string(Integer) ->
erlang:integer_to_list(Integer, 16).
-file("src/ewe/internal/stream/chunked.gleam", 129).
?DOC(false).
-spec send_chunk(
glisten@transport:transport(),
glisten@socket:socket(),
bitstring()
) -> {ok, nil} | {error, glisten@socket:socket_reason()}.
send_chunk(Transport, Socket, Chunk) ->
_pipe = gleam@bytes_tree:new(),
_pipe@1 = gleam@bytes_tree:append_string(
_pipe,
to_hex_string(erlang:byte_size(Chunk))
),
_pipe@2 = gleam@bytes_tree:append(_pipe@1, <<"\r\n"/utf8>>),
_pipe@3 = gleam@bytes_tree:append(_pipe@2, Chunk),
_pipe@4 = gleam@bytes_tree:append(_pipe@3, <<"\r\n"/utf8>>),
glisten@transport:send(Transport, Socket, _pipe@4).