Current section
Files
Jump to
Current section
Files
src/dream@servers@mist@handler.erl
-module(dream@servers@mist@handler).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream/servers/mist/handler.gleam").
-export([create/5]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/dream/servers/mist/handler.gleam", 177).
-spec stream_unfolder(
fun((integer()) -> {ok, mist:chunk()} | {error, mist:read_error()})
) -> gleam@yielder:step(bitstring(), fun((integer()) -> {ok, mist:chunk()} |
{error, mist:read_error()})).
stream_unfolder(Provider) ->
case Provider(65536) of
{ok, {chunk, Data, Next_provider}} ->
{next, Data, Next_provider};
{ok, done} ->
done;
{error, _} ->
done
end.
-file("src/dream/servers/mist/handler.gleam", 203).
-spec bad_request_response() -> gleam@http@response:response(mist:response_data()).
bad_request_response() ->
_pipe = gleam@http@response:new(400),
gleam@http@response:set_body(_pipe, {bytes, gleam@bytes_tree:new()}).
-file("src/dream/servers/mist/handler.gleam", 164).
-spec prepare_streaming_request(
gleam@http@request:request(mist@internal@http:connection()),
dream@http@request:request()
) -> {ok, dream@http@request:request()} |
{error, gleam@http@response:response(mist:response_data())}.
prepare_streaming_request(Mist_request, Partial_request) ->
case mist:stream(Mist_request) of
{ok, Chunk_provider} ->
Stream = gleam@yielder:unfold(Chunk_provider, fun stream_unfolder/1),
{ok,
{request,
erlang:element(2, Partial_request),
erlang:element(3, Partial_request),
erlang:element(4, Partial_request),
erlang:element(5, Partial_request),
erlang:element(6, Partial_request),
erlang:element(7, Partial_request),
erlang:element(8, Partial_request),
erlang:element(9, Partial_request),
erlang:element(10, Partial_request),
erlang:element(11, Partial_request),
{some, Stream},
erlang:element(13, Partial_request),
erlang:element(14, Partial_request),
erlang:element(15, Partial_request),
erlang:element(16, Partial_request)}};
{error, _} ->
{error, bad_request_response()}
end.
-file("src/dream/servers/mist/handler.gleam", 188).
-spec prepare_buffered_request(
gleam@http@request:request(mist@internal@http:connection()),
dream@http@request:request(),
integer()
) -> {ok, dream@http@request:request()} |
{error, gleam@http@response:response(mist:response_data())}.
prepare_buffered_request(Mist_request, Partial_request, Max_body_size) ->
case mist:read_body(Mist_request, Max_body_size) of
{ok, Request_with_body} ->
Body_string = begin
_pipe = gleam@bit_array:to_string(
erlang:element(4, Request_with_body)
),
gleam@result:unwrap(_pipe, <<""/utf8>>)
end,
{ok,
{request,
erlang:element(2, Partial_request),
erlang:element(3, Partial_request),
erlang:element(4, Partial_request),
erlang:element(5, Partial_request),
erlang:element(6, Partial_request),
erlang:element(7, Partial_request),
erlang:element(8, Partial_request),
erlang:element(9, Partial_request),
erlang:element(10, Partial_request),
Body_string,
erlang:element(12, Partial_request),
erlang:element(13, Partial_request),
erlang:element(14, Partial_request),
erlang:element(15, Partial_request),
erlang:element(16, Partial_request)}};
{error, _} ->
{error, bad_request_response()}
end.
-file("src/dream/servers/mist/handler.gleam", 128).
-spec handle_routed_request(
gleam@http@request:request(mist@internal@http:connection()),
dream@http@request:request(),
dream@router:route(AHHE, AHHF),
list({binary(), binary()}),
integer(),
AHHE,
AHHF
) -> gleam@http@response:response(mist:response_data()).
handle_routed_request(
Mist_request,
Partial_request,
Route,
Params,
Max_body_size,
Request_context,
Services_instance
) ->
Final_request_result = case erlang:element(6, Route) of
true ->
prepare_streaming_request(Mist_request, Partial_request);
false ->
prepare_buffered_request(
Mist_request,
Partial_request,
Max_body_size
)
end,
case Final_request_result of
{ok, Final_request} ->
Dream_response = dream@dream:execute_route(
Route,
Final_request,
Params,
Request_context,
Services_instance
),
dream@servers@mist@response:convert(Dream_response);
{error, Response} ->
Response
end.
-file("src/dream/servers/mist/handler.gleam", 63).
?DOC(" Create the request handler function that processes Mist requests\n").
-spec create_request_handler(
dream@router:router(AHGX, AHGY),
integer(),
AHGX,
AHGY,
fun((AHGX, binary()) -> AHGX)
) -> fun((gleam@http@request:request(mist@internal@http:connection())) -> gleam@http@response:response(mist:response_data())).
create_request_handler(
Router,
Max_body_size,
Template_context,
Services_instance,
Update_context
) ->
fun(Mist_request) ->
Request_key = erlang:binary_to_atom(<<"dream_mist_request"/utf8>>),
erlang:put(Request_key, gleam_stdlib:identity(Mist_request)),
Response_key = erlang:binary_to_atom(<<"dream_mist_response"/utf8>>),
erlang:put(Response_key, gleam_stdlib:identity(none)),
{Partial_request, Request_id} = dream@servers@mist@request:convert_metadata(
Mist_request
),
Dream_response@1 = case dream@router:find_route(Router, Partial_request) of
{some, {Route, Params}} ->
Request_context = Update_context(Template_context, Request_id),
handle_routed_request(
Mist_request,
Partial_request,
Route,
Params,
Max_body_size,
Request_context,
Services_instance
);
none ->
Dream_response = {response,
404,
{text, <<"Route not found"/utf8>>},
[{header,
<<"Content-Type"/utf8>>,
<<"text/plain; charset=utf-8"/utf8>>}],
[],
{some, <<"text/plain; charset=utf-8"/utf8>>}},
dream@servers@mist@response:convert(Dream_response)
end,
Raw_upgrade = erlang:get(Response_key),
Upgrade_result = gleam_stdlib:identity(Raw_upgrade),
case Upgrade_result of
{some, Mist_response} ->
Mist_response;
none ->
Dream_response@1
end
end.
-file("src/dream/servers/mist/handler.gleam", 45).
?DOC(
" Create a request handler that converts Mist requests to Dream requests\n"
"\n"
" This function creates the main request handler used by the Mist server.\n"
" It handles the complete request/response cycle:\n"
"\n"
" 1. Convert Mist request headers/metadata to Dream request\n"
" 2. Match route to determine if body should be buffered or streamed\n"
" 3. Read body (buffered) or wrap stream (streaming)\n"
" 4. Route the request through the router\n"
" 5. Convert Dream response back to Mist format\n"
" 6. Handle HTTP → WebSocket upgrades when a controller calls\n"
" `websocket.upgrade_websocket` (the upgrade response is stashed and\n"
" returned here instead of a normal HTTP response)\n"
"\n"
" ## Parameters\n"
"\n"
" - `router`: The application's router with all routes configured\n"
" - `max_body_size`: Maximum allowed request body size in bytes\n"
" - `template_context`: Template context to clone for each request\n"
" - `services_instance`: Application services (database, cache, etc.)\n"
" - `update_context`: Function to update context with request-specific data\n"
"\n"
" ## Returns\n"
"\n"
" A function that takes a Mist HTTP request and returns a Mist HTTP response.\n"
" This function is what you pass to `mist.new()`.\n"
).
-spec create(
dream@router:router(AHGR, AHGS),
integer(),
AHGR,
AHGS,
fun((AHGR, binary()) -> AHGR)
) -> fun((gleam@http@request:request(mist@internal@http:connection())) -> gleam@http@response:response(mist:response_data())).
create(
Router,
Max_body_size,
Template_context,
Services_instance,
Update_context
) ->
create_request_handler(
Router,
Max_body_size,
Template_context,
Services_instance,
Update_context
).