-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 ).