file cache seems to work

This commit is contained in:
Peter Harpending 2026-01-12 18:25:34 -08:00
parent 6bfd19e027
commit 46aacfb621
2 changed files with 62 additions and 19 deletions

View File

@ -8,8 +8,14 @@ GOALS
GOAL STACK
--------------------------------------------------------------------
- replace `io:format` calls with zx log
- use `gh_sfc`
- use `gh_sfc` in `gh_client`
- don't spam filesystem for 404/500
TODONE
--------------------------------------------------------------------
- ~~replace `io:format` calls with zx log~~
- ~~write out call paths for `gh_sfc`~~

View File

@ -110,7 +110,7 @@ listen(Parent, Debug, ListenSocket) ->
{ok, Socket} ->
{ok, _} = start(ListenSocket),
{ok, Peer} = inet:peername(Socket),
ok = log("~p Connection accepted from: ~p~n", [self(), Peer]),
ok = tell("~p Connection accepted from: ~p~n", [self(), Peer]),
ok = gh_client_man:enroll(),
State = #s{socket = Socket},
loop(Parent, Debug, State);
@ -151,7 +151,13 @@ loop(Parent, Debug, State = #s{socket = Socket, received = Received}) ->
%% see: https://git.qpq.swiss/QPQ-AG/QHL/pulls/1
case qhl:parse(Socket, Message2) of
{ok, Request, NewReceived} ->
ok = handle_request(Socket, Request),
try
ok = handle_request(Socket, Request)
catch
X:Y:Z ->
tell(error, "~tp ~tp: CRASH: ~tp:~tp:~tp, returning 500", [?MODULE, self(), X, Y, Z]),
http_err(Socket, 500)
end,
NewState = State#s{received = NewReceived},
loop(Parent, Debug, NewState);
{error, Reason} ->
@ -230,23 +236,52 @@ system_replace_state(StateFun, State) ->
%% ref: https://git.qpq.swiss/QPQ-AG/QHL/src/commit/7f77f9e3b19f58006df88a2a601e85835d300c37/include/http.hrl
handle_request(Socket, #request{method = get, path = <<"/">>}) ->
IndexHtmlPath = filename:join([zx:get_home(), "priv", "index.html"]),
case file:read_file(IndexHtmlPath) of
{ok, ResponseBody} ->
%% see https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Messages#http_responses
Headers = [{"content-type", "text/html"}],
Response = #response{headers = Headers,
body = ResponseBody},
respond(Socket, Response);
Error ->
log("~p ~p error: ~p~n", [?MODULE, self(), Error]),
http_err(Socket, 500)
handle_request(Socket, #request{method = get, path = Path}) ->
% future-proofing for hardcoded paths
case Path of
_ -> handle_static(Socket, Path)
end;
handle_request(Socket, _) ->
http_err(Socket, 404).
-spec handle_static(Socket, Path) -> ok
when Socket :: gen_tcp:socket(),
Path :: binary().
handle_static(Socket, <<"/">>) ->
handle_static(Socket, <<"/index.html">>);
handle_static(Socket, Path) ->
case gh_sfc:query(Path) of
{found, Entry} -> handle_entry(Socket, Entry);
not_found -> http_err(Socket, 404)
end.
-spec handle_entry(Socket, Entry) -> ok
when Socket :: gen_tcp:socket(),
Entry :: gh_sfc_entry:entry().
handle_entry(Socket, Entry) ->
% -type encoding() :: none | gzip.
% -record(e, {fs_path :: file:filename(),
% last_modified :: file:date_time(),
% mime_type :: string(),
% encoding :: encoding(),
% contents :: binary()}).
Encoding = gh_sfc_entry:encoding(Entry) ,
MimeType = gh_sfc_entry:mime_type(Entry),
Contents = gh_sfc_entry:contents(Entry),
Headers0 =
case Encoding of
gzip -> [{"content-encoding", "gzip"}];
none -> []
end,
Headers1 = [{"content-type", MimeType} | Headers0],
Response = #response{headers = Headers1,
body = Contents},
respond(Socket, Response).
http_err(Socket, 404) ->
HtmlPath = filename:join([zx:get_home(), "priv", "404.html"]),
{ok, ResponseBody} = file:read_file(HtmlPath),
@ -268,9 +303,11 @@ http_err(Socket, _) ->
respond(Socket, R = #response{code = Code, headers = Headers, body = Body}) ->
Slogan = slogan(Code),
ContentLength = byte_size(Body),
DefaultHeaders = [{"date", qhl:ridiculous_web_date()},
{"content-length", integer_to_list(ContentLength)}],
BodyBytes = iolist_to_binary(Body),
ContentLength = byte_size(BodyBytes),
DefaultHeaders = [{"Server", "gex_httpd 0.1.0"},
{"Date", qhl:ridiculous_web_date()},
{"Content-Length", integer_to_list(ContentLength)}],
Headers2 = merge_headers(DefaultHeaders, Headers),
really_respond(Socket, R#response{slogan = Slogan,
headers = Headers2}).