@@ -2,720 +2,60 @@
2title = "Overview"
2title = "Overview"
4template = "doc.html"
4template = "doc.html"
5−aliases = ["/docs/learn/arvo/eyre/"]
8−*Current docs on Eyre are out of date. Until they are updated this doc remains for historical purposes*
7+Eyre is the webserver vane.
9+HTTP messages come in from outside and Eyre produces HTTP messages in response. In general, apps do not call Eyre; rather, Eyre calls apps. Eyre has a number of ways to handle such HTTP requests which we'll briefly describe.
11−Our HTTP server.
11+# Authentication
13−Unix sends http messages to `%eyre`, and `%eyre` produces http messages
13+Most types of requests require the client provide a valid session cookie which is obtained by authenticating with your ship's web login code. Authentication is documented in the [Authentication](@/docs/arvo/eyre/external-api-ref.md#authentication) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) documentation.
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.
18−`%eyre` primarily parses web requests and handles them in a variety of
15+# The Channel System
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.
24−## Reference
17+Eyre's channel system is the primary way of interacting with Gall agents from outside of Urbit. It provides a simple JSON API that allows you to send data to apps and subscribe for updates from apps. Updates come back on a SSE ([Server Sent Event](https://html.spec.whatwg.org/#server-sent-events)) stream which you can easily handle with an EventSource object in Javascript or the equivalent in whichever language you prefer.
26−### State
19+The channel system is designed to be extremely simple with just a handful of `action` and `response` JSON objects to deal. Essentially it's a thin layer on top of the underlying Gall agent interface. You can poke agents, subscribe for updates, etc, just like you would from within Urbit.
28−Stored
21+Detailed documentation of the channel system's JSON API is provided in the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document with corresponding examples in the [Examples](@/docs/arvo/eyre/examples.md#using-the-channel-system) document.
30−- `++bolo`
23+# Scrying
34−Runtime
25+Along with the channel system, Eyre also provides a way to make read-only requests for data which are called scries. Eyre's scry interface is separate to the channel system but may be useful in conjunction with it.
36−- `perk`
27+Details of Eyre's scry API are in the [Scry](@/docs/arvo/eyre/external-api-ref.md#scry) section of the [External API Reference](@/docs/arvo/eyre/external-api-ref.md) document.
41−### Cores
29+# Spider Threads
43−- `++handle`
31+Spider (the Gall agent that manages threads) has an Eyre binding that allows you to run threads through Eyre. Spider's [HTTP API](@/docs/userspace/threads/http-api.md) is not part of Eyre proper, so is documented separately in the [Threads](@/docs/userspace/threads/overview.md) documentation.
49−## Commentary
33+# Generators
35+Generators, which are like Hoon scripts, can also be used through Eyre. Rather than having a predefined JSON API, they instead handle HTTP requests and return HTTP responses directly, and are therefore a more complex case that you're less likely to use.
52−Let us follow the loading of a simple cli app, as it bounces from
37+Their usage is explained in the [%serve](@/docs/arvo/eyre/tasks.md#serve) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) documentation and a practical example is provided in the [Generators](@/docs/arvo/eyre/examples.md#generators) section of the [Examples](@/docs/arvo/eyre/examples.md) document.
53−browser to server to browser and back.
55−### Initial request
39+# Direct HTTP Handling With Gall Agents
57−An http request for `http://sampel-sipnym.urbit.org/cli` will be [redirected](dns)
41+As well as the [Channel System](#the-channel-system) and [Scries](#scrying), it's also possible for Gall agents to deal directly with HTTP requests. This method is much more complicated than the channel system so you're unlikely to use it unless you want to build a custom HTTP-based API or something like that.
58−to the `%eyre` on ~sampel-sipnym, and come in as a `%this` task.
60−From arvo, requests enter `++call`, which after some type reification are passed
43+This method is explained in the [%connect](@/docs/arvo/eyre/tasks.md#connect) section of the [Internal API Reference](@/docs/arvo/eyre/tasks.md) document and a detailed example is provided in the [Direct HTTP Handling With Gall Agents](@/docs/arvo/eyre/examples.md#direct-http-handling-with-gall-agents) section of the [Examples](@/docs/arvo/eyre/examples.md) document.
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.
67−XX it also seems to affect the current ship, test that serving ship name is consistently correct
45+# Cross-Origin Resource Sharing
69−The pest is produced by `++process`, which will first further `++parse` the
47+Eyre supports both simple [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) requests and OPTIONS preflight requests. It has a CORS registry with three categories - `approved`, `rejected` and `requests`. Eyre will respond positively for origins in its `approved` list and negatively for all others. Eyre will add origins in requests that it doesn't have in either its `approved` or `rejected` lists to its `requests` list. Eyre always allows all methods and headers over CORS.
70−request, and if this does not make the response immediately obvious,
71−`++process-parsed` the resulting `perk`.
73−`++parse` produces the `perk`, by attempting to interpret the `pork`(url path)
49+There are three generators - `+cors-registry`, `|cors-approve`, and `|cors-reject` to view, approve, and deny origins respectively from the dojo. Eyre also has [tasks](@/docs/arvo/eyre/tasks.md) to [approve](@/docs/arvo/eyre/tasks.md#approve-origin) and [reject](@/docs/arvo/eyre/tasks.md#reject-origin) origins programmatically, and a number of [scry endpoints](@/docs/arvo/eyre/scry.md) to query them. Examples are also included in the [Managing CORS Origins](@/docs/arvo/eyre/examples.md#managing-cors-origins) section of the Examples document.
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.
80−XX spur: when the desks are merged, `/cli` shall point to `/=main=/pub/cli`
51+# Eyre Documentation Sections
82−The parsed `perk` generates a `%f %boil` note, `mark`ed as its extension(here
53+- [External API Reference](@/docs/arvo/eyre/external-api-ref.md) - Details of Eyre's external API including the channel system's JSON API.
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.
88−`%ford`s translation of `/=cli=/hymn/hook` to a self-refreshing `%urb` html page
55+- [Internal API Reference](@/docs/arvo/eyre/tasks.md) - The `task`s Eyre takes and the `gift`s it returns.
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.
97−XX `%cast %mime` used to be in ford-get-beam, is there a reason it was removed?
57+- [Scry Reference](@/docs/arvo/eyre/scry.md) - The scry endpoints of Eyre.
99−## Back into the breach, or: auxilary requests
59+- [Data Types](@/docs/arvo/eyre/data-types.md) - Reference documentation of the various data types used by Eyre.
101−Now, it was mentioned that this result is self-refreshing: the `%urb`
61+- [Examples](@/docs/arvo/eyre/examples.md) - Practical examples of the different ways of using Eyre.
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
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
114−A `%js` `pest` is `resolve`d as a `text/javascript` success `%this`.
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`.
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
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
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.
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
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.
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".
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`.
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`.
169−XX explain `ixor` here and not [later](#ixor)?
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`.
180−It is at this point that there is first occasion for user input, namely the password.
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.
190−### Post-authentication: app communication.
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
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
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.
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
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.
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.
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.
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.
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.
247−## A path not taken: magic filenames
249−The `/robots.txt` and `/favicon.(ico|png)` files are static, and served
250−immediately when caught by a `++parse`.
254−## A path not taken: foreign auth
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
268−### A path not taken: deauthentication
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
275−### A path not taken: unsubscription
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`.
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
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.
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.
297−This document outlines the following:
299−1. [`perk`](#perk), a `pork` subset that defines what URLs the client can send to `%eyre`.
301−2. [the values stored on the client](#client), both statically in cookies and dynamically as the `window.urb` object, which facilitate this transaction.
303−3. [`task`](#task), the requests `%eyre` will accept.
305−4. [`gift`](#gift), the responses it will give to those requests.
307−5. [`note`](#note), the set of arvo requests that %eyre makes to the other vanes.
309−6. [`whir`](#whir), a `wire` subset, the associated dynamic state
311−7. [`sign`](#sign), the responses `%eyre` accepts
313−8. [`bolo`](#bolo), the state stored between separate events.
317−There exist several URL forms accepted by `%eyre`.
319−### 1.1 Functional request
321−The simplest of them is a static `%f` functional publish request:
324− GET /[ship]/[desk]/[case]/path/to/file.[mark]
329− /~pittyp-pittyp/main/5/lib/urb.js
331−A `case` of 0 signifies the most recent version.
333−If no file extension is provided, the default `mark` is `%urb`, which consists of `%html` injected with an auto-refresh script.
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`.
344−Auxiliary paths start with `/~/`, and provide other functionality, such as:
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.
352−### 1.3 Authentication
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.
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.
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.
377−### 1.5 Subscriptions
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.
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.
394−Some information is stored on, and provided to, browser clients
398−Authenticated users receive a cookie on the domain of `*.urbit.org`. The cookie contains a client session token, keyed by the serving ship.
400−### 2.2 Authentication
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
409−### 2.3 Client library
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.
420−## `[%born port=@ud]`, unix init
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)
424−**Gifts given in response:** none.
426−## `[%hiss p=mark q=cage]`, outbound http
428−Userspace http request, converted by `%ford` into an actual `hiss`.
430−**Gifts given in response:** a `%sigh`
432−### 3.1 `[%this httq]`, inbound http
434−The primary `%eyre` request type comes from the host system, and constitutes an inbound http request. It consists of five parts:
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`
438−II. `q=meth`, an http method
440−III. `r=@t`, the unparsed URL
442−IV. `s=mess`, an associative list of header keys/values
444−V. `t=(unit octs)`, the request body, if any.
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).
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).
458−**Gifts given in response:** a `%thou`, or a [`%that`](#that) followed by multiple `%thar`s.
460−### 3.2 `[%thud ~]`, inbound close
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
467−### 3.3 `[%thin p=@ud]`, delivery failure
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.
472−**Gifts given in response:** None.
474−### 3.4 ``[%wart sock [path *]]``, inbound message
476−Sometimes, messages are received from other ships. They are expected to take the from of a `gram`.
478−**Gifts given in response:** [`%nice` or `%mean`](#ack).
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.
487−**Gifts given in response:** nice?
491−### 4.1 `[%nice ~]`, `[%mean ares]`, network acknowledgement
493−A `%nice` is given upon receiving an [ames message](#gram), indicating succesful receipt. `%mean` is currently unused directly, but reserved for error conditions.
495−## `[%sigh p=cage]`, inbound http response
497−An HTTP response gets converted to the requested mark, or `%tang` in case of error.
499−### 4.2 `[%thou httr]`, full HTTP response
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
506−### 4.3 `[%that httr]`, partial HTTP response
508−[EventStream responses](#of-ixor) consist of multiple sequential chunks. Treated as `%thou`, except the request is kept open.
510−### 4.4 `[%thar (unit octs)]`, partial HTTP body
512−Complementing `%that`, `%thar` is a body chunk, containing an event. An empty `%thar` signals for the connection to be closed.
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.
516−#### 4.4.1 `even`, event types
518−There are three events that a [client subscription](#subs) will be given.
520−- `[%news hash]` is a `%f` update, and contains the relevant dependency token.
521−- `[%mean [term path] ares]` is a sourced subscription error.
525−### 5.1 ``[%a %wont sock `[path *]`gram]``, outbound message
527−The `%a` interface provides conveyance of [messages](#gram) over UDP.
529−Signs a `%woot` upon message arrival.
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.
535−Signs a `%wake` upon timer activation.
537−### 5.3 `[%f %wasp @uvI]`, dependency listen
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`.
541−Signs a `%writ` upon change.
543−### 5.4 `[%f %exec (unit silk)]`, functional transformations
545−The `%f` interface converts [nouns](/docs/glossary/noun/) from one form to another. An empty unit represents cancellation.
547−Signs a `%made` containing the computation result.
549−The `silk`s used are as follows:
551−### `[%cast %mime %boil mark beam [%web span ~]]`, file load
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.
558−### `[%cast mark %done ~ cage]`, convert
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.
564−### 5.5 `%g`, app actions
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.
568−### `[%mess hapt ship cage]`, app message
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.
572−Signs a `%nice` or `%mean`, in userspace or upon crashing.
574−### `[%show hapt ship path]`, app subscription
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`.
578−Signs a `%nice` on init, `%rush` on data, and a `%mean` in subscription termination.
580−### `[%took hapt ship]`, %rush confirmation
582−A `%took` must be sent to acknowledge the receipt of subscription data, which in this case occurs automatically.
586−### `[%nuke hapt $|(ship [ship path])]`, subscription cancel
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.
590−Signs an empty `%mean` for each open subscription that is closed.
592−## 6. In-flight metadata
594−Various state can be associated with requests, but not necessarily be returned in responses to them.
596−### 6.1 `~`, dropthrough
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.
600−### 6.2 `[?(%y %n) ...]`, stability
602−The first element of a [`%b` timer](#wait) path distinguishes between live(%y) and dying(%n) channels.
604−### 6.3 `/of/[ixor]`, view
606−Designates which stream to act upon. Present on `%b` timer cards.
610−Present on `%f` dependency news. Looked up in [the state](#bolo) to see if any response is necessary.
612−### 6.5 `/to/<hasp>/<ship>`, app
614−Present on `%f` translations of message marks
616−### 6.6 `/is/[ixor]/{hasp path}`, subscription
618−Subscription requests. Present on `%g` subscription requests, and `%f` translations of [`%rush` subscription data](#show).
622−The goal of requests is to cause some manner of result. Specifically,
624−### 7.1 `[%a %woot ship coop]`, acknowledgement
626−A [message](#mess) which has been acknowledged remotely.
628−### 7.2 `[%b %wake ~]`, timer
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.
632−### 7.3 `[%f %news ~]`, dependency update
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.
636−### 7.4 `[%f %made (each bead (list tank))]`, compute result
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.
643−### 7.5 `%g`, applications
645−The `%g` interface sends several responses.
647−### `[%nice ~]` and `[%mean ares]`, acknowledgment
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.
652−#### 7.5 `[%rush cage]`, subscription data
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.
658−There is a quantity of data that persists between events.
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.
672−### 8.2 `live`, per-request state
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
680−### 8.3 `sink`, per-session state
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`.
688−### 8.4 `stem`, per-view state
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
699−## Appendix A: Glossary
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).
706−## Appendix B: EventSource
710−For more information, see <http://dev.w3.org/html5/eventsource/>
712−An EventSource is a stream of events, encoded in a conceptually infinite `GET` request. Each event is formatted as
718− data: {more-contents}
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.