Current section

Files

Jump to
dream src dream@servers@mist@handler.erl
Raw

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.
?MODULEDOC(
" Request handler for Mist server\n"
"\n"
" This module provides handler creation functionality that converts\n"
" Mist requests to Dream requests, routes them, and converts the\n"
" response back to Mist format.\n"
"\n"
" This is an internal module used by the Dream server implementation.\n"
" Most applications won't need to use this directly.\n"
).
-file("src/dream/servers/mist/handler.gleam", 161).
-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", 187).
-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", 148).
-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_req, Partial_req) ->
case mist:stream(Mist_req) of
{ok, Chunk_provider} ->
Stream = gleam@yielder:unfold(Chunk_provider, fun stream_unfolder/1),
{ok,
{request,
erlang:element(2, Partial_req),
erlang:element(3, Partial_req),
erlang:element(4, Partial_req),
erlang:element(5, Partial_req),
erlang:element(6, Partial_req),
erlang:element(7, Partial_req),
erlang:element(8, Partial_req),
erlang:element(9, Partial_req),
erlang:element(10, Partial_req),
erlang:element(11, Partial_req),
{some, Stream},
erlang:element(13, Partial_req),
erlang:element(14, Partial_req),
erlang:element(15, Partial_req),
erlang:element(16, Partial_req)}};
{error, _} ->
{error, bad_request_response()}
end.
-file("src/dream/servers/mist/handler.gleam", 172).
-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_req, Partial_req, Max_body_size) ->
case mist:read_body(Mist_req, Max_body_size) of
{ok, Req_with_body} ->
Body_string = begin
_pipe = gleam@bit_array:to_string(
erlang:element(4, Req_with_body)
),
gleam@result:unwrap(_pipe, <<""/utf8>>)
end,
{ok,
{request,
erlang:element(2, Partial_req),
erlang:element(3, Partial_req),
erlang:element(4, Partial_req),
erlang:element(5, Partial_req),
erlang:element(6, Partial_req),
erlang:element(7, Partial_req),
erlang:element(8, Partial_req),
erlang:element(9, Partial_req),
erlang:element(10, Partial_req),
Body_string,
erlang:element(12, Partial_req),
erlang:element(13, Partial_req),
erlang:element(14, Partial_req),
erlang:element(15, Partial_req),
erlang:element(16, Partial_req)}};
{error, _} ->
{error, bad_request_response()}
end.
-file("src/dream/servers/mist/handler.gleam", 113).
-spec handle_routed_request(
gleam@http@request:request(mist@internal@http:connection()),
dream@http@request:request(),
dream@router:route(AEEA, AEEB),
list({binary(), binary()}),
integer(),
AEEA,
AEEB
) -> gleam@http@response:response(mist:response_data()).
handle_routed_request(
Mist_req,
Partial_req,
Route,
Params,
Max_body_size,
Request_context,
Services_instance
) ->
Final_req_result = case erlang:element(6, Route) of
true ->
prepare_streaming_request(Mist_req, Partial_req);
false ->
prepare_buffered_request(Mist_req, Partial_req, Max_body_size)
end,
case Final_req_result of
{ok, Final_req} ->
Dream_response = dream@dream:execute_route(
Route,
Final_req,
Params,
Request_context,
Services_instance
),
dream@servers@mist@response:convert(Dream_response);
{error, Response} ->
Response
end.
-file("src/dream/servers/mist/handler.gleam", 67).
?DOC(" Create the request handler function that processes Mist requests\n").
-spec create_request_handler(
dream@router:router(AEDT, AEDU),
integer(),
AEDT,
AEDU,
fun((AEDT, binary()) -> AEDT)
) -> 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_req) ->
{Partial_req, Request_id} = dream@servers@mist@request:convert_metadata(
Mist_req
),
case dream@router:find_route(Router, Partial_req) of
{some, {Route, Params}} ->
Request_context = Update_context(Template_context, Request_id),
handle_routed_request(
Mist_req,
Partial_req,
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
end.
-file("src/dream/servers/mist/handler.gleam", 49).
?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"
"\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(AEDN, AEDO),
integer(),
AEDN,
AEDO,
fun((AEDN, binary()) -> AEDN)
) -> 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
).