aboutsummaryrefslogtreecommitdiff
path: root/src/http_ffi.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/http_ffi.erl')
-rw-r--r--src/http_ffi.erl34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/http_ffi.erl b/src/http_ffi.erl
index 507ee06..5304ee4 100644
--- a/src/http_ffi.erl
+++ b/src/http_ffi.erl
@@ -1,7 +1,7 @@
-module(http_ffi).
--export([serve/1]).
+-export([serve/4]).
-serve(Port) ->
+serve(Host, Port, OnStart, OnPortTaken) ->
{ok, Pattern} = re:compile("name *= *\"(?<Name>.+)\""),
{ok, Toml} = file:read_file("gleam.toml"),
{match, [Name]} = re:run(Toml, Pattern, [{capture, all_names, binary}]),
@@ -43,25 +43,51 @@ serve(Port) ->
inets:start(),
Address = {127, 0, 0, 1},
+ ActualPort =
+ case port_available(Port) of
+ true ->
+ Port;
+ false ->
+ OnPortTaken(Port),
+ first_available_port(Port + 1)
+ end,
+
{ok, Pid} =
httpd:start_service([
{bind_address, Address},
{document_root, AbsPath},
{server_root, AbsPath},
{directory_index, ["index.html"]},
- {server_name, "localhost"},
- {port, Port},
+ {server_name, binary_to_list(Host)},
+ {port, ActualPort},
{default_type, "text/html"},
{mime_types, mime_types()},
{modules, [mod_alias, mod_dir, mod_get]}
]),
+ OnStart(ActualPort),
+
receive
{From, shutdown} ->
ok = httpd:stop_service(Pid),
From ! done
end.
+port_available(Port) ->
+ case gen_tcp:listen(Port, []) of
+ {ok, Sock} ->
+ ok = gen_tcp:close(Sock),
+ true;
+ _ ->
+ false
+ end.
+
+first_available_port(Port) ->
+ case port_available(Port) of
+ true -> Port;
+ false -> first_available_port(Port + 1)
+ end.
+
mime_types() ->
[
{"html", "text/html"},