- [x] Rip out existing response handling code
- [x] Logging mechanism
- [x] Review "BCP 14" to properly interpret the key words: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL"
- Client-server protocol
- [x] Servers listen on port 1965 when served over TCP/IP
- [x] One type, roughly equivalent to HTTP GET method, structured like so:
```
C: Opens connection
S: Accepts connection
C/S: Complete TLS handshake (see section 4)
C: Validates server certificate (see 4.2)
C: Sends request (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 body (text or binary data) (see 3.3)
S: Closes connection (including TLS close_notify, see section 4)
C: Handles response (see 3.4)
```
- [x] Gemini resources identified via URIs
- [x] "gemini" scheme
- [x] Compatible with URI syntax in RFC 3986, with the following caveats:
- [x] Authority component is allowed and required
- [x] userinfo subcomponent is NOT allowed
- [x] Host subcomponent is required
- [x] Port subcomponent is optional, defaults to 1965
- [x] Path, query and fragment components are allowed and have no special meaning beyond those defined by the generic syntax
- [x] Empty path is equivalent to a path consisting of "/"
- [x] Spaces in paths should be encoded as `%20`, not as `+`
- [x] Clients SHOULD normalize URLs (as per section 6.2.3 of RFC before sending requests
- [x] Servers SHOULD normalize received URIs before processing a request
- [x] Single CRLF-terminated line with the following structure:
- [x] <URL><CR><LF>
- [x] <URL>
- [x] UTF-8 encoded
- [x] Absolute URL
- [x] Includes a scheme
- [x] Scheme can optionally be something other than `gemini://`, i.e., for proxying or protocol-translating gateways
- [x] Proxying optional
- [x] Maximum length is 1024 bytes
- [x] Request MUST NOT begin with a U+FEFF byte order mark
- Clients MUST NOT send anything after the first occurrence of <CR><LF> in a request
- [x] Servers MUST ignore anything sent after the first occurrence of a <CR><LF>
- [x] Single CRLF-terminated header line
- [x] optionally followed by response body
- [x] <STATUS><SPACE><META><CR><LF>
- [x] <STATUS>
- [x] 2-digit numeric code (described in its own section, see below and appendix notes)
- [x] If not in the "SUCCESS" range, server MUST close the connection after sending the header and MUST NOT send a response body
- If server sends something not a 2-digit number or a <META> exceeding 1024 bytes in length, the client SHOULD close the connection and disregard the response header, informing the user of an error
- [x] <SPACE>: Single space character, i.e. the byte 0x20
- [x] <META>
- [x] UTF-8 encoded string
- [x] Max length of 1024 bytes
- [x] Meaning is <STATUS>-dependent
- Response header as a whole and <META> as a substring both MUST NOT begin with a U+FEFF byte order mark
- 2-digit
- Related ones share same first digit, which is also enough for a client to use by itself and ignore the second digit if so desired
- Second digit provides more fine-grained information
- Unambiguous server logging
- More robust user or automated clients
- First digit unambigiously places response into one of 6 categories, which define the semantics of the <META> line
- [x] Codes beginning with 1 are INPUT status codes
- [x] Requested resource accepts a line of textual user input
- [x] <META> line is a prompt which should be displayed to the user
- The same resource should then be requested again with the user's input included as a query component
- [x] Query included in request as per usual generic URL definition in RFC3986, i.e. separated from the path by a `?`
- [x] Reserved characters used in the user's input must be percent encoded as per RFC3986
- [x] Space characters should also be percent-encoded
- [x] Codes beginning with 2 are SUCCESS status codes
- Request was handled successfully
- [x] Response body will follow the response header
- [x] <META> line is a MIME media type which applies to the response body
- [x] Codes beginning with 3 are REDIRECT status codes
- Server is redirecting client to new location for the requested resource
- [x] There is no response body
- [x] <META> is a new URL for the requested resource
- [x] URL may be absolute or relative
- [x] If relative, it should be resolved against the URL used in the original requested
- If contains a query string, the client MUST NOT apply this string to the redirect URL but instead use the redirect url as is
- Redirect is considered temporary (clients should not automatically update bookmarks or perform other automated actions)
- [x] Codes beginning with 4 are TEMPORARY FAILURE status codes
- Request has failed
- [x] No response body
- Nature of failure is temporary, i.e. an identical request MAY succeed in the future
- [x] <META> may provide additional information on failure and should be displayed to human users
- [x] Codes beginning with 5 are PERMANENT FAILURE status codes
- Request has failed
- [x] No response body
- Nature of failure is permanent, i.e., identical requests will reliably fail for the same reason
- [x] <META> may provide additional information on the failure and should be displayed to human users
- Automated clients (aggregators, crawlers, etc.) should not repeat this request
- [x] Codes beginning with 6 are CLIENT CERTFICICATE REQUIRED
- Requested resource requires a client certificate to access
- If request was made without a certificate, it should be repeated with one
- If request was made with a certificate, the server did not accept it and the request should be repeated with a different certificate
- [x] <META> (and/or the specific 6x code) may provide additional information on certificate requirements or the reason a certificate was rejected
- For basic human clients, 4x and 5x may effectively be treated identically, by simply displaying the contents of <META> under a heading of "ERROR"
- Temporary / permanent is more for well-behaving automated clients
- Basic clients may choose not to support client-certificate authentication, in which case only 4 distinct status codes are required: 1x, 2x, 3x, or combined 4x/5x
- See appendix notes for full digit-system
- Any status code with a second digit of 0 corresponds to a generic status of that kind with no special semantics
- This means that basic servers without any advanced functionality need only be able to return codes of 10, 20, 30, 40 or 50
- Status code system purposely designed so the second digits are entirely opt-in for both clients and servers
- [x] Just raw content, text or binary (like gopher)
- No compression support, chunking or any other kind of transfer encoding
- [x] Server closes connection after the final byte
- There is no "end of response" signal gopher's "dot"
- [x] Bodies only accompany responses whose header indicates a SUCCESS (first digit of 2)
- [x] For these, <META> is a MIME media type as defined in RFC 2046
- Internet media types are registered with a canonical form
- [x] Content transferred via Gemini MUST be represented in the appropriate canonical form prior to its transmission except for "text" types, as defined directly below
- When in canonical form, media subtypes of the "text" type use CRLF as the text line break
- [x] Gemini relaxes this requirement
- [x] Allows transport of text media with plain LF alone (but NOT plain CR alone) representing a line break when it is done consistently for an entire response body
- [x] Clients MUST accept CRLF and bare LF as being representative of a line break in text media received via Gemini
- [x] If MIME type begins with "text/" and no charset is explicitly given, charset should be assumed to be UTF-8
- [x] Compliant clients MUST support UTF-8-encoded "text/" responses
- [x] Clients MAY optionally support other encodings
- Clients receiving a response in a charset they cannot decode SHOULD gracefully inform the user what happened instead of displaying garbage
- [x] If <META> is empty string, MIME type MUST default to "text/gemini;charset=utf-8" (text/gemini media type is defined in section 5