/- srv=file-server, glob /+ *server, default-agent, verb, dbug |% +$ card card:agent:gall +$ serving (map url-base=path [=content public=?]) +$ content $% [%clay =path] [%glob =glob:glob] == +$ state-base $: =configuration:srv =serving == +$ state-2 $: %2 state-base == -- :: %+ verb | %- agent:dbug :: =| state-2 =* state - ^- agent:gall |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) :: ++ on-init ^- (quip card _this) |^ :_ %_ this serving %- ~(gas by *^serving) %+ turn ^- (list path) [/ /'~landscape' ~] |=(pax=path [pax [clay+/app/landscape %.n]]) == :~ (connect /) (connect /'~landscape') == :: ++ connect |= =path ^- card [%pass path %arvo %e %connect [~ path] %file-server] -- :: ++ on-save !>(state) ++ on-load |= old-vase=vase ^- (quip card _this) |^ =+ !<(old-state=versioned-state old-vase) =? old-state ?=(%0 -.old-state) %= old-state - %1 serving-0 %- ~(run by serving-0.old-state) |= [=clay=path public=?] ^- [content ?] [[%clay clay-path] public] == =? old-state ?=(%1 -.old-state) %= old-state - %2 serving (~(del by serving.old-state) /'~landscape'/js/index) == ?> ?=(%2 -.old-state) [~ this(state old-state)] :: +$ versioned-state $% state-0 state-1 state-2 == :: +$ serving-0 (map url-base=path [=clay=path public=?]) +$ state-0 $: %0 =configuration:srv =serving-0 == +$ state-1 $: %1 state-base == -- :: ++ on-poke |= [=mark =vase] ^- (quip card _this) |^ ?> (team:title our.bowl src.bowl) ?+ mark (on-poke:def mark vase) %file-server-action (file-server-action !<(action:srv vase)) %handle-http-request =+ !<([id=@ta req=inbound-request:eyre] vase) :_ this %+ give-simple-payload:app id (handle-http-request req) == :: ++ file-server-action |= act=action:srv ^- (quip card _this) |^ ?- -.act %serve-dir =* url-base url-base.act ?: (~(has by serving) url-base) ~|("url already bound to {<(~(got by serving) url-base.act)>}" !!) :- [%pass url-base %arvo %e %connect [~ url-base] %file-server]~ this(serving (~(put by serving) url-base clay+clay-base.act public.act)) :: %serve-glob =* url-base url-base.act ?: (~(has by serving) url-base) ~|("url already bound to {<(~(got by serving) url-base.act)>}" !!) :- [%pass url-base %arvo %e %connect [~ url-base] %file-server]~ this(serving (~(put by serving) url-base glob+glob.act public.act)) :: %unserve-dir :- [%pass url-base.act %arvo %e %disconnect [~ url-base.act]]~ this(serving (~(del by serving) url-base.act)) :: %toggle-permission ?. (~(has by serving) url-base.act) ~|("url is not bound" !!) =/ [=content public=?] (~(got by serving) url-base.act) :- ~ this(serving (~(put by serving) url-base.act [content !public])) :: %set-landscape-homepage-prefix =. landscape-homepage-prefix.configuration prefix.act :_ this (give [%configuration configuration]) == :: ++ give |= =update:srv ^- (list card) [%give %fact [/all]~ [%file-server-update !>(update)]]~ -- :: ++ handle-http-request |= =inbound-request:eyre ^- simple-payload:http |^ =* req request.inbound-request =* headers header-list.req =/ req-line (parse-request-line url.req) ?. =(method.req %'GET') not-found:gen =? req-line ?=(~ ext.req-line) [[[~ %html] ~['index']] args.req-line] ?> ?=(^ ext.req-line) ?~ site.req-line not-found:gen =* url-prefix landscape-homepage-prefix.configuration ?. ?| ?=(~ url-prefix) =(u.url-prefix i.site.req-line) == not-found:gen :: ?: ?=([%'~landscape' %js %session ~] site.req-line) %+ require-authorization-simple:app inbound-request %- js-response:gen (as-octt:mimes:html "window.ship = '{+:(scow %p our.bowl)}';") :: =/ [payload=simple-payload:http public=?] (get-file req-line) ?: public payload (require-authorization-simple:app inbound-request payload) :: ++ get-file |= req-line=request-line ^- [simple-payload:http ?] =/ pax=path (snoc site.req-line (need ext.req-line)) =/ content=(unit [=content suffix=path public=?]) (get-content pax) ?~ content [not-found:gen %.n] ?- -.content.u.content %clay =/ scry-path=path :* (scot %p our.bowl) q.byk.bowl (scot %da now.bowl) (lowercase (weld path.content.u.content suffix.u.content)) == ?. .^(? %cu scry-path) [not-found:gen %.n] =/ file (as-octs:mimes:html .^(@ %cx scry-path)) :_ public.u.content ?+ ext.req-line not-found:gen [~ %js] (js-response:gen file) [~ %css] (css-response:gen file) [~ %png] (png-response:gen file) :: [~ %html] %. file %* . html-response:gen cache !=(/app/landscape/index/html (slag 3 scry-path)) == == :: %glob =/ data=(unit mime) (~(get by glob.content.u.content) suffix.u.content) ?~ data [not-found:gen %.n] :_ public.u.content =/ mime-type=@t (rsh 3 1 (crip