diff --git a/priv/chat.html b/priv/chat.html deleted file mode 100644 index 895393b..0000000 --- a/priv/chat.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Chat with Websockets - - - -
-

Chat with websockets

- -
- - - -
-
- - - - diff --git a/priv/default.css b/priv/default.css deleted file mode 100644 index d7f1ad5..0000000 --- a/priv/default.css +++ /dev/null @@ -1,95 +0,0 @@ -/* color pallette */ -* { - --white: #f7f8fb; - --lgray0: #f5fbfd; - --lgray1: #daddd6; - --lgray2: #d3d8d5; - --mgray1: #687864; - --dgreen1: #21341e; - --lgreen1: #e5eef2; - --black: #003d27; - - --sans: Helvetica, Liberation Sans, FreeSans, Roboto, sans-serif; - --mono: Liberation Mono, FreeMono, Roboto Mono, monospace; - --fsdef: 12pt; -} - -/* body */ -body { - background: var(--white); - color: var(--dgray1); - font-size: var(--fsdef); - font-family: var(--sans); - margin: 0; - padding: 0; - line-height: 1.4; -} - - -.content { - max-width: 800px; - margin: 0 auto; - /* - background: #ff0; - */ -} - - -/* add some top padding to content */ - -.content-title { - text-align: center; - text-decoration: underline; -} - -.content-body { - width: 100%; - margin: 0 auto; - /* - background: #f00; - */ - - - padding-left: 10px; - padding-right: 10px; - - box-sizing: border-box; -} - -/* element-specific styling */ - -a { - color: var(--mgray1); -} - - -#wfc-input { - font-family: var(--mono); - font-size: var(--fsdef); - background: var(--lgreen1); - - width: 100%; - - box-sizing: border-box; - - border-radius: 6px; - border: 1px solid var(--lgray1); - - padding: 5px; -} - -#wfc-output { - background: var(--lgray0); - font-family: var(--mono); - font-size: var(--fsdef); - - width: 100%; - resize: vertical; - - box-sizing: border-box; - - border-radius: 6px; - border: 1px solid var(--lgray1); - - padding: 5px; -} diff --git a/priv/index.html b/priv/index.html deleted file mode 100644 index 6c1b6d7..0000000 --- a/priv/index.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - - WF Compiler Demo - - - -
-

WFC Demo

- - - -
- - - -

Settings

- Auto-resize output
- Auto-scroll output to bottom -
-
- - - - diff --git a/priv/scratch.txt b/priv/scratch.txt deleted file mode 100644 index db3b7c7..0000000 --- a/priv/scratch.txt +++ /dev/null @@ -1,56 +0,0 @@ - /* header */ - div#header { - background: var(--lgray2); - height: 50px; - width: 100%; - } - - img#header-logo { - height: 40px; - margin-top: 5px; - margin-bottom: 5px; - margin-left: 5px; - } - - -.main { - padding-top: 20px; -} - -.content-diagram { - max-width: 100%; - margin: 0 auto; - padding: 0 auto; -} - - -/* Pandoc makes some wacky choices with how it lays out code blocks - * - * this means all blocks that do not have a
 block as an ancestor
- *
- * ie the `inline code`
- */
-code:not(pre *) {
-    border-radius:  6px;
-    border:         1px solid var(--lgray1);
-    padding-left:   3px;
-    padding-right:  3px;
-    padding-top:    1px;
-    padding-bottom: 1px;
-    background:     var(--lgreen1);
-}
-
-/* this is specifically for ```fenced blocks``` */
-pre {
-    border-radius:  6px;
-    border:         1px solid var(--lgray1);
-    padding:        5px;
-    background:     var(--lgreen1);
-    overflow:       scroll;
-}
-
-/* All `unfenced` or ```fenced``` blocks */
-code {
-    font-family:    Liberation Mono, Roboto Mono, monospace;
-    color:          var(--dgreen1);
-}
diff --git a/priv/ws-test-echo.html b/priv/ws-test-echo.html
deleted file mode 100644
index 2c3d47d..0000000
--- a/priv/ws-test-echo.html
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-    
-    Websockets echo test
-    
-
-
-    
-

Websockets echo test

- -
- - -
-
- - - - diff --git a/src/fd_client.erl b/src/fd_client.erl index c50d18a..f5e7fcb 100644 --- a/src/fd_client.erl +++ b/src/fd_client.erl @@ -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}}) -> diff --git a/src/fd_sfc.erl b/src/fd_sfc.erl index 32347e9..bc17c2d 100644 --- a/src/fd_sfc.erl +++ b/src/fd_sfc.erl @@ -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. diff --git a/src/fd_sfc_entry.erl b/src/fd_sfc_entry.erl index a363484..623bd73 100644 --- a/src/fd_sfc_entry.erl +++ b/src/fd_sfc_entry.erl @@ -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)};