feat: add Gemini and Spartan protocol support
This commit is contained in:
parent
a4a49f41d7
commit
fa7aa5557c
48 changed files with 4992 additions and 161 deletions
16
SPEC.md
16
SPEC.md
|
|
@ -14,7 +14,7 @@ Flutter version: `3.41.9-sdk-links` (keep in sync with devbox.json).
|
|||
|
||||
## What it is
|
||||
|
||||
A Flutter browser/client for Mews Pages (see mews-spec).
|
||||
A Flutter browser/client for Mews pages (see mews-spec), Gemini capsules and Spartan sites.
|
||||
|
||||
## Approach
|
||||
|
||||
|
|
@ -22,6 +22,20 @@ Local-first: all data is stored locally in a Drift database. Network operations
|
|||
|
||||
Posts found on a subscribed page are stored per site with a read mark, so an unread post survives a restart. A post's address identifies it for its lifetime (spec 6.1), so finding it again never clears its mark. Subscribing to a site stores what it already published as read, so a new subscription arrives without a backlog.
|
||||
|
||||
## Protocols
|
||||
|
||||
The client speaks `gemini://` and `spartan://` alongside the web. A page over either is gemtext, which converts into the same document model a Mews page parses into, so it renders through the same reader presentation, joins the history and the swipes, and can be bookmarked and subscribed to; a link label that begins with a date is a dated entry, so subscriptions work on capsules too. A body's MIME type decides what becomes of it: `text/gemini` is converted, other text is shown plainly as preformatted text, an image is shown in place, and anything else is refused rather than shown as garbage.
|
||||
|
||||
Gemini runs over TLS on port 1965; Spartan runs over plain TCP on port 300 with a request line of host, path and body length. Redirects are followed up to five times and only within the same protocol; a redirect pointing elsewhere is left for the reader to open as their own navigation. Neither protocol has validators, so a cached page is only the offline fallback, never a revalidation. An input request (Gemini 1x) is rendered as a one-field form whose answer rides back as the address's query string; a sensitive input (11) asks quietly.
|
||||
|
||||
Servers present self-signed certificates, so the client decides what to trust itself: the first visit to a host pins the certificate it saw, and every later visit compares against that pin. A change while the pinned certificate has expired is the routine renewal and is accepted silently; a change while it is still valid is refused with an error page offering the reader the choice to trust the new certificate. Trust is per host and port.
|
||||
|
||||
A client certificate is an identity. Certificates are imported from PEM files, one file holding both the certificate and its key or two holding one each, and are named after their file. They are managed on `mews:certificates`, linked from the settings page; removing one takes a second step, because the sites it is worn at lose it too. A certificate is bound to one host at a time and worn only there, and it is presented only when the site asks (Gemini 60): the answer is a picker naming each identity, and the choice is remembered for the next visit. A site that refuses the certificate presented (61) or calls it invalid (62) gets an error page explaining so, with the site's own words under it. Private keys live as files in the app's own storage, never in the database.
|
||||
|
||||
An address typed without a scheme is tried as `https` first, then on its `wap.` subdomain, then over `gemini`, then over `spartan`, before an error is shown; an address carrying a scheme is never second-guessed. When nothing answers, the first error is the one shown, beside the web address.
|
||||
|
||||
An image over a protocol has no address the platform could load, so its bytes are fetched through the same transport, wearing the same trust and identity as the page it appears on, and decoded in place; protocol images are never cached, so they arrive fresh on each visit. A missing image falls back to its alt text, the way a missing web image does.
|
||||
|
||||
# Architecture directives
|
||||
|
||||
Keep files small and focused.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue