Current section
Files
Jump to
Current section
Files
src/dream@servers@mist@request.erl
-module(dream@servers@mist@request).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream/servers/mist/request.gleam").
-export([generate_request_id/0, convert/2]).
-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 conversion from Mist to Dream format\n"
"\n"
" This module provides functions to convert Mist HTTP requests\n"
" to Dream request format, including method, header, and cookie conversion.\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/request.gleam", 46).
?DOC(
" Generate a simple request ID\n"
"\n"
" Creates a request ID using the current process ID.\n"
" This provides a unique identifier for each request that can be used\n"
" for logging, tracing, and debugging.\n"
"\n"
" In production applications, you may want to use UUID or a more\n"
" sophisticated ID generation strategy.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let request_id = generate_request_id()\n"
" // Returns something like: \"#PID<0.123.0>\"\n"
" ```\n"
).
-spec generate_request_id() -> binary().
generate_request_id() ->
Pid = erlang:self(),
Pid_string = gleam@string:inspect(Pid),
Pid_string.
-file("src/dream/servers/mist/request.gleam", 168).
?DOC(" Convert HTTP method from gleam/http format to Dream format\n").
-spec convert_method(gleam@http:method()) -> dream@http@request:method().
convert_method(Http_method) ->
case Http_method of
get ->
get;
post ->
post;
put ->
put;
delete ->
delete;
patch ->
patch;
options ->
options;
head ->
head;
{other, _} ->
get;
connect ->
get;
trace ->
get
end.
-file("src/dream/servers/mist/request.gleam", 186).
-spec convert_header({binary(), binary()}) -> dream@http@header:header().
convert_header(Header) ->
{header, erlang:element(1, Header), erlang:element(2, Header)}.
-file("src/dream/servers/mist/request.gleam", 190).
-spec format_ip_address_value(mist:ip_address()) -> binary().
format_ip_address_value(Ip_address) ->
case Ip_address of
{ip_v4, A, B, C, D} ->
gleam@string:join(
[erlang:integer_to_binary(A),
<<"."/utf8>>,
erlang:integer_to_binary(B),
<<"."/utf8>>,
erlang:integer_to_binary(C),
<<"."/utf8>>,
erlang:integer_to_binary(D)],
<<""/utf8>>
);
{ip_v6, _, _, _, _, _, _, _, _} ->
<<"::1"/utf8>>
end.
-file("src/dream/servers/mist/request.gleam", 91).
?DOC(
" Convert Mist request to Dream request format\n"
"\n"
" Converts a Mist HTTP request (with Erlang/BEAM specific types) to\n"
" Dream's unified request format. This includes converting:\n"
"\n"
" - HTTP method (from gleam/http to dream/http/request)\n"
" - Protocol and version (HTTP/HTTPS, HTTP/1.1)\n"
" - Headers and cookies\n"
" - Request body (from BitArray to String)\n"
" - Client information (IP address, port)\n"
"\n"
" Returns a tuple with the Dream Request and a generated request ID.\n"
"\n"
" ## Parameters\n"
"\n"
" - `mist_req`: The original Mist request with Connection\n"
" - `req_with_body`: The same request but with body read as BitArray\n"
"\n"
" ## Returns\n"
"\n"
" A tuple of `#(Dream Request, request_id)` where:\n"
" - Dream Request contains all HTTP data in Dream's format\n"
" - request_id is a unique identifier for this request\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" // Internal use - normally called by the request handler\n"
" let body_result = mist.read_body(mist_req, max_body_limit: 10_000_000)\n"
"\n"
" case body_result {\n"
" Ok(req_with_body) -> {\n"
" let #(dream_req, request_id) = convert(mist_req, req_with_body)\n"
" // Now use dream_req in your router\n"
" }\n"
" Error(_) -> // Handle error\n"
" }\n"
" ```\n"
).
-spec convert(
gleam@http@request:request(mist@internal@http:connection()),
gleam@http@request:request(bitstring())
) -> {dream@http@request:request(), binary()}.
convert(Mist_req, Req_with_body) ->
Request_id = generate_request_id(),
Method = convert_method(erlang:element(2, Mist_req)),
Protocol = case erlang:element(5, Mist_req) of
http ->
http;
https ->
https
end,
Version = http1,
Path = erlang:element(8, Mist_req),
Query = gleam@option:unwrap(erlang:element(9, Mist_req), <<""/utf8>>),
Headers = gleam@list:map(erlang:element(3, Mist_req), fun convert_header/1),
Cookies = dream@dream:parse_cookies_from_headers(Headers),
Content_type = begin
_pipe = gleam@list:key_find(
erlang:element(3, Mist_req),
<<"content-type"/utf8>>
),
gleam@option:from_result(_pipe)
end,
Content_length = begin
_pipe@1 = gleam@list:key_find(
erlang:element(3, Mist_req),
<<"content-length"/utf8>>
),
_pipe@2 = gleam@result:'try'(_pipe@1, fun gleam_stdlib:parse_int/1),
gleam@option:from_result(_pipe@2)
end,
Body_string = begin
_pipe@3 = gleam@bit_array:to_string(erlang:element(4, Req_with_body)),
gleam@result:unwrap(_pipe@3, <<""/utf8>>)
end,
Client_info = mist:get_client_info(erlang:element(4, Mist_req)),
Remote_address = case Client_info of
{ok, Info} ->
Ip_address = erlang:element(3, Info),
_pipe@4 = format_ip_address_value(Ip_address),
{some, _pipe@4};
{error, _} ->
none
end,
Request = {request,
Method,
Protocol,
Version,
Path,
Query,
[],
{some, erlang:element(6, Mist_req)},
erlang:element(7, Mist_req),
Remote_address,
Body_string,
Headers,
Cookies,
Content_type,
Content_length},
{Request, Request_id}.