Packages
mist
0.1.3
6.0.3
6.0.2
6.0.1
6.0.0
5.0.4
5.0.3
5.0.2
5.0.1
5.0.0
5.0.0-rc1
4.0.7
4.0.6
4.0.5
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
3.0.0
2.0.0
1.2.0
1.1.0
1.0.0
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
0.17.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.3
a misty Gleam web server
Current section
Files
Jump to
Current section
Files
src/mist.erl
-module(mist).
-compile(no_auto_import).
-export([from_header/1, parse_headers/2, parse_request/1, code_to_string/1, headers/1, to_string/1, http_response/2, hello_world/2, make_handler/1, listen/2, start_acceptor_pool/3]).
-export_type([packet_type/0, http_uri/0, http_packet/0, decoded_packet/0, decode_error/0]).
-type packet_type() :: http | httph_bin.
-type http_uri() :: {abs_path, gleam@erlang@charlist:charlist()}.
-type http_packet() :: {http_request,
gleam@erlang@atom:atom_(),
http_uri(),
{integer(), integer()}} |
{http_header,
integer(),
gleam@erlang@atom:atom_(),
bitstring(),
bitstring()}.
-type decoded_packet() :: {binary_data, http_packet(), bitstring()} |
{end_of_headers, bitstring()} |
{more_data, gleam@option:option(integer())}.
-type decode_error() :: invalid_method | unknown_header.
-spec from_header(bitstring()) -> binary().
from_header(Value) ->
{ok, Value@2} = case gleam@bit_string:to_string(Value) of
{ok, Value@1} -> {ok, Value@1};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"mist"/utf8>>,
function => <<"from_header"/utf8>>,
line => 54})
end,
gleam@string:lowercase(Value@2).
-spec parse_headers(bitstring(), list({binary(), binary()})) -> {ok,
{list({binary(),
binary()}),
bitstring()}} |
{error, decode_error()}.
parse_headers(Bs, Headers) ->
case glisten_ffi:decode_packet(httph_bin, Bs, []) of
{ok, {binary_data, {http_header, _@1, _@2, Field, Value}, Rest}} ->
Field@1 = from_header(Field),
Value@1 = from_header(Value),
parse_headers(Rest, [{Field@1, Value@1} | Headers]);
{ok, {end_of_headers, Rest@1}} ->
{ok, {Headers, Rest@1}};
_@3 ->
{error, unknown_header}
end.
-spec parse_request(bitstring()) -> {ok,
gleam@http@request:request(bitstring())} |
{error, decode_error()}.
parse_request(Bs) ->
case glisten_ffi:decode_packet(http, Bs, []) of
{error, _try} -> {error, _try};
{ok, {binary_data, Req, Rest}} ->
{http_request, Method@1, {abs_path, Path@1}, _@2} = case Req of
{http_request, Method, {abs_path, Path}, _@1} -> {http_request,
Method,
{abs_path,
Path},
_@1};
_try@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@1,
module => <<"mist"/utf8>>,
function => <<"parse_request"/utf8>>,
line => 77})
end,
case begin
_pipe = Method@1,
_pipe@1 = gleam@erlang@atom:to_string(_pipe),
_pipe@2 = gleam@http:parse_method(_pipe@1),
gleam@result:replace_error(_pipe@2, invalid_method)
end of
{error, _try@2} -> {error, _try@2};
{ok, Method@2} ->
case parse_headers(Rest, []) of
{error, _try@3} -> {error, _try@3};
{ok, {Headers, Rest@1}} ->
Req@1 = begin
_pipe@3 = gleam@http@request:new(),
_pipe@4 = gleam@http@request:set_body(
_pipe@3,
Rest@1
),
_pipe@5 = gleam@http@request:set_method(
_pipe@4,
Method@2
),
gleam@http@request:set_path(
_pipe@5,
gleam@erlang@charlist:to_string(Path@1)
)
end,
{ok, erlang:setelement(3, Req@1, Headers)}
end
end
end.
-spec code_to_string(integer()) -> binary().
code_to_string(Code) ->
case Code of
200 ->
<<"Ok"/utf8>>;
_@1 ->
<<"Unknown"/utf8>>
end.
-spec headers(gleam@http@response:response(bitstring())) -> gleam@string_builder:string_builder().
headers(Resp) ->
gleam@list:fold(
erlang:element(3, Resp),
gleam@string_builder:from_string(<<""/utf8>>),
fun(Builder, Tup) ->
{Header, Value} = Tup,
_pipe = gleam@string_builder:from_strings(
[Header, <<": "/utf8>>, Value, <<"\r\n"/utf8>>]
),
gleam@string_builder:append_builder(Builder, _pipe)
end
).
-spec to_string(gleam@http@response:response(bitstring())) -> bitstring().
to_string(Resp) ->
Body_builder = case gleam@bit_string:byte_size(erlang:element(4, Resp)) of
0 ->
gleam@string_builder:from_string(<<""/utf8>>);
_@1 ->
_pipe = erlang:element(4, Resp),
_pipe@1 = gleam@bit_string:to_string(_pipe),
_pipe@2 = gleam@result:unwrap(_pipe@1, <<""/utf8>>),
_pipe@3 = gleam@string_builder:from_string(_pipe@2),
gleam@string_builder:append(_pipe@3, <<"\r\n"/utf8>>)
end,
_pipe@4 = <<"HTTP/1.1 "/utf8>>,
_pipe@5 = gleam@string_builder:from_string(_pipe@4),
_pipe@6 = gleam@string_builder:append(
_pipe@5,
gleam@int:to_string(erlang:element(2, Resp))
),
_pipe@7 = gleam@string_builder:append(_pipe@6, <<"\r\n"/utf8>>),
_pipe@8 = gleam@string_builder:append_builder(_pipe@7, headers(Resp)),
_pipe@9 = gleam@string_builder:append(_pipe@8, <<"\r\n\r\n"/utf8>>),
_pipe@10 = gleam@string_builder:append_builder(_pipe@9, Body_builder),
_pipe@11 = gleam@string_builder:to_string(_pipe@10),
gleam@bit_string:from_string(_pipe@11).
-spec http_response(integer(), bitstring()) -> bitstring().
http_response(Status, Body) ->
_pipe = gleam@http@response:new(Status),
_pipe@1 = gleam@http@response:set_body(_pipe, Body),
_pipe@2 = gleam@http@response:prepend_header(
_pipe@1,
<<"Content-Type"/utf8>>,
<<"text/plain"/utf8>>
),
_pipe@6 = gleam@http@response:prepend_header(
_pipe@2,
<<"Content-Length"/utf8>>,
begin
_pipe@3 = Body,
_pipe@4 = gleam@bit_string:byte_size(_pipe@3),
_pipe@5 = (fun(Size) -> Size + 1 end)(_pipe@4),
gleam@int:to_string(_pipe@5)
end
),
to_string(_pipe@6).
-spec hello_world(glisten@tcp:handler_message(), glisten@tcp:socket()) -> gleam@otp@actor:next(glisten@tcp:socket()).
hello_world(_, Sock) ->
{ok, Resp@1} = case begin
_pipe = <<"hello, world!"/utf8>>,
_pipe@1 = gleam@bit_string:from_string(_pipe),
_pipe@2 = http_response(200, _pipe@1),
gleam@bit_string:to_string(_pipe@2)
end of
{ok, Resp} -> {ok, Resp};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"mist"/utf8>>,
function => <<"hello_world"/utf8>>,
line => 155})
end,
_pipe@3 = Resp@1,
_pipe@4 = gleam@erlang@charlist:from_string(_pipe@3),
glisten_ffi:send(Sock, _pipe@4),
{stop, normal}.
-spec make_handler(
fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(bitstring()))
) -> fun((glisten@tcp:handler_message(), glisten@tcp:socket()) -> gleam@otp@actor:next(glisten@tcp:socket())).
make_handler(Handler) ->
fun(Msg, Sock) -> case Msg of
{tcp, _@1, _@2} ->
gleam@io:print(<<"this should not happen"/utf8>>),
{continue, Sock};
{tcp_closed, _@3} ->
{stop, normal};
{receive_message, Data} ->
case parse_request(
begin
_pipe = Data,
_pipe@1 = gleam@erlang@charlist:to_string(_pipe),
gleam@bit_string:from_string(_pipe@1)
end
) of
{ok, Req} ->
{ok, Resp@1} = case begin
_pipe@2 = Req,
_pipe@3 = Handler(_pipe@2),
_pipe@4 = to_string(_pipe@3),
gleam@bit_string:to_string(_pipe@4)
end of
{ok, Resp} -> {ok, Resp};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"mist"/utf8>>,
function => <<"make_handler"/utf8>>,
line => 188})
end,
{ok, nil} = case glisten_ffi:send(
Sock,
gleam@erlang@charlist:from_string(Resp@1)
) of
{ok, nil} -> {ok, nil};
_try@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@1,
module => <<"mist"/utf8>>,
function => <<"make_handler"/utf8>>,
line => 193})
end;
{error, _@4} ->
{ok, Error@1} = case begin
_pipe@5 = 400,
_pipe@6 = gleam@http@response:new(_pipe@5),
_pipe@7 = gleam@http@response:set_body(
_pipe@6,
gleam@bit_string:from_string(<<""/utf8>>)
),
_pipe@8 = to_string(_pipe@7),
gleam@bit_string:to_string(_pipe@8)
end of
{ok, Error} -> {ok, Error};
_try@2 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@2,
module => <<"mist"/utf8>>,
function => <<"make_handler"/utf8>>,
line => 196})
end,
{ok, nil} = case glisten_ffi:send(
Sock,
gleam@erlang@charlist:from_string(Error@1)
) of
{ok, nil} -> {ok, nil};
_try@3 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@3,
module => <<"mist"/utf8>>,
function => <<"make_handler"/utf8>>,
line => 202})
end
end,
{stop, normal}
end end.
-spec listen(integer(), list(glisten@tcp:tcp_option())) -> {ok,
glisten@tcp:listen_socket()} |
{error, glisten@tcp:socket_reason()}.
listen(Port, Options) ->
glisten@tcp:listen(Port, Options).
-spec start_acceptor_pool(
glisten@tcp:listen_socket(),
fun((glisten@tcp:handler_message(), glisten@tcp:socket()) -> gleam@otp@actor:next(glisten@tcp:socket())),
integer()
) -> {ok, nil} | {error, nil}.
start_acceptor_pool(Listener_socket, Handler, Pool_count) ->
glisten@tcp:start_acceptor_pool(Listener_socket, Handler, Pool_count).