-module(starfruit@internal).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src\\starfruit\\internal.gleam").
-export([senddata/2, parse_url/4, router/1, response/1, bind/2]).
-export_type([response/0, response_code/0]).
-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(false).
-type response() :: {response, binary(), binary(), bitstring()}.
-type response_code() :: status51 | status59 | status53.
-file("src\\starfruit\\internal.gleam", 18).
?DOC(false).
-spec senddata(list(gleam@bytes_tree:bytes_tree()), glisten:connection(any())) -> {ok,
nil} |
{error, glisten@socket:socket_reason()}.
senddata(Data, Conn) ->
Firstsegment@1 = case gleam@list:first(Data) of
{ok, Firstsegment} -> Firstsegment;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"starfruit/internal"/utf8>>,
function => <<"senddata"/utf8>>,
line => 22,
value => _assert_fail,
start => 451,
'end' => 497,
pattern_start => 462,
pattern_end => 478})
end,
case erlang:length(Data) of
1 ->
glisten:send(Conn, Firstsegment@1);
_ ->
case glisten:send(Conn, Firstsegment@1) of
{ok, _} -> nil;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"starfruit/internal"/utf8>>,
function => <<"senddata"/utf8>>,
line => 28,
value => _assert_fail@1,
start => 604,
'end' => 655,
pattern_start => 615,
pattern_end => 620})
end,
senddata(gleam@list:drop(Data, 1), Conn)
end.
-file("src\\starfruit\\internal.gleam", 124).
?DOC(false).
-spec checkiflocalip(binary()) -> boolean().
checkiflocalip(Host) ->
case Host of
<<"::1"/utf8>> ->
true;
<<"localhost"/utf8>> ->
true;
<<"127.0.0.1"/utf8>> ->
true;
A ->
Splitip = gleam@string:split(A, <<"."/utf8>>),
case erlang:length(Splitip) of
4 ->
Toint = gleam@list:map(
Splitip,
fun(A@1) ->
Z@1 = case gleam_stdlib:parse_int(A@1) of
{ok, Z} -> Z;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"starfruit/internal"/utf8>>,
function => <<"checkiflocalip"/utf8>>,
line => 135,
value => _assert_fail,
start => 3763,
'end' => 3794,
pattern_start => 3774,
pattern_end => 3779})
end,
Z@1
end
),
case Toint of
[10, _, _, _] ->
true;
[172, A@2, _, _] ->
case gleam@bool:'and'(A@2 >= 16, A@2 < 32) of
true ->
true;
false ->
false
end;
[192, 168, _, _] ->
true;
_ ->
false
end;
_ ->
false
end
end.
-file("src\\starfruit\\internal.gleam", 37).
?DOC(false).
-spec parse_url(bitstring(), integer(), binary(), glisten:ip_address()) -> {ok,
binary()} |
{error, response_code()}.
parse_url(Url, Boundport, Hostname, Clientip) ->
gleam_stdlib:print(
gleam@result:unwrap(
gleam@bit_array:to_string(Url),
<<"unwrappable request"/utf8>>
)
),
Checklength = fun(X) -> case X of
{error, _} ->
{error, status59};
{ok, A} ->
_assert_subject = <<"\r\n"/utf8>>,
case gleam_stdlib:contains_string(A, _assert_subject) of
true -> nil;
false -> erlang:error(#{gleam_error => assert,
message => <<"Assertion failed."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"starfruit/internal"/utf8>>,
function => <<"parse_url"/utf8>>,
line => 48,
kind => function_call,
arguments => [#{kind => expression,
value => A,
start => 1271,
'end' => 1272
}, #{kind => literal,
value => _assert_subject,
start => 1274,
'end' => 1280
}],
start => 1248,
'end' => 1281,
expression_start => 1255})
end,
Trimmed = gleam@string:trim(A),
case erlang:byte_size(Trimmed) > 1024 of
true ->
{error, status59};
false ->
{ok, Trimmed}
end
end end,
Touri = fun(X@1) -> case X@1 of
{error, A@1} ->
{error, A@1};
{ok, A@2} ->
_pipe = gleam_stdlib:uri_parse(A@2),
gleam@result:replace_error(_pipe, status59)
end end,
Checkscheme = fun(X@2) ->
Validhost = fun(Hostname@1, Req, Client_ip) ->
Reqdhostname = gleam@option:unwrap(Req, <<""/utf8>>),
Client = glisten:ip_address_to_string(Client_ip),
case checkiflocalip(Client) of
true ->
checkiflocalip(Reqdhostname);
false ->
Hostname@1 =:= Reqdhostname
end
end,
case X@2 of
{error, A@3} ->
{error, A@3};
{ok, A@4} ->
case A@4 of
{uri, {some, <<"gemini"/utf8>>}, none, D, C, B, _, _} ->
case Validhost(Hostname, D, Clientip) of
false ->
{error, status53};
true ->
case C of
none ->
{ok, B};
{some, C@1} ->
case C@1 =:= Boundport of
true ->
{ok, B};
false ->
{error, status53}
end
end
end;
{uri, none, _, _, _, _, _, _} ->
{error, status59};
_ ->
{error, status53}
end
end
end,
_ = begin
_pipe@1 = gleam@bit_array:to_string(Url),
_pipe@2 = Checklength(_pipe@1),
_pipe@3 = Touri(_pipe@2),
Checkscheme(_pipe@3)
end.
-file("src\\starfruit\\internal.gleam", 199).
?DOC(false).
-spec router({ok, binary()} | {error, response_code()}) -> response().
router(Reqpath) ->
Index = <<"/index.gmi"/utf8>>,
Rootpath = gleam@result:map(
Reqpath,
fun(A) ->
gleam_stdlib:string_remove_suffix(
erlang:list_to_binary([<<"./capsule"/utf8>>, A]),
<<"/"/utf8>>
)
end
),
Path = case Rootpath of
{ok, A@1} ->
_pipe = case simplifile_erl:is_directory(A@1) of
{ok, true} ->
{ok, erlang:list_to_binary([A@1, Index])};
{ok, false} ->
{ok, A@1};
{error, A@2} ->
{error, A@2}
end,
gleam@result:replace_error(_pipe, status51);
{error, A@3} ->
{error, A@3}
end,
Validfile = case Path of
{ok, A@4} ->
_pipe@1 = simplifile_erl:is_file(A@4),
gleam@result:replace_error(_pipe@1, status51);
{error, A@5} ->
{error, A@5}
end,
case Validfile of
{error, status59} ->
{response, <<"59"/utf8>>, <<"59 - Bad request!"/utf8>>, <<>>};
{error, status51} ->
{response, <<"51"/utf8>>, <<"51 - Page not found!"/utf8>>, <<>>};
{error, status53} ->
{response,
<<"53"/utf8>>,
<<"53 - Proxy request denied!"/utf8>>,
<<>>};
{ok, false} ->
{response, <<"51 "/utf8>>, <<"51 - Page not found!"/utf8>>, <<>>};
{ok, true} ->
Filepath = gleam@result:unwrap(Path, <<""/utf8>>),
Filedata = begin
_pipe@2 = simplifile_erl:read_bits(Filepath),
gleam@result:unwrap(_pipe@2, <<>>)
end,
Mime = case gleam_stdlib:string_ends_with(Filepath, <<".gmi"/utf8>>) of
true ->
<<"text/gemini"/utf8>>;
false ->
mimetype:to_string(
mimetype:detect_with_filename(Filedata, Filepath)
)
end,
{response, <<"20"/utf8>>, Mime, Filedata}
end.
-file("src\\starfruit\\internal.gleam", 260).
?DOC(false).
-spec slicebody(bitstring(), list(gleam@bytes_tree:bytes_tree())) -> list(gleam@bytes_tree:bytes_tree()).
slicebody(Data, Segments) ->
Length = erlang:byte_size(Data),
Getslice = fun(A, Len, Slicelen) ->
_pipe = gleam_stdlib:bit_array_slice(A, Len, Slicelen),
gleam@result:unwrap(_pipe, <<>>)
end,
case Length of
0 ->
Segments;
_ ->
case (Length =< 65536) of
true ->
[gleam@bytes_tree:from_bit_array(Data) | Segments];
false ->
slicebody(
Getslice(Data, 0, Length - 65536),
[gleam@bytes_tree:from_bit_array(
Getslice(Data, Length, - 65536)
) |
Segments]
)
end
end.
-file("src\\starfruit\\internal.gleam", 249).
?DOC(false).
-spec response(response()) -> list(gleam@bytes_tree:bytes_tree()).
response(Data) ->
gleam_stdlib:print(
<<<<<<<<"Response: "/utf8, (erlang:element(2, Data))/binary>>/binary,
" "/utf8>>/binary,
(erlang:element(3, Data))/binary>>/binary,
"\r\n"/utf8>>
),
Respstring = begin
_pipe = erlang:list_to_binary(
[erlang:element(2, Data),
<<" "/utf8>>,
erlang:element(3, Data),
<<"\r\n"/utf8>>]
),
gleam_stdlib:wrap_list(_pipe)
end,
[Respstring | slicebody(erlang:element(4, Data), [])].
-file("src\\starfruit\\internal.gleam", 285).
?DOC(false).
-spec bind(glisten:builder(nil, KUY), boolean()) -> glisten:builder(nil, KUY).
bind(Actor, Loopy) ->
case Loopy of
false ->
glisten:bind(Actor, <<"0.0.0.0"/utf8>>);
true ->
Actor
end.