diff --git a/pkg/arvo/app/eth-watcher.hoon b/pkg/arvo/app/eth-watcher.hoon index 426523586..0a4355a47 100644 --- a/pkg/arvo/app/eth-watcher.hoon +++ b/pkg/arvo/app/eth-watcher.hoon @@ -318,7 +318,11 @@ %watch-ack ?~ p.sign [~ this] - %- (slog leaf+"eth-watcher couldn't start listen to thread" u.p.sign) + %- (slog leaf+"eth-watcher couldn't start listening to thread" u.p.sign) + :: TODO: kill thread that may have started, although it may not + :: have started yet since we get this response before the + :: %start-spider poke is processed + :: [~ (clear-running t.wire)] :: %kick [~ (clear-running t.wire)] @@ -413,7 +417,7 @@ ++ on-arvo |= [=wire =sign-arvo] ^- (quip card agent:gall) - ?+ +<.sign-arvo ~|([%strange-sign-arvo -.sign-arvo] !!) + ?+ +<.sign-arvo ~|([%strange-sign-arvo -.sign-arvo] !!) %wake ?. ?=([%timer *] wire) ~& weird-wire=wire [~ this] =* path t.wire diff --git a/pkg/arvo/app/file-server.hoon b/pkg/arvo/app/file-server.hoon index adc4e7125..d4b741bac 100644 --- a/pkg/arvo/app/file-server.hoon +++ b/pkg/arvo/app/file-server.hoon @@ -1,4 +1,4 @@ -/- srv=file-server +/- srv=file-server, glob /+ *server, default-agent, verb, dbug |% +$ card card:agent:gall @@ -6,7 +6,11 @@ $% state-zero == :: -+$ serving (map url-base=path [clay-base=path public=?]) ++$ serving (map url-base=path [=content public=?]) ++$ content + $% [%clay =path] + [%glob =glob:glob] + == +$ state-zero $: %0 =configuration:srv @@ -33,7 +37,7 @@ %+ turn ^- (list path) [/ /'~landscape' ~] - |=(pax=path [pax [/app/landscape %.n]]) + |=(pax=path [pax [clay+/app/landscape %.n]]) == :~ (connect /) (connect /'~landscape') @@ -75,7 +79,14 @@ ?: (~(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-base.act public.act])) + 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]]~ @@ -84,9 +95,9 @@ %toggle-permission ?. (~(has by serving) url-base.act) ~|("url is not bound" !!) - =/ [clay-base=path public=?] (~(got by serving) url-base.act) + =/ [=content public=?] (~(got by serving) url-base.act) :- ~ - this(serving (~(put by serving) url-base.act [clay-base !public])) + this(serving (~(put by serving) url-base.act [content !public])) :: %set-landscape-homepage-prefix =. landscape-homepage-prefix.configuration prefix.act @@ -133,22 +144,36 @@ |= req-line=request-line ^- [simple-payload:http ?] =/ pax=path (snoc site.req-line (need ext.req-line)) - =/ clay-path=(unit [path ?]) (get-clay-path pax) - ?~ clay-path [not-found:gen %.n] - =/ scry-path - :* (scot %p our.bowl) - q.byk.bowl - (scot %da now.bowl) - (lowercase -.u.clay-path) + =/ content=(unit [=content suffix=path public=?]) (get-content pax) + ?~ content [not-found:gen %.n] + ?- -.content.u.content + %clay + =/ scry-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 + [~ %html] (html-response:gen file) + [~ %js] (js-response:gen file) + [~ %css] (css-response:gen file) + [~ %png] (png-response:gen file) == - ?. .^(? %cu scry-path) [not-found:gen %.n] - =/ file (as-octs:mimes:html .^(@ %cx scry-path)) - :_ +.u.clay-path - ?+ ext.req-line not-found:gen - [~ %html] (html-response:gen file) - [~ %js] (js-response:gen file) - [~ %css] (css-response:gen file) - [~ %png] (png-response:gen file) + :: + %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 )) + :: Should maybe inspect to see how long cache should hold + :: + [[200 ['content-type' mime-type] max-1-da:gen ~] `q.u.data] == :: ++ lowercase @@ -162,24 +187,24 @@ char (add char ^~((sub 'a' 'A'))) :: - ++ get-clay-path + ++ get-content |= pax=path - ^- (unit [path ?]) - =/ first-try (match-clay-path pax (~(del by serving) /)) + ^- (unit [content path ?]) + =/ first-try (match-content-path pax (~(del by serving) /)) ?^ first-try first-try =/ root (~(get by serving) /) ?~ root ~ - (match-clay-path pax (~(gas by *^serving) [[/ u.root] ~])) + (match-content-path pax (~(gas by *^serving) [[/ u.root] ~])) :: - ++ match-clay-path + ++ match-content-path |= [pax=path =^serving] - ^- (unit [path ?]) + ^- (unit [content path ?]) %- ~(rep by serving) - |= [[url-base=path clay-base=path public=?] out=(unit [path ?])] + |= [[url-base=path =content public=?] out=(unit [content path ?])] ?^ out out =/ suf (get-suffix url-base pax) ?~ suf ~ - `[(weld clay-base u.suf) public] + `[content u.suf public] :: ++ get-suffix |= [a=path b=path] diff --git a/pkg/arvo/app/glob.hoon b/pkg/arvo/app/glob.hoon new file mode 100644 index 000000000..9625e4fa3 --- /dev/null +++ b/pkg/arvo/app/glob.hoon @@ -0,0 +1,163 @@ +/- glob +/+ default-agent, verb, dbug +|% +++ hash 0v4.jhi39.ns412.vhlmi.i1b1h.56kvu ++$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))] ++$ all-states + $% state-0 + == ++$ card card:agent:gall +-- +|% +++ wait + |= [=path now=@da time=@dr] + ^- card + [%pass [%timer path] %arvo %b %wait (add now time)] +:: +++ poke-file-server + |= [our=@p =cage] + ^- card + [%pass /serving/(scot %uv hash) %agent [our %file-server] %poke cage] +:: +++ poke-spider + |= [=path our=@p =cage] + ^- card + [%pass [%running path] %agent [our %spider] %poke cage] +:: +++ watch-spider + |= [=path our=@p =sub=path] + ^- card + [%pass [%running path] %agent [our %spider] %watch sub-path] +:: +++ leave-spider + |= [=path our=@p] + ^- card + [%pass [%running path] %agent [our %spider] %leave ~] +-- +=| state=state-0 +=. hash.state hash +^- agent:gall +%+ verb | +%- agent:dbug +^- agent:gall +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) +++ on-init + ^- (quip card _this) + =/ new-tid=@ta (cat 3 'glob--' (scot %uv eny.bowl)) + =/ args [~ `new-tid %glob !>([hash.state ~])] + :_ this(glob.state `[%| new-tid]) + =/ action !>([%unserve-dir /'~glob']) + :~ (poke-file-server our.bowl %file-server-action action) + (wait /[new-tid] now.bowl ~s15) + (watch-spider /(scot %uv hash.state) our.bowl /thread-result/[new-tid]) + (poke-spider /(scot %uv hash.state) our.bowl %spider-start !>(args)) + == +:: +++ on-save !>(state) +++ on-load + |= old-state=vase + ^- (quip card _this) + ~& > %initting + =+ !<(old=all-states old-state) + ?> ?=(%0 -.old) + ?~ glob.old + on-init + ?: ?=(%& -.u.glob.old) + ?: =(hash.old hash.state) + `this(state old) + on-init + =/ cancel-cards + =/ args [tid.p.u.glob.old &] + :~ (leave-spider /(scot %uv hash.old) our.bowl) + (poke-spider /(scot %uv hash.old) our.bowl %spider-stop !>(args)) + == + =^ init-cards this on-init + [(weld cancel-cards init-cards) this] +:: +++ on-poke + |= [=mark =vase] + ^- (quip card _this) + ?: =(%kick q.vase) + (on-load !>(state(hash *@uv))) + (on-poke:def mark vase) +:: +++ on-watch on-watch:def +++ on-leave on-leave:def +++ on-peek on-peek:def +++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card _this) + ?: ?=([%serving @ ~] wire) + (on-agent:def wire sign) + ?. ?=([%running @ ~] wire) + %- (slog leaf+"glob: strange on-agent! {}" ~) + (on-agent:def wire sign) + ?- -.sign + %poke-ack + ?~ p.sign + [~ this] + %- (slog leaf+"glob: couldn't start thread; will retry" u.p.sign) + :_ this(glob.state ~) :_ ~ + (leave-spider t.wire our.bowl) + :: + %watch-ack + ?~ p.sign + [~ this] + %- (slog leaf+"glob: couldn't listen to thread; will retry" u.p.sign) + [~ this(glob.state ~)] + :: + %kick + =? glob.state ?=([~ %| *] glob.state) + ~ + `this + :: + %fact + =/ produced-hash (slav %uv i.t.wire) + ?. =(hash.state produced-hash) + [~ this] + ?+ p.cage.sign (on-agent:def wire sign) + %thread-fail + =+ !<([=term =tang] q.cage.sign) + %- (slog leaf+"glob: thread failed; will retry" leaf+ tang) + [~ this(glob.state ~)] + :: + %thread-done + =+ !<(=glob:glob q.cage.sign) + ?. =(hash.state (sham glob)) + %: mean + leaf+"glob: hash doesn't match!" + >expected=hash.state< + >got=(sham glob)< + ~ + == + :_ this(glob.state `[%& glob]) :_ ~ + %+ poke-file-server our.bowl + [%file-server-action !>([%serve-glob /'~glob' glob %|])] + == + == +:: +++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card _this) + ?. ?=([%timer @ ~] wire) + %- (slog leaf+"glob: strange on-arvo wire: {}" ~) + `this + ?. ?=(%wake +<.sign-arvo) + %- (slog leaf+"glob: strange on-arvo sign: {}" ~) + `this + ?: ?=([~ %& *] glob.state) + `this + ?. ?| ?=(~ glob.state) + =(i.t.wire tid.p.u.glob.state) + == + `this + ?^ error.sign-arvo + %- (slog leaf+"glob: timer handling failed; will retry" ~) + [[(wait t.wire now.bowl ~s15)]~ this] + %- (slog leaf+"glob: timed out; retrying" ~) + (on-load !>(state(hash *@uv))) +:: +++ on-fail on-fail:def +-- diff --git a/pkg/arvo/lib/strandio.hoon b/pkg/arvo/lib/strandio.hoon index db9db877e..71299cb8b 100644 --- a/pkg/arvo/lib/strandio.hoon +++ b/pkg/arvo/lib/strandio.hoon @@ -366,14 +366,20 @@ ?> ?=(^ full-file.client-response) (pure:m q.data.u.full-file.client-response) :: -++ fetch-json +++ fetch-cord |= url=tape - =/ m (strand ,json) + =/ m (strand ,cord) ^- form:m =/ =request:http [%'GET' (crip url) ~ ~] ;< ~ bind:m (send-request request) ;< =client-response:iris bind:m take-client-response - ;< =cord bind:m (extract-body client-response) + (extract-body client-response) +:: +++ fetch-json + |= url=tape + =/ m (strand ,json) + ^- form:m + ;< =cord bind:m (fetch-cord url) =/ json=(unit json) (de-json:html cord) ?~ json (strand-fail %json-parse-error ~) diff --git a/pkg/arvo/sur/file-server.hoon b/pkg/arvo/sur/file-server.hoon index 7bd02922f..b29379c91 100644 --- a/pkg/arvo/sur/file-server.hoon +++ b/pkg/arvo/sur/file-server.hoon @@ -1,6 +1,8 @@ +/- glob |% +$ action $% [%serve-dir url-base=path clay-base=path public=?] + [%serve-glob url-base=path =glob:glob public=?] [%unserve-dir url-base=path] [%toggle-permission url-base=path] [%set-landscape-homepage-prefix prefix=(unit term)] diff --git a/pkg/arvo/sur/glob.hoon b/pkg/arvo/sur/glob.hoon new file mode 100644 index 000000000..4c2950310 --- /dev/null +++ b/pkg/arvo/sur/glob.hoon @@ -0,0 +1,3 @@ +|% ++$ glob (map path mime) +-- diff --git a/pkg/arvo/ted/glob.hoon b/pkg/arvo/ted/glob.hoon new file mode 100644 index 000000000..d50e7a114 --- /dev/null +++ b/pkg/arvo/ted/glob.hoon @@ -0,0 +1,12 @@ +/- spider, glob +/+ strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([hash=@uv ~] arg) +=/ url "https://bootstrap.urbit.org/glob-{(scow %uv hash)}.glob" +;< =cord bind:m (fetch-cord:strandio url) +=+ ;;(=glob:glob (cue cord)) +(pure:m !>(glob))