@@ -0,0 +1,721 @@
1++++
2+title = "Overview"
3+weight = 1
4+template = "doc.html"
5+aliases = ["/docs/learn/arvo/eyre/"]
6++++
7+
8+*Current docs on Eyre are out of date. Until they are updated this doc remains for historical purposes*
9+
10+
11+Our HTTP server.
12+
13+Unix sends http messages to `%eyre`, and `%eyre` produces http messages
14+in response. In general, apps and vanes do not call `%eyre`; rather,
15+`%eyre` calls apps and vanes. `%eyre` uses `%ford` and `%gall` to
16+functionally publish pages and facilitate communication with apps.
17+
18+`%eyre` primarily parses web requests and handles them in a variety of
19+ways, depending on the control string. Nearly all of these are
20+essentially stateless, like functional publishing with `%ford`.
21+Additionally, there's a fairly significant component that handles
22+`%gall` messaging and subscriptions, which must be stateful.
23+
24+## Reference
25+
26+### State
27+
28+Stored
29+
30+- `++bolo`
31+- `++cyst`
32+- `++stem`
33+
34+Runtime
35+
36+- `perk`
37+ + `perk-auth`
38+- `pest`
39+- `even`
40+
41+### Cores
42+
43+- `++handle`
44+ + `++parse`
45+ - `++as...`
46+- `++ya`
47+- `++ix`
48+
49+## Commentary
50+
51+
52+Let us follow the loading of a simple cli app, as it bounces from
53+browser to server to browser and back.
54+
55+### Initial request
56+
57+An http request for `http://sampel-sipnym.urbit.org/cli` will be [redirected](dns)
58+to the `%eyre` on ~sampel-sipnym, and come in as a `%this` task.
59+
60+From arvo, requests enter `++call`, which after some type reification are passed
61+along to `++apex:ye`. In the case of a `%this` task, its components are
62+parsed(see `++zest:epur`, `++eat-headers`) and handed off to `++handle`, wrapped
63+in `++emule` to produce a `++fail` page in case of error. `++apex:handle` will
64+`++process` the request to a `pest` or a `++done` [core](/docs/glossary/core/), and in the former case
65+`++resolve` the pest into an outgoing card.
66+
67+XX it also seems to affect the current ship, test that serving ship name is consistently correct
68+
69+The pest is produced by `++process`, which will first further `++parse` the
70+request, and if this does not make the response immediately obvious,
71+`++process-parsed` the resulting `perk`.
72+
73+`++parse` produces the `perk`, by attempting to interpret the `pork`(url path)
74+[`++as-magic-filename`](#mage), `++as-beam`, and `++as-aux-request`. In this
75+case, `/cli` is parsed by the second case as a `%beam` query to `/=cli=`: a path
76+which starts with a valid ship name is expected to be a full clay(well, ford)
77+path, and one starting with a term implies the current serving ship and a case
78+of `0`, the current revision.
79+
80+XX spur: when the desks are merged, `/cli` shall point to `/=main=/pub/cli`
81+
82+The parsed `perk` generates a `%f %boil` note, `mark`ed as its extension(here
83+defaulting to `%urb`) and `wire`d with `~` to return unaltered to the client. It
84+goes on to `++resolve` by being passed to `++ford-get-beam`, which translates
85+the perk it into a `%boil` `++ford-req`, adding an `++fcgi` path-segment
86+containing query string and `++fcgi-cred:for-client` auth information.
87+
88+`%ford`s translation of `/=cli=/hymn/hook` to a self-refreshing `%urb` html page
89+[deserves its own commentary](/docs/arvo/ford#commentary), but
90+we resume in `%eyre` when the `%made` sign arrives in `++take`, and soon after
91+`++axon:ye`. There the `wire`, or rather the `whir` it has been verified to be,
92+determines that the response should be served immediately. However, as the mark
93+is not `%mime`, another trip to `%ford` is required to encode it, on the same
94+wire; afterwards, the value of the `%mime` cage is verified to be of the correct type, and finally
95+delivered back up the requesting duct as a successful `%thou` HTTP response.
96+
97+XX `%cast %mime` used to be in ford-get-beam, is there a reason it was removed?
98+
99+## Back into the breach, or: auxilary requests
100+
101+Now, it was mentioned that this result is self-refreshing: the `%urb`
102+translation [door](/docs/glossary/door/) injects a `;script@"/~/on/{deps}.js"` into every page, `deps`
103+is a ford-readable hash of the set of resources that page construction depended
104+on.
105+
106+This triggers another `%this` request. Its handling is identical to that of
107+`/cli` up until `++parse`, where it is seen not `++as-beam` but
108+`++as-aux-request`(auxillary requests starting with `/~/` or `/~~/`).
109+`/on/[hash]` is a long-`%poll`, which `++process-parsed`, for a `.js` mark,
110+answers with a direct `%js`. Its contents are the static `++poll:js`, which
111+initiates the long-polling loop, run against an injected `urb.js` of
112+`{poll:[hash]}`.
113+
114+A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
115+
116+When `poll.js` is received by the client, it opens an `XMLHttpRequest` for
117+`/~/on/{window.urb.poll}.json`, bringing us back to `%poll:process`.
118+
119+In the case of a non-`%js` `/~/on/`, `%poll:process-parsed` turns into a
120+`++new-dependency`, which stores the listening duct, and `pass-note`s a `%wasp`
121+with the deps-hash back to `%ford` whence it came. While this occured, the page
122+has loaded.
123+
124+Some indeterminate amount of time afterwards, with dropped `/~/on/{...}.json`s
125+being retried upon expiring and also being stored, a `%news` sign arrives in
126+`++axon`, and the hash in question is retrieved from the wire, and the listening
127+long-polls retrieved by the hash. Each receives a 205 "Reload parent view" HTTP
128+response, which `poll.js` dutifully executes, and a fixed typo of markdown is
129+rendered.
130+
131+## Authentication
132+
133+Now, while this accurately reflects the presentation of e.g. a markdown file,
134+`/cli` is an application front-end, and one that permits only owner access. Its
135+second script is `@"/~~/~/at/main/lib/urb.js"`, semantically equivalent to
136+`/~/as/own/~/at/main/lib/urb.js`, and handled as follows.
137+
138+In `++as-aux-request`, `%as %own` becomes `%auth %get our` perk, which
139+`++process` passes to `++process-parsed` passes to `++process-auth`. There, a
140+`yac` "ya" core is built `++for-client`: a `++cookie-prefix`, which is just the
141+serving ship name, is used to get a `++session-from-cookies`, here nil as the
142+client has no cookie set. In lieu of a cookie, a `++new-ya` is constructed, with
143+a random token `hole` and a `++new-cyst` which fills out `cyst` session state
144+from request data.
145+
146+Returning to `++process-auth`, `%get` checks if the yac is authenticated with
147+the requested credentials(`anon` requests are always granted), which for the
148+fresh new `cyst` is not the case (more on success [later](#auth-ok)). Unless
149+authenticating as a [foreign ship](#xeno), the only thing left is to
150+`++show-login-page`, which detects that the requested resource is not `%html`,
151+and produces a `%red` pest. For `%js`, `%red`irections `++resolve` to
152+`++auth-redir:js`, a line of javascript which prepends `/~~` to the url path.
153+
154+The owner-authenticated main page request similarly ends in `++show-login-page`,
155+which for the empty session is an `[%htme ++login-page:xml]`, `resolve`d to
156+`++give-html` with a 401 "unathorized".
157+
158+The login page shows a simple prompt, and requests `/~/at/auth.js` to handle the
159+submission. And so we are, once again, attempting to divine if what we're doing
160+makes sense `++as-aux-request`.
161+
162+To understand `/~/at`, there will first be a brief diversion to `~/auth.json`.
163+`auth.json`, perk `[%auth %json]`, in `++process-auth` serves `++stat-json:ya`,
164+containing such information as the serving ship, which identities are associated
165+with this session, and `oryx`, a CSRF token. An oryx must be present on all
166+stateful requests, in this case executing a log in. It also saves the new/old
167+session using `abet`.
168+
169+XX explain `ixor` here and not [later](#ixor)?
170+
171+`/~/at` is an alternate interface, which injects `auth.json` data into the
172+requested file. `/~/at/auth.js`, then, is a request for the built-in `auth:js`
173+(parsed to and processed from an `[%auth %js ~]` perk), with session data added
174+as `window.urb`. And indeed, ``[`%js /~/at/auth]`` is parsed to
175+``[%auth at [`%js /auth]``, which in `++process-auth` is re-`process`ed to
176+`[%js ++auth:js]`, which is `++resolve`d after an `++add-json` of
177+the relevant data. The yac cookies are also passed to `resolve`, which
178+`++add-cookies` injects into the `httr`.
179+
180+It is at this point that there is first occasion for user input, namely the password.
181+
182+The `auth:js` script sends a `PUT` request, also to `/~/auth.json`. In `parse`,
183+the first nontrivial `++check-oryx` occurs, `++grab-body` the request oryx and
184+ensuring it is recorded for the session. The request parsed with `++need-body`
185+to a `[%auth %try {password}]` perk. `%get:process-auth` checks it against
186+`++load-secret`, upon success updates the session with `++logon:ya`, and
187+serves a fresh `auth.json` which reflects the changed `user`. Upon receiving
188+this, the page is refreshed to retry the original request.
189+
190+### Post-authentication: app communication.
191+
192+Upon refresh, `/~~/cli` brings us for the third time to `%get:process-auth`, but
193+this time the cookie is set, and the `yac` fetched contains the serving ship as
194+authenticated. The `++handle` sample is updated to reflect the requesting ship,
195+and the `process` continues for the rest of the pork, once again serving the
196+ford page.
197+
198+The `/~/on/[deps].json` poll starts anew, and `/~~/~/at/main/lib/urb.js` we now
199+know to serve the window.urb necessary to make requests, and the `urb.js`
200+standard library which extends it with a number of wrappers to them and other
201+useful functions.
202+
203+One of those functions is `urb.bind`, which is used to subscribe to application
204+data. Userspace javascript sets `urb.appl` to `/tic`, and binds `lines` to a
205+`;pre;` text display, using a callback.
206+
207+This triggers a `PUT` to `/~/is/{ixor}/cli/lines.json`, where `ixor` is a hash
208+of `oryx` that identifies the connection. `++as-aux-request`, an `%is` is a
209+`%subs` subscription update update, which for `%put` forwards to
210+`++add-subs:ix`, the ix core fetched `++for-view` by hashing the request
211+`++oryx-to-ixor`.
212+
213+A view has all the state associated with a client that must be
214+remembered between events. In this case, this is what app/path the request duct
215+is associated with; but mainly, `++add-subs:ix` will `pass-note` to `%gall` so
216+it `%show`s the data on the path, current and future.
217+
218+This will immediately(assuming the ship is local) result in a `%nice` by the
219+`/cli` app, returning `{ok:true}` `++nice-json` to `urb.bind`'s second callback
220+as `{ok:true}`. The initial `%rush` results also arrive, and in `++axon` are
221+converted to json using `++back`(ford `%cast` wrapper), and when `%made` get
222+passed to `++get-rush:ix`. There the source application/path are decoded by
223+duct, and then the full event goes to `++get-even`; `++add-even` inserts it to
224+the queue, and as there is no long poll it simply stays there.
225+
226+Upon receipt, the client realizes the long-poll isn't actually running, so that
227+is started using `urb.poll`. At `/~/of/{ixor}`, perk
228+`[%view ixor ~ {sequence-number}]`, it is `process`ed by `++poll:ix` (the cyst
229+is retrieved by `++ire-ix` form global state, using the perk `ixor`): the
230+sequence number is in the past, so the previously received `%rush` is
231+`++give-even`. After deleting the previous message in the queue and invoking
232+`++pass-took` to signal `%gall` of this occurrence, the data is annotated with
233+the source app+path `++subs-to-json`, and returned to the polling duct.
234+
235+On the client, the user callback receives the `/cli` history, and displays it on
236+the page. The `/~/of` long poll is continued, this time reaching `++poll:ix`
237+with the "pending" sequence number, and being stored in the `cyst` for its troubles.
238+
239+Its next update proceeds idenitcally, but first it must be triggered, which
240+happens when the user enters "(add 2 2)\n", firing an `urb.send` from the event
241+handler. This sends a `POST` request to `/~/to/cli/json.json`, perk `%mess`,
242+`++process`ed to a `%g %mess`. Were the mark not `%json`, a `%ford` conversion
243+would occur first, and `%made:axon` would send the gall message proper. In
244+either case, eventually a `%mean` or `%nice` arrives, is encoded as json, and
245+sent to the client callback.
246+
247+## A path not taken: magic filenames
248+
249+The `/robots.txt` and `/favicon.(ico|png)` files are static, and served
250+immediately when caught by a `++parse`.
251+
252+XX index.html?
253+
254+## A path not taken: foreign auth
255+
256+While this example details a login `/~/as/own`, it is possible to be
257+authenticated as any ship on the network. A request for such seen in
258+`%get:process-auth` is passed to `++foreign-auth:ya`, which sends an
259+`%ames /lon` message to the ship in question. The foreign ship stores the
260+inquiry, calculates(the local) `++our-host` and responds with a `/hat`,
261+containing the redirection host, which is stored by `++foreign-hat`; it is later
262+used to send the client to a `/~/am` url on the foreign client, which acts as a
263+normal login page but later sends the client back. XX expand, basically the
264+status quo is you're logged in and `/~/as/foo` is ignored, just setting your
265+`urb.user` XX
266+
267+
268+### A path not taken: deauthentication
269+
270+`/~/away`, perk `[%away ~]`, produces a static `++logout-page:xml`, which also
271+uses `/~/at/auth.js`, to send a `DELETE /~/auth.json`, perk `[%auth %del]`. This
272+executes `++logoff:ya` for the cookie session, resolving to `++abut` to wipe it
273+from memory.
274+
275+### A path not taken: unsubscription
276+
277+`DELETE /~/is/app/path/within` works much like `PUT /~/is/app/path/within`,
278+`++del-subs:ix` acting as reverse of `++add-subs` by deleting the duct binding
279+and sending `%g %nuke`.
280+
281+
282+XX 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
283+
284+### Appendix A: DNS
285+
286+The `*.urbit.org` domain can be used to access destroyers and cruisers. In the
287+common case oh hosted ships, this is done by dynamic DNS directly to the hosting
288+instance. We do not speak of the uncommon case. When ports are blocked and
289+infrastructure crumbles around you, only imported martian networking can be
290+trusted: the `%get` and `%got` grams are used to proxy `%this` requests and
291+`%thou` responses respectively.
292+
293+## Specification
294+
295+The `%eyre` vane serves one purpose: receiving inbound HTTP requests from browsers and clients pretending to be browsers. To facilitate this communication, `%eyre` does two things: 1. provide an API for traditional clients to talk to; and 2. provide a mechanism for saving state that allows the server to keep track of identities/sessions, subscription data, and active connections.
296+
297+This document outlines the following:
298+
299+1. [`perk`](#perk), a `pork` subset that defines what URLs the client can send to `%eyre`.
300+
301+2. [the values stored on the client](#client), both statically in cookies and dynamically as the `window.urb` object, which facilitate this transaction.
302+
303+3. [`task`](#task), the requests `%eyre` will accept.
304+
305+4. [`gift`](#gift), the responses it will give to those requests.
306+
307+5. [`note`](#note), the set of arvo requests that %eyre makes to the other vanes.
308+
309+6. [`whir`](#whir), a `wire` subset, the associated dynamic state
310+
311+7. [`sign`](#sign), the responses `%eyre` accepts
312+
313+8. [`bolo`](#bolo), the state stored between separate events.
314+
315+## 1. URL structure
316+
317+There exist several URL forms accepted by `%eyre`.
318+
319+### 1.1 Functional request
320+
321+The simplest of them is a static `%f` functional publish request:
322+
323+```
324+ GET /[ship]/[desk]/[case]/path/to/file.[mark]
325+```
326+e.g.
327+
328+```
329+ /~pittyp-pittyp/main/5/lib/urb.js
330+```
331+A `case` of 0 signifies the most recent version.
332+
333+If no file extension is provided, the default `mark` is `%urb`, which consists of `%html` injected with an auto-refresh script.
334+
335+A shorter form:
336+
337+```
338+ /path/to.[mark]
339+```
340+is prepended with the [default request path](#prefix). For example, if `%eyre`
341+is configured with a root of `/<our>/main/0/pub`, then `/doc/arvo` is
342+interpreted as a request for `/=main=/pub/doc/arvo.urb`.
343+
344+Auxiliary paths start with `/~/`, and provide other functionality, such as:
345+
346+### 1.2 Auto-reload
347+
348+When a new version of a page becomes available, it is useful to propagate it to the client. The `%f` vane manages the particulars, and provides an update token along with all published pages. The `/~/on` long-polling endpoint makes use of that token, which is a hash of the server-stored dependency set.
349+- `/~/on/[hash].json` retuns `true` when a page may require updating.
350+- `/~/on/[hash].js` is a lightweight script that polls for the above. It is primarily used in error messages.
351+
352+### 1.3 Authentication
353+
354+Authenticated requests are accomplished through sessions, tracked with cookies which are set on the first such request.
355+- `/~/as/[user]/...` is an authenticated request to `...`, where `user` can be a `@p` ship, `'own'`, `'any'`, or `'anon'`.
356+ + `'anon'` is a randomly-generated per-session submarine, and requires no further authentication.
357+ + `'own'` represents the serving ship. The short form of `/~/as/own/` is `/~~/`
358+ + `'any'` requires a network ship, chosen with a prompt if unknown. The short form of `/~/as/any/` is `/_/`
359+ + Auth requests are handled in three ways:
360+ + I. If the session is associated with the `ship`, serve `...`, storing the ship as the session's default ship. For example, `/~/as/sivtyv-barnel/main/pub/test.html` is an authenticated request of `/main/pub/test.html` with the identity of `~sivtyv-barnel`.
361+ + II. If the session is not associated with the `ship` in the path, the client is redirected to a login page, where a password can be entered. Successful authentication results in a page refresh to the requested path.
362+ + III. otherwise, [send a message](#foreign) to the claimed ship, and redirect the user to `https://[foreign-host]/~/am/[ses]/...#[current-host]&?code=[code]`
363+- `/~/am/[ses]/...#original-host` similarly serves a login page. Upon success, inform the `ship` of the success and redirect it back to `http://[original-host]/~/as/<this-ship>/...`
364+- `/~/away.html` is a log-out page.
365+- `/~/auth.json` returns `{ship,oryx,user,auth}`: the serving ship, a CSRF token, active user, and all allowed users respectively.
366+- `/~/at/{...}.js` is an alternate form of `/~/auth.json`, which injects a line into the served js file that sets `{ship, oryx, user, auth}` on the `window.urb` object.
367+
368+So far, all the paths specified have been GET requests. Authentication, however, requires sending data. This is also done at the `/~/auth.json` endpoint.
369+- `POST {oryx,ship,code} /~/auth.json?PUT` is used by the login script to authorize a user, and returns the same result as `GET`, additionally containing either`{ok:true}` or `{fail:'type',mess:"Error message"}`
370+- `POST {oryx,ship?} /~/auth.json?DELETE` revokes authorization. Response as above.
371+
372+### 1.4 Messaging
373+
374+- `POST {oryx, wire, xyro} /~/to/[app]/[mark].json`, where `xyro` is data that will be converted to the `mark`. In the simplest case, `/~/to/hello/json.json` will pass `xyro` through verbatim, sending `[%json xyro]` to the `++poke` arm of app `%hello`.
375+- `POST {oryx, wire, xyro} /~/to/<ship>/[app]/[mark].json` is a foreign message send, as above.
376+
377+### 1.5 Subscriptions
378+
379+- `/~/of/[ixor]` is an `EventSource`: a conceptually infinite file containing a stream of events. By default, it sends a newline every 30 seconds serving to signal that the connection is alive to both the server and IP middleware.
380+ + `/~/of/[ixor]?poll={n}` is a long-polling fallback interface. Produces event number `{n}`, blocking until it occurs. Its contexts can be affected by `POST` requests with a body of `{oryx, wire}`, and a query string of `PUT` or `DELETE`. They return either `{mark}`(which may be `null`), or [`{fail, mess}`](#mean-json)
381+- `/~/in/[hash].json` is a dual to [`/~/on`](#on-change). It binds `mod` events, which echo the requesting token.
382+- `/~/is/[app]/path/to.[mark]` binds `rush` events, formatted with a first line of `[app] /path/to`, and the rest containing subscription data. Additionally, `mean` events formatted similarly may arrive, also converted to the relevant mark.
383+
384+
385+
386+### 1.6 Ablative
387+
388+These interfaces will temporarily exist to aid development, and are to be considered unstable.
389+- `/~/debug/...` access normally inaccessible pages. For example, `/~/debug/as.html` will present the login page, regardless of current session status.
390+
391+
392+## 2. Client state
393+
394+Some information is stored on, and provided to, browser clients
395+
396+### 2.1 Cookies
397+
398+Authenticated users receive a cookie on the domain of `*.urbit.org`. The cookie contains a client session token, keyed by the serving ship.
399+
400+### 2.2 Authentication
401+
402+It is common(e.g. by the `%urb` mark) to set window.urb to the contents of `/~/auth.json`:
403+- `ship` is the serving ship
404+- `oryx` is a unique CSRF token that identifies this view, bound to the session cookie
405+- `ixor` is a hash of `oryx`, used as an insecure view identifier
406+- `user` is the authenticated/generated ship name
407+- `auth` is a list of identities usable by this session
408+
409+### 2.3 Client library
410+
411+To this object, `/main/lib/urb.js` adds helpers:
412+- `app` is an optional app name to send messages to by default
413+- `send({data,mark?='json',app?=urb.app,ship?}, cb?)` delivers messages
414+- `bind({path,app?=urb.app}, cb)` subscribes by path
415+- `drop({path,app?=urb.app}, cb?)` pulls the subscription
416+- `util` is an object containing methods for converting between JavaScript types and Hoon [atom](/docs/glossary/atom/) auras.
417+
418+## 3. Requests
419+
420+## `[%born port=@ud]`, unix init
421+
422+When the `vere` process is re/started, a TCP port is bound, HTTP requests on which are the scope of this document. The `%born` gift informs eyre of this occurrence, which in turn updates [its state.](#bolo)
423+
424+**Gifts given in response:** none.
425+
426+## `[%hiss p=mark q=cage]`, outbound http
427+
428+Userspace http request, converted by `%ford` into an actual `hiss`.
429+
430+**Gifts given in response:** a `%sigh`
431+
432+### 3.1 `[%this httq]`, inbound http
433+
434+The primary `%eyre` request type comes from the host system, and constitutes an inbound http request. It consists of five parts:
435+
436+I. `p=[? @if]`: a loobean determining whether the request is being made over https, and the client source, an IPv6 address possibly encoding an IPv4 one as `.0.0.0.0.0.ffff.wwxx.yyzz`
437+
438+II. `q=meth`, an http method
439+
440+III. `r=@t`, the unparsed URL
441+
442+IV. `s=mess`, an associative list of header keys/values
443+
444+V. `t=(unit octs)`, the request body, if any.
445+
446+After `r` is parsed to a `purl`, the `pork`(relative path) determines the resource being served. The first step in handling an http request is [classifying its intent](#perk).
447+
448+- A ford request results in a [`%boil` note](#boil).
449+- `/~/[name].js` is generated from [session](#sink) or [view](#stem) state, and [served](#mime) as `%js`.
450+- `/~/am` generates a login page.
451+- `/~/as` is resolved further if authenticated, generates a similar login page if the claimed ship is local, and otherwise is saved to [session state](#sink) and sends a ["login" `%a` message](#lon) to the foreign ship.
452+- `/~/at` and `/~/auth.json` generate a new `oryx` and store it in the [session state](#sink).
453+- `/~/in` and `/~/is` affect [view state](#stem), possibly sending subscriptions or unsubscriptions to `%f` and `%g` respectively, and are generated from view state.
454+- `/~/on` is saved to the `bolo` by `hash`, and translated to a [`%wasp` note](#wasp).
455+- `/~/of` fails if the `ixor` is unknown, and otherwise is stored in the `ixor`, receiving a partial response and all events after its [last-seen header](#). If it has a `poll` parameter, the response is full, and only occurs if the body is non-empty. Otherwise the oryx is saved as a [live](#live) request in case of cancellation.
456+- `/~/to` transforms into a [`%g` message](#mess).
457+
458+**Gifts given in response:** a `%thou`, or a [`%that`](#that) followed by multiple `%thar`s.
459+
460+### 3.2 `[%thud ~]`, inbound close
461+
462+Sent when an unresponded-to request is cancelled. The [live](#live) effect of the request is looked up, and
463+- `%exec` ford boil requests are cancelled with `[%exec ~]`
464+- `%wasp` ford deps requests are cancelled with `[%wasp |]`
465+- `%poll` session polls `%rest` the session heartbeat timeout
466+
467+### 3.3 `[%thin p=@ud]`, delivery failure
468+
469+Sent when a partial [response](#that) or [body](#thar) fails to arrive. Its `duct` is the same as that of the original request. This is handled by [waiting](#wait) for the client to reconnect, and if this not occur, unwinding all subscription state.
470+
471+
472+**Gifts given in response:** None.
473+
474+### 3.4 ``[%wart sock [path *]]``, inbound message
475+
476+Sometimes, messages are received from other ships. They are expected to take the from of a `gram`.
477+
478+**Gifts given in response:** [`%nice` or `%mean`](#ack).
479+
480+#### 3.4.1 `gram`
481+
482+There are three messages of note, all concerning authentication
483+- `[/lon ses]` is a login request, which contains the session wishing to authenticate.
484+- if the session is already authorized, a reply of `[/aut ses]` from (%eyre on) a foreign ship prescribes that the session is henceforth allowed to act on its behalf. All waiting `/~/as` are resolved as successful.
485+- otherwise, `[/hat ses hart]` contains the ship's preferred hostname. This can then be used to redirect the client. All waiting `/~/as` are given `307 Redirect`s to `/~/am` on the provided host.
486+
487+**Gifts given in response:** nice?
488+
489+## 4. Responses
490+
491+### 4.1 `[%nice ~]`, `[%mean ares]`, network acknowledgement
492+
493+A `%nice` is given upon receiving an [ames message](#gram), indicating succesful receipt. `%mean` is currently unused directly, but reserved for error conditions.
494+
495+## `[%sigh p=cage]`, inbound http response
496+
497+An HTTP response gets converted to the requested mark, or `%tang` in case of error.
498+
499+### 4.2 `[%thou httr]`, full HTTP response
500+
501+Most requests are served with one coherent response, consisting of
502+- `p=@ud`, an HTTP status code
503+- `q=mess`, response headers
504+- `r=(unit octs)`, an optional body
505+
506+### 4.3 `[%that httr]`, partial HTTP response
507+
508+[EventStream responses](#of-ixor) consist of multiple sequential chunks. Treated as `%thou`, except the request is kept open.
509+
510+### 4.4 `[%thar (unit octs)]`, partial HTTP body
511+
512+Complementing `%that`, `%thar` is a body chunk, containing an event. An empty `%thar` signals for the connection to be closed.
513+
514+Body chunks, besides `[1 '\0a']`(a heartbeat newline), are encoded from `even` events. The stem becomes the [`event` field](#eventsource), and the content, `data` lines.
515+
516+#### 4.4.1 `even`, event types
517+
518+There are three events that a [client subscription](#subs) will be given.
519+
520+- `[%news hash]` is a `%f` update, and contains the relevant dependency token.
521+- `[%mean [term path] ares]` is a sourced subscription error.
522+
523+## 5. Vane requests
524+
525+### 5.1 ``[%a %wont sock `[path *]`gram]``, outbound message
526+
527+The `%a` interface provides conveyance of [messages](#gram) over UDP.
528+
529+Signs a `%woot` upon message arrival.
530+
531+
532+All open [subscriptions](#of-ixor) require a "heartbeat" newline every `~s30`. When this fails to arrive, a complementary timer is set for `~m1`, after which the client is considered to have departed.
533+The `%b` timer interface is used to schedule the next such event, or cancel past scheduled ones when a connection closes.
534+
535+Signs a `%wake` upon timer activation.
536+
537+### 5.3 `[%f %wasp @uvI]`, dependency listen
538+
539+Knowledge of filesystem changes, requested by `/~/on` and `/~/in`, is requested the `%wasp` note. It contains the hash token which identifies a set of dependencies to query. Saved as a (live[live](#live)] request in case of cancellation when caused by `/~/on`.
540+
541+Signs a `%writ` upon change.
542+
543+### 5.4 `[%f %exec (unit silk)]`, functional transformations
544+
545+The `%f` interface converts [nouns](/docs/glossary/noun/) from one form to another. An empty unit represents cancellation.
546+
547+Signs a `%made` containing the computation result.
548+
549+The `silk`s used are as follows:
550+
551+### `[%cast %mime %boil mark beam [%web span ~]]`, file load
552+
553+The simplest functional request is the construction of a page. Saved as a [live](#live) request in case of cancellation.
554+- The `mark` is the request extension, defaulting to `%html`.
555+- A `beam`(path in `%clay`) is decoded from the request path.
556+- A `/web/<nyp ced quy>` virtual path is appended, span-encoding method, auth, and query string.
557+
558+### `[%cast mark %done ~ cage]`, convert
559+
560+This is used when communicating with apps, in both directions.
561+- Client messages are encoded as JSON objects, but can contain many different marks. Ones sent to non-`json.json` endpoints are `%cast` to he relevant mark, with a `cage` of `[%json p:!>(*json) jon]`, prior to being sent onwards to applications with `[%g %mess]`.
562+- Subscription responses also come in arbitrary marks, but are required to be sent as whichever mark an endpoint is subscribed to. They get `%cast` prior to being sent back as a `%that` EventSource segment.
563+
564+### 5.5 `%g`, app actions
565+
566+The end goal of many a userspace `hymn.hook` is to provide UI for a `%gall` app. To accommodate this, various functionality needs to be interfaced with.
567+
568+### `[%mess hapt ship cage]`, app message
569+
570+After a `/~/to` POST has been received, and possibly converted to the correct mark, it is sent to `%g` for processing. The `hapt` is the destination, the `ship` is the source, the `cage` is the marked message data.
571+
572+Signs a `%nice` or `%mean`, in userspace or upon crashing.
573+
574+### `[%show hapt ship path]`, app subscription
575+
576+An `/~/is` PUT, if not already registered, results in a new subscription. A request for such contains the destination `hapt`, requesting `ship`, and app-internal `path`.
577+
578+Signs a `%nice` on init, `%rush` on data, and a `%mean` in subscription termination.
579+
580+### `[%took hapt ship]`, %rush confirmation
581+
582+A `%took` must be sent to acknowledge the receipt of subscription data, which in this case occurs automatically.
583+
584+Causes no signs.
585+
586+### `[%nuke hapt $|(ship [ship path])]`, subscription cancel
587+
588+An `/~/is` DELETE is used to remove a subscription, and is converted straightforwardly to a `%nuke`. Additionally, when a client disconnects, all of its subscriptions are `%nuke`d to reflect their expiration.
589+
590+Signs an empty `%mean` for each open subscription that is closed.
591+
592+## 6. In-flight metadata
593+
594+Various state can be associated with requests, but not necessarily be returned in responses to them.
595+
596+### 6.1 `~`, dropthrough
597+
598+If the response should be sent statelessly further up the duct, the `wire` is empty. This is used in `%f` pure functional page generation.
599+
600+### 6.2 `[?(%y %n) ...]`, stability
601+
602+The first element of a [`%b` timer](#wait) path distinguishes between live(%y) and dying(%n) channels.
603+
604+### 6.3 `/of/[ixor]`, view
605+
606+Designates which stream to act upon. Present on `%b` timer cards.
607+
608+### 6.4 `/on/<deps>`
609+
610+Present on `%f` dependency news. Looked up in [the state](#bolo) to see if any response is necessary.
611+
612+### 6.5 `/to/<hasp>/<ship>`, app
613+
614+Present on `%f` translations of message marks
615+
616+### 6.6 `/is/[ixor]/{hasp path}`, subscription
617+
618+Subscription requests. Present on `%g` subscription requests, and `%f` translations of [`%rush` subscription data](#show).
619+
620+## 7. Vane responses
621+
622+The goal of requests is to cause some manner of result. Specifically,
623+
624+### 7.1 `[%a %woot ship coop]`, acknowledgement
625+
626+A [message](#mess) which has been acknowledged remotely.
627+
628+### 7.2 `[%b %wake ~]`, timer
629+
630+Timer activate. If this is a `%y` [timer](#wire-live), send a newline to each `/~/of/[oryx]`; if `%n` and the `oryx` still has no listeners, wipe its state/subscriptions.
631+
632+### 7.3 `[%f %news ~]`, dependency update
633+
634+This message signifies a `hash` has changed, and listeners to it should be updated. Results in [`%news` events](#even-news) to concerned streams, and [full responses](#thou) to relevant long-polls.
635+
636+### 7.4 `[%f %made (each bead (list tank))]`, compute result
637+
638+Further action depends on the [`wire`](#whir). It can:
639+- Be empty, designating direct request data, which is [served](#mime) back up the `duct`.
640+- Contain [app and requester identities](#wire-to), which designates an app message has been converted to the correct `mark`, and can now be [sent to the app](#mess) with an empty `wire`.
641+- Contain an `oryx`, app, and `path`, designating subscription data. If the subscription is active in the relevant `stem`, it is acknowledged with a `%took` and given as a [`%rush` event](#even-rush) to all listeners. Otherwise, the subscription is `%nuke`d.
642+
643+### 7.5 `%g`, applications
644+
645+The `%g` interface sends several responses.
646+
647+### `[%nice ~]` and `[%mean ares]`, acknowledgment
648+
649+These are given as a response to `%mess`, with an empty wire, and `%show`s, with a [subscription wire](#wire-is).
650+The former is [served](#mime) back to the requester(i.e. the remaining duct), and the latter returned to the client.
651+
652+#### 7.5 `[%rush cage]`, subscription data
653+
654+A `%rush` arrives on a [subscription wire](#wire-is), and is then sent [for conversion](#done) to the correct mark. An unexpected `%rush` is `%nuke`d.
655+
656+## 8. Server state
657+
658+There is a quantity of data that persists between events.
659+
660+### 8.1 Global
661+
662+- `path` the default path which is prepended to relative plain requests. Initialized to `/<our>`, the serving ship; this interprets the first element of requests as a desk, and injects a `case` of `0`.
663+- `(jar ship hart)` remembered hostnames in order of preference, made accessible through `.^`
664+ + The default values(for self) are `http://<ship>.urbit.org:80` if not on a fake network, followed by `https://0.0.0.0:[port]`.
665+- `(jug deps (each duct oryx))`, `/~/on` and `/~/in` endpoints listening to `%c` updates.
666+- `(map duct live)`, inbound request state
667+- `(map ixor oryx)`, open `/~/of` streams.
668+- `(map oryx stem)`, open view state.
669+- `(map hole sink)`, session state.
670+- `(map hole ,[ship ?])`, foreign session names, along with their origin ships and whether they are authorized to act on our behalf.
671+
672+### 8.2 `live`, per-request state
673+
674+To honor request cancellations, each unserved request must track which effect it is causing.
675++ `[%exec whir]` if it is a ford data request
676++ `[%wasp (list @uvH)]` if it is a ford dependency poll
677++ `[%xeno ship]` if this is a proxied request
678++ `[%poll ixor]` if this is a session long-poll
679+
680+### 8.3 `sink`, per-session state
681+
682+Each `hole` has associated authentication state.
683+- `priv`, a random secret that verifies the session, stored in cookie.
684+- `[ship (set ship)]`, the `ship` a session is acting as and any others it has been authorized with.
685+- `(jug ship ,[path duct])`, authentication `/~/as` requests waiting on foreign ships.
686+- `(set oryx)`, views associated with this session. Dual of `hole` in `stem`.
687+
688+### 8.4 `stem`, per-view state
689+
690+Each `oryx` has active subscription state.
691+- `hole`, session in which this view resides. Dual of `(set oryx)` in `sink`.
692+- `ixor`, a cached hash of the `oryx` that is used as a subscription id, by the `/~/of` EventStream.
693+- `[,@u (map ,@u even)]`, queued [events](#even). Has a maximum size.
694+- `(unit ,[duct @u ?])`, http connection, its last received event, and whether it is a long-poll request.
695+- `(set deps)`, subscribed `/~/in` points. Mirrored in `bolo`.
696+- `(map ,[hasp path] mark)`, subscribed `/~/is` points
697+- `(que duct)`, where any `%nice`/`%mean
698+
699+## Appendix A: Glossary
700+
701+- An `oryx` is a CSRF token used for [authenticated requests](#auth)
702+- `mean.json` is a rendering of hoon `ares`: an error message formatted as `{fail:'type',mess:"Error message"}`
703+- `urb.js` is the standard client-side implementation of the `%eyre` protocols, normally found in `/=main=/lib`
704+- The act of "serving", refers to the wrapping of a `%mime` cage in an HTTP `200 Success` response, and errors or other marks being [sent to ford](#done) for conversion. Inside a `sign`, this conversion occurs along the same [`wire`](#wire); otherwise, the `wire` is [empty](#wire-drop).
705+
706+## Appendix B: EventSource
707+
708+UNIMPLEMENTED
709+
710+For more information, see <http://dev.w3.org/html5/eventsource/>
711+
712+An EventSource is a stream of events, encoded in a conceptually infinite `GET` request. Each event is formatted as
713+```
714+ http
715+ id: {number}
716+ event: {type}
717+ data: {contents}
718+ data: {more-contents}
719+```
720+
721+Data lines are joined by ASCII `10` newline characters; multiple newlines signify separate events. The `id` is used in a `Last-Event-ID` HTTP request header upon reconnection.