static file caching/serving seems to work
This commit is contained in:
+25
-59
@@ -224,12 +224,9 @@ handle_request(Sock, R = #request{method = M, path = P}) when M =/= undefined, P
|
||||
|
||||
route(Sock, get, Route, Request) ->
|
||||
case Route of
|
||||
<<"/">> -> home(Sock);
|
||||
<<"/default.css">> -> default_css(Sock);
|
||||
<<"/chat.html">> -> chat_html(Sock);
|
||||
<<"/ws-test-echo.html">> -> ws_test_echo_html(Sock);
|
||||
<<"/ws/echo">> -> ws_echo(Sock, Request);
|
||||
_ -> http_err(Sock, 404)
|
||||
<<"/ws/echo">> -> ws_echo(Sock, Request);
|
||||
<<"/">> -> route_static(Sock, <<"/index.html">>);
|
||||
_ -> route_static(Sock, Route)
|
||||
end;
|
||||
route(Sock, post, Route, Request) ->
|
||||
case Route of
|
||||
@@ -240,6 +237,28 @@ route(Sock, _, _, _) ->
|
||||
http_err(Sock, 404).
|
||||
|
||||
|
||||
route_static(Sock, Route) ->
|
||||
respond_static(Sock, fd_sfc:query(Route)).
|
||||
|
||||
respond_static(Sock, {found, Entry}) ->
|
||||
% -record(e, {fs_path :: file:filename(),
|
||||
% last_modified :: file:date_time(),
|
||||
% mime_type :: string(),
|
||||
% encoding :: encoding(),
|
||||
% contents :: binary()}).
|
||||
Headers0 =
|
||||
case fd_sfc_entry:encoding(Entry) of
|
||||
gzip -> [{"content-encoding", "gzip"}];
|
||||
none -> []
|
||||
end,
|
||||
Headers1 = [{"content-type", fd_sfc_entry:mime_type(Entry)} | Headers0],
|
||||
Response = #response{headers = Headers1,
|
||||
body = fd_sfc_entry:contents(Entry)},
|
||||
respond(Sock, Response);
|
||||
respond_static(Sock, not_found) ->
|
||||
http_err(Sock, 404).
|
||||
|
||||
|
||||
ws_echo(Sock, Request) ->
|
||||
try
|
||||
ws_echo2(Sock, Request)
|
||||
@@ -279,59 +298,6 @@ ws_echo_loop(Sock, Frames, Received) ->
|
||||
error(Error)
|
||||
end.
|
||||
|
||||
|
||||
home(Sock) ->
|
||||
%% fixme: cache
|
||||
Path_IH = filename:join([zx:get_home(), "priv", "index.html"]),
|
||||
case file:read_file(Path_IH) of
|
||||
{ok, Body} ->
|
||||
Resp = #response{headers = [{"content-type", "text/html"}],
|
||||
body = Body},
|
||||
respond(Sock, Resp);
|
||||
Error ->
|
||||
tell("error: ~p~n", [self(), Error]),
|
||||
http_err(Sock, 500)
|
||||
end.
|
||||
|
||||
default_css(Sock) ->
|
||||
%% fixme: cache
|
||||
Path_IH = filename:join([zx:get_home(), "priv", "default.css"]),
|
||||
case file:read_file(Path_IH) of
|
||||
{ok, Body} ->
|
||||
Resp = #response{headers = [{"content-type", "text/css"}],
|
||||
body = Body},
|
||||
respond(Sock, Resp);
|
||||
Error ->
|
||||
io:format("~p error: ~p~n", [self(), Error]),
|
||||
http_err(Sock, 500)
|
||||
end.
|
||||
|
||||
ws_test_echo_html(Sock) ->
|
||||
%% fixme: cache
|
||||
Path_IH = filename:join([zx:get_home(), "priv", "ws-test-echo.html"]),
|
||||
case file:read_file(Path_IH) of
|
||||
{ok, Body} ->
|
||||
Resp = #response{headers = [{"content-type", "text/html"}],
|
||||
body = Body},
|
||||
respond(Sock, Resp);
|
||||
Error ->
|
||||
io:format("~p error: ~p~n", [self(), Error]),
|
||||
http_err(Sock, 500)
|
||||
end.
|
||||
|
||||
chat_html(Sock) ->
|
||||
%% fixme: cache
|
||||
Path_IH = filename:join([zx:get_home(), "priv", "chat.html"]),
|
||||
case file:read_file(Path_IH) of
|
||||
{ok, Body} ->
|
||||
Resp = #response{headers = [{"content-type", "text/html"}],
|
||||
body = Body},
|
||||
respond(Sock, Resp);
|
||||
Error ->
|
||||
io:format("~p error: ~p~n", [self(), Error]),
|
||||
http_err(Sock, 500)
|
||||
end.
|
||||
|
||||
wfcin(Sock, #request{enctype = json,
|
||||
cookies = Cookies,
|
||||
body = #{"wfcin" := Input}}) ->
|
||||
|
||||
+42
-2
@@ -5,6 +5,8 @@
|
||||
|
||||
-export([
|
||||
%% caller context
|
||||
base_path/0,
|
||||
renew/0, query/1,
|
||||
start_link/0,
|
||||
|
||||
%% process context
|
||||
@@ -15,8 +17,24 @@
|
||||
-include("$zx_include/zx_logger.hrl").
|
||||
|
||||
|
||||
-record(s, {cache = fd_sfc_cache:new() :: fd_sfc_cache:cache()}).
|
||||
-type state() :: #s{}.
|
||||
-record(s, {base_path = base_path() :: file:filename(),
|
||||
cache = fd_sfc_cache:new(base_path()) :: fd_sfc_cache:cache(),
|
||||
auto_renew = 5_000 :: pos_integer()}).
|
||||
%-type state() :: #s{}.
|
||||
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% caller context
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
base_path() ->
|
||||
filename:join([zx:get_home(), "priv", "static"]).
|
||||
|
||||
renew() ->
|
||||
gen_server:cast(?MODULE, renew).
|
||||
|
||||
query(Path) ->
|
||||
gen_server:call(?MODULE, {query, Path}).
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, none, []).
|
||||
@@ -31,19 +49,31 @@ start_link() ->
|
||||
init(none) ->
|
||||
log(info, "starting fd_cache"),
|
||||
InitState = #s{},
|
||||
erlang:send_after(3_000, self(), auto_renew),
|
||||
{ok, InitState}.
|
||||
|
||||
|
||||
handle_call({query, Path}, _, State = #s{cache = Cache}) ->
|
||||
Reply = fd_sfc_cache:query(Path, Cache),
|
||||
{reply, Reply, State};
|
||||
handle_call(Unexpected, From, State) ->
|
||||
tell("~tp: unexpected call from ~tp: ~tp", [?MODULE, Unexpected, From]),
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
handle_cast(renew, State) ->
|
||||
NewState = i_renew(State),
|
||||
{noreply, NewState};
|
||||
handle_cast(Unexpected, State) ->
|
||||
tell("~tp: unexpected cast: ~tp", [?MODULE, Unexpected]),
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
handle_info(auto_renew, State = #s{auto_renew = MS}) ->
|
||||
log(info, "~tp: auto_renew", [?MODULE]),
|
||||
erlang:send_after(MS, self(), auto_renew),
|
||||
NewState = i_renew(State),
|
||||
{noreply, NewState};
|
||||
handle_info(Unexpected, State) ->
|
||||
tell("~tp: unexpected info: ~tp", [?MODULE, Unexpected]),
|
||||
{noreply, State}.
|
||||
@@ -54,3 +84,13 @@ code_change(_, State, _) ->
|
||||
|
||||
terminate(_, _) ->
|
||||
ok.
|
||||
|
||||
|
||||
%%-----------------------------------------------------------------------------
|
||||
%% internals
|
||||
%%-----------------------------------------------------------------------------
|
||||
|
||||
i_renew(State = #s{base_path = BasePath}) ->
|
||||
NewCache = fd_sfc_cache:new(BasePath),
|
||||
NewState = State#s{cache = NewCache},
|
||||
NewState.
|
||||
|
||||
@@ -50,7 +50,7 @@ contents(#e{contents = X}) -> X.
|
||||
% returns not_found if ANY I/O error occurs during the process. will be logged
|
||||
|
||||
new(Path) ->
|
||||
tell("~tp:new(~tp)", [?MODULE, Path]),
|
||||
log(info, "~tp:new(~tp)", [?MODULE, Path]),
|
||||
case file:read_file(Path) of
|
||||
{ok, Binary} ->
|
||||
{found, new2(Path, Binary)};
|
||||
|
||||
Reference in New Issue
Block a user