on 492ae2f help sign in
273 lines 13 kB history raw
1Eyre: Reference
2===============
4## State
6Stored
8- `++bolo`
9- `++cyst`
10- `++stem`
12Runtime
14- `perk`
15 + `perk-auth`
16- `pest`
17- `even`
19## Cores
21- `++handle`
22 + `++parse`
23 - `++as...`
24- `++ya`
25- `++ix`
27Eyre: Commentary
28================
30Let us follow the loading of a simple cli app, as it bounces from
31browser to server to browser and back.
33## Initial request[#init]
35An http request for `http://sampel-sipnym.urbit.org/cli` will be [redirected](dns)
36to the `%eyre` on ~sampel-sipnym, and come in as a `%this` kiss.
38From arvo, requests enter `++call`, which after some type reification are passed
39along to `++apex:ye`. In the case of a `%this` kiss, its components are
40parsed(see `++zest:epur`, `++eat-headers`) and handed off to `++handle`, wrapped
41in `++emule` to produce a `++fail` page in case of error. `++apex:handle` will
42`++process` the request to a `pest` or a `++done` core, and in the former case
43`++resolve` the pest into an outgoing card.
45XX it also seems to affect the current ship, test that serving ship name is consistently correct
47The pest is produced by `++process`, which will first further `++parse` the
48request, and if this does not make the response immediately obvious,
49`++process-parsed` the resulting `perk`.
51`++parse` produces the `perk`, by attempting to interpret the `pork`(url path)
52[`++as-magic-filename`](#mage), `++as-beam`, and `++as-aux-request`. In this
53case, `/cli` is parsed by the second case as a `%beam` query to `/=cli=`: a path
54which starts with a valid ship name is expected to be a full clay(well, ford)
55path, and one starting with a term implies the current serving ship and a case
56of `0`, the current revision.
58XX spur: when the desks are merged, `/cli` shall point to `/=main=/pub/cli`
60The parsed `perk` generates a `%f %boil` note, `mark`ed as its extension(here
61defaulting to `%urb`) and `wire`d with `~` to return unaltered to the client. It
62goes on to `++resolve` by being passed to `++ford-get-beam`, which translates
63the perk it into a `%boil` `++ford-req`, adding an `++fcgi` path-segment
64containing query string and `++fcgi-cred:for-client` auth information.
66`%ford`s translation of `/=cli=/hymn/hook` to a self-refreshing `%urb` html page
67[deserves its own commentary](../ford/commentary), but we resume in `%eyre`
68when the `%made` sign arrives in `++take`, and soon after `++axon:ye`. There the
69`wire`, or rather the `whir` it has been verified to be, determines that the
70response should be served immediately. However, as the mark is not `%mime`,
71another trip to `%ford` is required to encode it, on the same wire; afterwards,
72the value of the `%mime` cage is verified to be of the correct type, and finally
73delivered back up the requesting duct as a succesful `%thou` HTTP response.
75XX `%cast %mime` used to be in ford-get-beam, is there a reason it was removed?
77## Back into the breach, or: auxilary requests
79Now, it was mentioned that this result is self-refreshing: the `%urb`
80translation door injects a `;script@"/~/on/{deps}.js"` into every page, `deps`
81is a ford-readable hash of the set of resources that page construction depended
82on.
84This triggers another `%this` request. Its handling is identical to that of
85`/cli` up until `++parse`, where it is seen not `++as-beam` but
86`++as-aux-request`(auxillary requests starting with `/~/` or `/~~/`).
87`/on/[hash]` is a long-`%poll`, which `++process-parsed`, for a `.js` mark,
88answers with a direct `%js`. Its contents are the static `++poll:js`, which
89initiates the long-polling loop, run against an injected `urb.js` of
90`{poll:[hash]}`.
92A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
94When `poll.js` is recieved by the client, it opens an `XMLHttpRequest` for
95`/~/on/{window.urb.poll}.json`, bringing us back to `%poll:process`.
97In the case of a non-`%js` `/~/on/`, `%poll:process-parsed` turns into a
98`++new-dependency`, which stores the listening duct, and `pass-note`s a `%wasp`
99with the deps-hash back to `%ford` whence it came. While this occured, the page
100has loaded.
102Some indeterminate amount of time afterwards, with dropped `/~/on/{...}.json`s
103being retried upon expiring and also being stored, a `%news` sign arrives in
104`++axon`, and the hash in question is retrieved from the wire, and the listening
105long-polls retrieved by the hash. Each receives a 205 "Reload parent view" HTTP
106response, which `poll.js` dutifully executes, and a fixed typo of markdown is
107rendered.
109## Authentication.
111Now, while this accurately reflects the presentation of e.g. a markdown file,
112`/cli` is an application front-end, and one that permits only owner access. Its
113second script is `@"/~~/~/at/main/lib/urb.js"`, semantically equivalent to
114`/~/as/own/~/at/main/lib/urb.js`, and handled as follows.
116In `++as-aux-request`, `%as %own` becomes `%auth %get our` perk, which
117`++process` passes to `++process-parsed` passes to `++process-auth`. There, a
118`yac` "ya" core is built `++for-client`: a `++cookie-prefix`, which is just the
119serving ship name, is used to get a `++session-from-cookies`, here nil as the
120client has no cookie set. In lieu of a cookie, a `++new-ya` is constructed, with
121a random token `hole` and a `++new-cyst` which fills out `cyst` session state
122from request data.
124Returning to `++process-auth`, `%get` checks if the yac is authenticated with
125the requested credentials(`anon` requests are always granted), which for the
126fresh new `cyst` is not the case (more on success [later](#auth-ok)). Unless
127authentiacting as a [foreign ship](#xeno), the only thing left is to
128`++show-login-page`, which detects that the requested resource is not `%html`,
129and produces a `%red` pest. For `%js`, `%red`irections `++resolve` to
130`++auth-redir:js`, a line of javascript which prepends `/~~` to the url path.
132The owner-authenticated main page request similarly ends in `++show-login-page`,
133which for the empty session is an `[%htme ++login-page:xml]`, `resolve`d to
134`++give-html` with a 401 "unathorized".
136The login page shows a simple prompt, and requests `/~/at/auth.js` to handle the
137submission. And so we are, once again, attempting to divine if what we're doing
138makes sense `++as-aux-request`.
140To understand `/~/at`, there will first be a brief diversion to `~/auth.json`.
141`auth.json`, perk `[%auth %json]`, in `++process-auth` serves `++stat-json:ya`,
142containing such information as the serving ship, which identities are associated
143with this session, and `oryx`, a CSRF token. An oryx must be present on all
144stateful requests, in this case executing a log in. It also saves the new/old
145session using `abet`.
147XX explain `ixor` here and not [later](#ixor)?
149`/~/at` is an alternate interface, which injects `auth.json` data into the
150requested file. `/~/at/auth.js`, then, is a request for the built-in `auth:js`
151(parsed to and processed from an `[%auth %js ~]` perk), with session data added
152as `window.urb`. And indeed, ``[`%js /~/at/auth]`` is parsed to
153``[%auth at [`%js /auth]``, which in `++process-auth` is re-`process`ed to
154`[%js ++auth:js]`, which is `++resolve`d after an `++add-json` of
155the relevant data. The yac cookies are also passed to `resolve`, which
156`++add-cookies` injects into the `httr`.
158It is at this point that there is first occasion for user input, namely the password.
160The `auth:js` script sends a `PUT` request, also to `/~/auth.json`. In `parse`,
161the first nontrivial `++check-oryx` occurs, `++grab-body` the request oryx and
162ensuring it is recorded for the session. The request parsed with `++need-body`
163to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
164`++load-secret`, upon success updates the session with `++logon:ya`, and
165serves a fresh `auth.json` which reflects the changed `user`. Upon recieving
166this, the page is refreshed to retry the original request.
168## Post-authentication: app communication. [#auth-ok]
170Upon refresh, `/~~/cli` brings us for the third time to `%get:process-auth`, but
171this time the cookie is set, and the `yac` fetched contains the serving ship as
172authenticated. The `++handle` sample is updated to reflect the requesting ship,
173and the `process` continues for the rest of the pork, once again serving the
174ford page.
176The `/~/on/[deps].json` poll starts anew, and `/~~/~/at/main/lib/urb.js` we now
177know to serve the window.urb necessary to make requests, and the `urb.js`
178standard library which extends it with a number of wrappers to them and other
179useful functions.
181---
183One of those functions is `urb.bind`, which is used to subscribe to application
184data. Userspace javascript sets `urb.appl` to `/tic`, and binds `lines` to a
185`;pre;` text display, using a callback.
187This triggers a `PUT` to `/~/is/{ixor}/cli/lines.json`, where `ixor` is a hash
188of `oryx` that identifies the connection. `++as-aux-request`, an `%is` is a
189`%subs` subscription update update, which for `%put` forwards to
190`++add-subs:ix`, the ix core fetched `++for-view` by hashing the request
191`++oryx-to-ixor`.
193[#ixor] A view has all the state associated with a client that must be
194remembered between events. In this case, this is what app/path the request duct
195is associated with; but mainly, `++add-subs:ix` will `pass-note` to `%gall` so
196it `%show`s the data on the path, current and future.
198This will immediately(assuming the ship is local) result in a `%nice` by the
199`/cli` app, returning `{ok:true}` `++nice-json` to `urb.bind`'s second callback
200as `{ok:true}`. The initial `%rush` results also arrive, and in `++axon` are
201converted to json using `++back`(ford `%cast` wrapper), and when `%made` get
202passed to `++get-rush:ix`. There the source application/path are decoded by
203duct, and then the full event goes to `++get-even`; `++add-even` inserts it to
204the queue, and as there is no long poll it simply stays there.
206Upon receipt, the client realizes the long-poll isn't actually running, so that
207is started using `urb.poll`. At `/~/of/{ixor}`, perk
208`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
209is retrieved by `++ire-ix` form global state, using the perk `ixor`): the
210sequence number is in the past, so the previously recieved `%rush` is
211`++give-even`. After deleting the previous message in the queue and invoking
212`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
213the source app+path `++subs-to-json`, and returned to the polling duct.
215On the client, the user callback receives the `/cli` history, and displays it on
216the page. The `/~/of` long poll is continued, this time reaching `++poll:ix`
217with the "pending" sequence number, and being stored in the `cyst` for its troubles.
219---
221Its next update proceeds idenitcally, but first it must be triggered, which
222happens when the user enters "(add 2 2)\n", firing an `urb.send` from the event
223handler. This sends a `POST` request to `/~/to/cli/json.json`, perk `%mess`,
224`++process`ed to a `%g %mess`. Were the mark not `%json`, a `%ford` conversion
225would occur first, and `%made:axon` would send the gall message proper. In
226either case, eventually a `%mean` or `%nice` arrives, is encoded as json, and
227sent to the client callback.
229## A path not taken: magic filenames [#mage]
231The `/robots.txt` and `/favicon.(ico|png)` files are static, and served
232immediately when caught by a `++parse`.
234XX index.html?
236## A path not taken: foreign auth [#xeno]
238While this example details a login `/~/as/own`, it is possible to be
239authenticated as any ship on the network. A request for such seen in
240`%get:process-auth` is passed to `++foreign-auth:ya`, which sends an
241`%ames /lon` message to the ship in question. The foreign ship stores the
242inquiry, calculates(the local) `++our-host` and responds with a `/hat`,
243containing the redirection host, which is stored by `++foreign-hat`; it is later
244used to send the client to a `/~/am` url on the foreign client, which acts as a
245normal login page but later sends the client back. XX expand, basically the
246status quo is you're logged in and `/~/as/foo` is ignored, just setting your
247`urb.user` XX
250## A path not taken: deauthentication
252`/~/away`, perk `[%away ~]`, produces a static `++logout-page:xml`, which also
253uses `/~/at/auth.js`, to send a `DELETE /~/auth.json`, perk `[%auth %del]`. This
254executes `++logoff:ya` for the cookie session, resolving to `++abut` to wipe it
255from memory.
257## A path not taken: unsubscription
259`DELETE /~/is/app/path/within` works much like `PUT /~/is/app/path/within`,
260`++del-subs:ix` acting as reverse of `++add-subs` by deleting the duct binding
261and sending `%g %nuke`.
264XX unmentioned arms: abet, add-poll, adit, ames-gram, anon, ares-to-json, bolo, cyst, doze, even, ford-kill, get-mean, gift, give-json, give-thou, gram, hapt, hasp, host-to-ship, ix, ixor, js, kiss, load, mean-json, move, note, pass-note, perk, perk-auth, pest, poke-test, print-subs, render-tang, resp, root-beak, scry, ses-authed, ses-ya, sign, silk, sine, stay, stem, teba, titl, to-oryx, urb, wait-era, wake, whir, wush, xml, ya, ye
266## Appendix A: DNS [#dns]
268The `*.urbit.org` domain can be used to access destroyers and cruisers. In the
269common case oh hosted ships, this is done by dynamic DNS directly to the hosting
270instance. We do not speak of the uncommon case. When ports are blocked and
271infrastructure crumbles around you, only imported martian networking can be
272trusted: the `%get` and `%got` [gram]()s are used to proxy [`%this` requests]() and
273[`%thou` responses]() respectively.