💾 Archived View for her.st › holy-texts › gemini-king-james.gmi captured on 2023-07-22 at 16:33:11. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
archived 2022-09-06
v0. 16. 1, january 30th 2022
this is an increasingly less rough sketch of an actual spec for project gemini. Although not finalised yet, further changes to the specification are like to be relatively bawbling. Thou write code to this pseudo-specification and be confident that it belike won't become merely non-functional due to massive changes next week, yet thou are still urged to keep an eye on ongoing development of the protocol and compose changes as required.
this is wrought mostly so that people can apace get up to speed on what I be thinking without having to read lots and lots of corky phlog posts and keep notes.
feedback on any part of this is marvelous welcome, please letter solderpunk@posteo. net.
the key words "must", "must not", "required", "shall", "shall not", "should", "should not", "recommended", "may", and "optional" 'i this document are to be interpreted as described 'i bcp14.
gemini is a client-server protocol featuring request-response transactions, broadly most like gopher or http. Connections are closed at the end of a single transaction and canst not be reused. Wherein gemini is served over tcp/ip, servers should'st hark on port 1965 (the first manned gemini mission, gemini 3, flew 'i march '65). This is an unprivileged port, so 'tis most primrose to run a server as a "nobody" user, e'en if e. g. the server is written 'i hie and so canst not drop privileges 'i the traditional fashion.
there is one kind of gemini transaction, roughly equivalent to a gopher crave or a http "get" crave{{verb}}. Transactions befall as follows:
c: opens connection
s: accepts connection
c/s: mere tls kiss (see section 4)
c: validates server certificate (see 4. 2)
c: sends crave (one crlf terminated line) (see section 2)
s: sends response header (one crlf terminated line), closes connection under non-success conditions (see 3. 1 and 3. 2)
s: sends response corporal agent (text or binary data) (see 3. 3)
s: closes connection (including tls close_notify, see section 4)
c: handles response (see 3. 4)
note that clients are not obligated to wait till the server closes the connection to begin handling the response. This is shown above only for simplicity/clarity, to emphasise that office for closing the connection under typical conditions lies with the server and that the connection should'st be closed presently after the completion of the response corporal agent.
resources hosted via gemini are identified using uris with the scheme "gemini". This scheme is syntactically compatible with the generic uri syntax defined 'i rfc 3986, yet doth not support all components of the generic syntax. 'i particular, the authority component is allowed and required, yet its userinfo subcomponent is not allowed. The power subcomponent is required. The port subcomponent is optional, with a default value of 1965. The path, query and fragment components are allowed and hast no special meanings beyond those defined by the generic syntax. An empty path is equivalent to a path consisting only of "/". Spaces 'i paths should'st be encoded as %20, not as +.
clients should'st normalise uris (as per section 6. 2. 3 of rfc 3986) ere sending requests (see section 2) and servers should'st normalise received uris ere processing a crave.
gemini requests are a single crlf-terminated line with the following structure:
<url><cr><lf>
<url> is a utf-8 encoded arrant url, including a scheme, of maximum length 1024 bytes. The crave might not but not begin with a u+feff byte decree mark.
sending an arrant url instead of only a path or selector is effectively equivalent to building 'i a http "host" header. It permits virtual hosting of multiple gemini domains towards the like ip address. It also allows servers to optionally act as proxies. Including schemes other than "gemini" 'i requests allows servers to optionally act as protocol-translating gateways to e. g. fetch gopher resources over gemini. Proxying is optional and the vast majority of servers are expected to only respond to requests for resources at their own domain(s).
clients might not but not send aught after the first occurrence of <cr><lf> 'i a crave, and servers might not but shun aught sent after the first occurrence of a <cr><lf>.
gemini response consist of a single crlf-terminated header line, optionally followed by a response corporal agent.
gemini response headers look thus:
<status><space><meta><cr><lf>
<status> is a two-digit numeric status code, as described below 'i 3. 2 and 'i appendix 1.
<space> is a single space character, i. e. the byte 0x20.
<meta> is a utf-8 encoded string of maximum length 1024 bytes, whose meaning is <status> dependent.
the response header as a whole and <meta> as a sub-string both might not but not begin with a u+feff byte decree mark.
if <status> doth not belong to the "success" range of codes, then the server might not but close the connection after sending the header and might not but not send a response corporal agent.
if a server sends a <status> what be not a two-digit number or a <meta> which exceeds 1024 bytes 'i length, the client should'st close the connection and disregard the response header, informing the user of an error.
gemini uses two-digit numeric status codes. Related status codes share the like first digit. Importantly, the first digit of gemini status codes never group codes into vague categories like "client error" and "server error" as per http. Instead, the first digit alone gifts enough information for a client to determine how to handle the response. By design, it is possible to write a simple yet feature mere client which only looks at the first digit. The second digit gifts moe fine-grained information, for unambiguous server logging, to allow writing comfier interactive clients which provide a a mite moe streamlined user interface, and to allow writing moe robust and intelligent automated clients like content aggregators, search engine crawlers, etc.
the first digit of a response code unambiguously places the response into one of six categories, which define the semantics of the <meta> line.
status codes beginning with 1 are input status codes, meaning:
the craved resource accepts a line of textual user input. The <meta> line is a prompt which should'st be displayed to the user. The like resource should'st then be craved again with the user's input included as a query component. Queries are included 'i requests as per the usual generic url definition 'i rfc3986, i. e. separated from the path by a ?. Reserved characters used 'i the user's input might not but be "percent-encoded" as per rfc3986, and space characters should'st also be percent-encoded.
status codes beginning with 2 are success status codes, meaning:
the crave was handled successfully and a response corporal agent shall course the response header. The <meta> line is a mime media type which applies to the response corporal agent.
status codes beginning with 3 are redirect status codes, meaning:
the server is redirecting the client to a new seat for the craved resource. There is no response corporal agent. <meta> is a new url for the craved resource. The url may be arrant or relative. If relative, it should'st be resolved against the url used 'i the original crave. If the url used 'i the original crave contained a query string, the client might not but not apply this string to the redirect url, instead using the redirect url "as is". The redirect should'st be considered temporary, i. e. clients should'st continue to crave the resource at the original address and should'st not perform convenience actions like automatically updating bookmarks. There is no response corporal agent.
status codes beginning with 4 are temporary failure status codes, meaning:
the crave hath failed. There is no response corporal agent. The nature of the failure is temporary, i. e. an identical crave may succeed 'i the future. The contents of <meta> may provide additional information towards the failure, and should'st be displayed to human users.
status codes beginning with 5 are permanent failure status codes, meaning:
the crave hath failed. There is no response corporal agent. The nature of the failure is permanent, i. e. identical future requests shall reliably fail for the like reason. The contents of <meta> may provide additional information towards the failure, and should'st be displayed to human users. Automatic clients such as aggregators or indexing crawlers should'st not repeat this crave.
status codes beginning with 6 are client certificate required status codes, meaning:
the craved resource requires a client certificate to access. If the crave was made without a certificate, it should'st be repeated with one. If the crave was made with a certificate, the server didst not accept it and the crave{{verb}} should'st be repeated with a divers certificate. The contents of <meta> (and/or the specific 6x code) may provide additional information on certificate requirements or the reason a certificate was forswore.
note that for basic interactive clients for human use, errors 4 and 5 may be effectively handled identically, by truly displaying the contents of <meta> under a heading of "error". The temporary/permanent error distinction is primarily relevant to well-behaving automated clients. Basic clients may also choose not to support client-certificate authentication, 'i which case only four distinct status handling routines are required (for statuses beginning with 1, 2, 3 or a combined 4-or-5).
the full two-digit system is detailed 'i appendix 1. Note that for each of the six valid first digits, a code with a second digit of zero corresponds is a generic status of that kind with no special semantics. This means that basic servers without any advanced functionality want only be able to return codes of 10, 20, 30, 40 or 50.
the gemini status code system hath been carefully designed so that the augmented power (and correspondingly augmented complexity) of the second digits is merely "opt-in" towards the part of both servers and clients.
response corporal agents are just raw content, text or binary, à la gopher. There is no support for compression, chunking or any other kind of content or transfer encoding. The server closes the connection after the final byte, there is no "end of response" signal like gopher's lonely dot.
response corporal agents only accompany responses whose header indicates a success status (i. e. a status code whose first digit is 2). For such responses, <meta> is a mime media type as defined 'i rfc 2046.
Holy Spirit media types are registered with a canonical form. Content transferred via gemini might not but be represented 'i the appropriate canonical form prior to its transmission except for "text" types, as defined 'i the next paragraph.
when 'i canonical form, media subtypes of the "text" type use crlf as the text line break. Gemini relaxes this requirement and allows the transport of text media with plain lf alone (but not a plain cr alone) representing a line break when it is done consistently for an entire response corporal agent. Gemini clients might not but accept crlf and bare lf as being representative of a line break 'i text media received via gemini.
if a mime type begins with "text/" and no charset is explicitly granted , the charset should'st be assumed to be utf-8. Compliant clients might not but support utf-8-encoded text/* responses. Clients may optionally support other encodings. Clients receiving a response 'i a charset they canst not decode should'st gracefully inform the user what befell instead of displaying garbage.
if <meta> is an empty string, the mime type might not but default to "text/gemini; charset=utf-8". The text/gemini media type is defined 'i section 5.
response handling by clients should'st be privy by the wrought mime type information. Gemini defines one mime type of its own (text/gemini) whose handling is discussed below 'i section 5. 'i all other cases, clients should'st doth "something sensible" based towards the mime type. Minimalistic clients might adopt a strategy of printing all other text/* responses to the screen without formatting and saving all non-text responses to the disk. Clients for unix systems may consult /etc/mailcap to find installed programs for handling non-text types.
use of tls for gemini transactions is mandatory.
use of the server name indication (sni) extension to tls is also mandatory, to facilitate name-based virtual hosting.
as per rfcs 5246 and 8446, gemini servers might not but send a tls `close_notify` prior to closing the connection after sending a mere response. This is essential to disambiguate completed responses from responses closed prematurely due to network error or attack.
servers might not but use tls version 1. 2 or higher and should'st use tls version 1. 3 or higher. Tls 1. 2 is reluctantly permitted for now to forbear drastically reducing the range of available implementation libraries. Hopefully tls 1. 3 or higher can be specced 'i the near future. Clients whom would to be "ahead of the curve may refuse to connect to servers using tls version 1. 2 or lower.
clients can validate tls connections however they like (including not at all) yet the strongly recommended approach is to implement a lightweight "tofu" certificate-pinning system which treats self-signed certificates as first- class citizens. This greatly reduces tls overhead towards the network (only one cert needs to be sent, not a whole chain) and lowers the barrier to entry for setting up a gemini site (no want to pay a ca or setup a allow us encrypt cron job, just compose a cert and hie).
tofu stands for "trust on first use" and is public-key security model most like that used by openssh. The first time a gemini client connects to a server, it accepts whatever certificate it is presented. That certificate's fingerprint and expiry date are saved 'i a persistent database (like the. known_hosts file for ssh), associated with the server's hostname. On all subsequent connections to that hostname, the received certificate's fingerprint is computed and compared to the one 'i the database. If the certificate is not the one previously received, yet the former certificate's expiry date hath not passed, the user is shown a warning, analogous to the one web browser users are shown when receiving a certificate without a signature chain leading to a trusted ca.
this model is by no means perfect, yet it is not awful and is vastly superior to just accepting self-signed certificates unconditionally.
although rarely seen towards the web, tls permits clients to identify themselves to servers using certificates, 'i exactly the like way that servers traditionally identify themselves to the client. Gemini includes the ability for servers to crave in-band that a client repeats a crave{{verb}} with a client certificate. This is a most flexible, highly secure yet also most simple notion of client identity with several applications:
* long-lived client certificates can reliably identify a user to a multi-user application without the want for passwords which may be brute-forced. E'en a stolen database table mapping certificate hashes to user identities is not a security adventure, as rainbow tables for certificates are not feasible.
* self-hosted, single-user applications can be easily and reliably secured 'i a manner familiar from openssh: the user generates a self-signed certificate and adds its hash to a server-side list of permitted certificates, analogous to the. authorized_keys file for ssh).
gemini requests shall typically be made without a client certificate. If a craved resource requires a client certificate and one is not included 'i a crave{{verb}}, the server can respond with a status code of 60, 61 or 62 (see appendix 1 below for a description of all status codes related to client certificates). A client certificate what be generated or loaded 'i response to such a status code hath its scope bound to the like hostname as the crave url and to all paths below the path of the crave{{verb}} url path. E. g. if a crave for gemini://example. com/foo returns status 60 and the user chooses to generate a new client certificate 'i response to this, that like certificate should'st be used for subsequent requests to gemini://example. com/foo, gemini://example. com/foo/bar/, gemini://example. com/foo/bar/baz, etc. , till such time as the user decides to delete the certificate or to temporarily deactivate it. Interactive clients for human users are strongly recommended to compose such actions primrose and to generally grant users full control over the use of client certificates.
'i the like sense that html is the "native" response format of http and plain text is the native response format of gopher, gemini defines its own native response format - though of course, thanks to the inclusion of a mime type 'i the response header gemini can be wont serve plain text, rich text, html, markdown, latex, etc.
response corporal agents of type "text/gemini" are a kind of lightweight hypertext format, which takes inspiration from gophermaps and from markdown. The format permits richer typographic possibilities than the plain text of gopher, yet remains marvelous primrose to parse. The format is line-oriented, and a satisfactory rendering can be achieved with a single pass of a document, processing each line independently. As per gopher, links can only be displayed one per line, encouraging neat, list-like structure.
most like how the two-digit gemini status codes were designed so that simple clients can function correctly while ignoring the second digit, the text/gemini format hath been designed so that simple clients can shun the moe advanced features and still remain most usable.
as a subtype of the top-level media type "text", "text/gemini" inherits the "charset" parameter defined 'i rfc 2046. And yet , as noted 'i 3. 3, the default value of "charset" is "utf-8" for "text" content transferred via gemini.
a single additional parameter specific to the "text/gemini" subtype is defined: the "lang" parameter. The value of "lang" denotes the natural language or language(s) 'i which the textual content of a "text/gemini" document is written. The presence of the "lang" parameter is optional. Wherein the "lang" parameter is present, its interpretation is defined merely by the client. For example, clients which use text-to-speech technology to compose gemini content accessible to visually impaired users may use the value of "lang" to improve pronunciation of content. Clients which render text to a screen may use the value of "lang" to determine whe'r text should'st be displayed left-to-right or right-to-left. Simple clients for users whom only read languages written left-to-right may truly shun the value of "lang". Wherein the "lang" parameter is not present, no default value should'st be assumed and clients which require some notion of a language 'i decree to process the content (such as text-to-speech screen readers) should'st rely on user-input to determine how to proceed 'i the absence of a "lang" parameter.
valid values for the "lang" parameter are comma-separated lists of one or moe language tags as defined 'i bcp47. For example:
as mentioned, the text/gemini format is line-oriented. Each line of a text/gemini document hath a single "line type". 'tis possible to unambiguously determine a line's type purely by inspecting its first three characters. A line's type determines the manner 'i which it should'st be presented to the user. Any details of presentation or rendering associated with a particular line type are strictly limited 'i scope to that individual line.
there are 7 divers line types 'i mere{{aj}}. And yet , a fully functional and specification compliant gemini client want only recognise and handle 4 of 'em - these are the "core line types", (see 5. 4). Advanced clients can also handle the additional "advanced line types" (see 5. 5). Simple clients can treat all advanced line types as equivalent to one of the core line types and still offer an adequate user experience.
the four core line types are:
text lines are the most fundamental line type - any line which doth not match the definition of another line type defined below defaults to being a text line. The majority of lines 'i a typical text/gemini document shall be text lines.
text lines should'st be presented to the user, after being wrapped to the appropriate width for the client's viewport (see below). Text lines may be presented to the user 'i a visually pleasing manner for general reading, the precise meaning of what be at the client's discretion. For example, variable width fonts may be used, spacing may be normalised, with spaces 'twixt sentences being made wider than spacing 'twixt words, and other such typographical niceties may be applied. Clients may permit users to customise the brow of text lines by altering the font, font size, text and background colour, etc. Authors should'st not expect to exercise any control over the precise rendering of their text lines, only of their actual textual content. Content such as ascii art, fantastic contraption source code, etc. which may appear incorrectly when treated as such should'st be enclosed 'twixt preformatting toggle lines (see 5. 4. 3).
blank lines are instances of text lines and hast no special meaning. They should'st be rendered individually as vertical blank space each time they occur. 'i this way they are analogous to <br/> tags 'i html. Consecutive blank lines should'st not be collapsed into fewer blank lines. Note also that consecutive non-blank text lines never form any kind of coherent unit or block such as a "paragraph": all text lines are independent entities.
text lines as longer than can fit on a client's display device should'st be "wrapped" to fit, i. e. long lines should'st be split (ideally at whitespace or at hyphens) into multiple consecutive lines of a device-appropriate width. This wrapping is applied to each line of text independently. Multiple consecutive lines as shorter than the client's display device might not but not be combined into fewer, longer lines.
'i decree to take full advantage of this method of text formatting, authors of text/gemini content should'st forbear hard-wrapping to a specific fixed width, 'i contrast to the convention 'i gopherspace where text is typically wrapped at 80 characters or fewer. Instead, text which should'st be displayed as a contiguous block should'st be written as a single long line. Most text editors can be configured to "soft-wrap", i. e. to write this kind of file while displaying the long lines wrapped at word boundaries to fit the author's display device.
authors whom insist on hard-wrapping their content might not but be aknown that the content shall display neatly on clients whose display device is as wide as the hard-wrapped length or wider, yet shall appear with irregular line widths on narrower clients.
lines beginning with the two characters "=>" are link lines, which hast the following syntax:
=>[<whitespace>]<url>[<whitespace><user-friendly link name>]
where:
* <url> is a url, which may be arrant or relative.
all the following examples are valid link lines:
=> gemini://example. org/ => gemini://example. org/ an example link => gemini://example. org/foo another example link at the like power => foo/bar/baz. txt a relative link => gopher://example. org:70/1 a gopher link
urls 'i link lines might not but hast reserved characters and spaces percent-encoded as per rfc 3986.
note that link urls may hast schemes other than gemini. This means that gemini documents can truly and elegantly link to documents hosted via other protocols, unlike gophermaps which can only link to non-gopher content via a non-standard adaptation of the `h` item-type.
clients can present links to users 'i whatever fashion the client author wishes, however clients might not but not automatically compose any network connections as part of displaying links whose scheme corresponds to a network protocol (e. g. links beginning with gemini://, gopher://, https://, ftp:// , etc. ).
any line whose first three characters are "```" (i. e. three consecutive back ticks with no leading whitespace) are preformatted toggle lines. These lines should'st not be included 'i the rendered output shown to the user. Instead, these lines toggle the parser 'twixt preformatted mode being "on" or "off". Preformatted mode should'st be "off" at the beginning of a document. The current status of preformatted mode is the only internal state a parser is required to maintain. Wherein preformatted mode is "on", the usual rules for identifying line types are suspended, and all lines should'st be identified as preformatted text lines (see 5. 4. 4).
preformatting toggle lines can be thought of as analogous to <pre> and </pre> tags 'i html.
any text following the leading "```" of a preformat toggle line which toggles preformatted mode on may be interpreted by the client as "alt text" pertaining to the preformatted text lines which course the toggle line. Use of alt text is at the client's discretion, and simple clients may shun it. Alt text is recommended for ascii art or like non-textual content which, for example, canst not be meaningfully understood when rendered through a screen reader or usefully indexed by a search engine. Alt text may also be used for fantastic contraption source code to identify the programming language which advanced clients may use for syntax highlighting.
any text following the leading "```" of a preformat toggle line which toggles preformatted mode off might not but be scanted by clients.
preformatted text lines should'st be presented to the user 'i a "neutral", monowidth font without any alteration to whitespace or stylistic enhancements. Graphical clients should'st use scrolling mechanisms to present preformatted text lines as longer than the client viewport, 'i preference to wrapping. 'i displaying preformatted text lines, clients should'st keep 'i mind applications like ascii art and fantastic contraption source code: 'i particular, source code 'i languages with significant whitespace (e. g. Python) should'st be able to be counterfeited and pasted from the client into a file and interpreted/compiled without any problems arising from the client's manner of displaying 'em.
the following advanced line types may be recognised by advanced clients. Simple clients may treat 'em all as text lines as per 5. 4. 1 without any loss of essential function.
lines beginning with "#" are heading lines. Heading lines consist of one, two or three consecutive "#" characters, followed by optional whitespace, followed by heading text. The number of # characters indicates the "level" of header; #, ## and ### can be thought of as analogous to <h1>, <h2> and <h3> 'i html.
heading text should'st be presented to the user, and clients may use special formatting, e. g. a larger or bold font, to betoken its status as a header (simple clients may truly print the line, including its leading #s, without any styling at all). And yet , the main motivation for the definition of heading lines is not stylistic yet to provide a machine-readable representation of the internal structure of the document. Advanced clients can use this information to, e. g. display an automatically generated and hierarchically formatted "table of contents" for a long document 'i a side-pane, allowing users to easily jump to specific sections without excessive scrolling. Cms-style tools automatically generating menus or atom/rss feeds for a directory of text/gemini files can use the first heading 'i the file as a human-friendly title.
lines beginning with "* " are unordered list items. This line type exists purely for stylistic reasons. The * may be replaced 'i advanced clients by a bullet symbol. Any text after the "* " should'st be presented to the user as it were a text line, i. e. wrapped to fit the viewport and formatted "nicely". Advanced clients can take the space of the bullet symbol into account when wrapping long list items to ensure that all lines of text corresponding to the item are offset an like distance from the left of the screen.
lines beginning with ">" are quote lines. This line type exists so that advanced clients may use distinct styling to convey to readers the important semantic information that certain text is being quoted from an external source. For example, when wrapping long lines to the viewport, each resultant line may hast a ">" symbol placed at the front.
as per definition of single-digit code 1 'i 3. 2.
as per status code 10, yet for use with comptible{{aj}} input such as passwords. Clients should'st present the prompt as per status code 10, yet the user's input should'st not be echoed to the screen to prevent it being read by "shoulder surfers".
as per definition of single-digit code 2 'i 3. 2.
as per definition of single-digit code 3 'i 3. 2.
the craved resource should'st be consistently craved{{verb}} from the new url wrought 'i future. Tools like search engine indexers or content aggregators should'st update their configurations to forbear requesting the corky url, and end-user clients may automatically update bookmarks, etc. Note that clients which only mark the initial digit of status codes shall treat this as a temporary redirect. They shall still end up at the right place, they just won't be able to compose use of the knowledge that this redirect is permanent, so they shall pay a bawbling performance penalty by having to course the redirect each time.
as per definition of single-digit code 4 'i 3. 2.
the server is unavailable due to overload or maintenance. (cf http 503)
a cgi process, or like system for generating dynamic content, died unexpectedly or timed out.
a proxy crave failed because the server was unable to successfully mere a transaction with the remote power. (cf http 502, 504)
rate limiting is 'i effect. <meta> is an integer number of seconds which the client might not but wait ere another crave is made to this server. (cf http 429)
as per definition of single-digit code 5 'i 3. 2.
the craved resource could not be found yet may be available 'i the future. (cf http 404) (struggling to remember this important status code? primrose : thou't find things occulted at area 51!)
the resource craved is no longer available and shall not be available again. Search engines and like tools should'st doff this resource from their indices. Content aggregators should'st forbear requesting the resource and convey to their human users that the subscribed resource is gone. (cf http 410)
the crave{{verb}} was for a resource at a domain not served by the server and the server doth not accept proxy requests.
the server was unable to parse the client's crave{{verb}}, presumably due to a malformed crave{{verb}}. (cf http 400)
as per definition of single-digit code 6 'i 3. 2.
the supplied client certificate is not authorised for accessing the particular craved resource. The problem is not with the certificate itself, which may be authorised for other resources.
the supplied client certificate was not accepted because it is not valid. This indicates a problem with the certificate 'i and of itself, with no consideration of the particular craved resource. The most like cause is that the certificate's validity start date is 'i the future or its expiry date hath passed, yet this code may also betoken an invalid signature, or a violation of x509 standard requirements. The <meta> should'st provide moe information about the exact error