summaryrefslogtreecommitdiff
path: root/docs/random/gemini_tldr.md
blob: b232bfd0fcb211f832d1e9d23260cca2dd65c05c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Gemini TL;DR

2020-06-05

For any internet protocol, you can either make it a few thousand words long, or make it 114M. Of course, we know this 114M wasn't there in the first place. W3C has tried very hard to standardize the web, without guarantee it would be simple. So, what we have now is a collaborative system where it's easier to introduce a standard than to deprecate one (remember Adobe Flash?). It's reassuring to know there isn't a central megacorp monopolizing the web, but this openness comes at a cost. It's when evangelical developers who can't program proper desktop apps abruptly choose to make a new web framework, a parasite on web browsers - one of the only things that are largely cross-platform. Because the work of portability has been handled by Mozilla, Google, etc, not by themselves, there is virtually no limitation regarding what you can do with it. If a handful of people suddenly like your "standard", all modern browsers will get to support it eventually.

[Gemini](https://gemini.circumlunar.space/) is a young protocol that's slightly heavier than Gopher, but radically more lightweight than the Web. Its [spec](https://gemini.circumlunar.space/docs/spec-spec.txt) is 4.4k words long as of time of writing, which, excluding the appendix, is a 20-minute read if you skim past the microscopic details. Here is a TL;DR of the specs that's ~1k words long.

## Prerequisites

Before you proceed, there are a few fields of knowledge that you need to temporarily throw away while reading this post, plus a few you don't. Most of the former is HTTP-related.

### Throw away entirely

- CSS
- JavaScript(R)(c)TM
- All the fancy frameworks you have learned about (flask, jinja, react, jquery etc.)
- Apache and nginx

### Place within arm's reach

- HTML
- HTTP:
    - headers
    - 3-digit status codes
    - verbs, e.g. GET, POST
    - cookies

### Do not throw away

- TCP
- TLS

## Gemini spec

### Synopsis

- "Gemini" is the name of a [crewed space mission by NASA](https://en.wikipedia.org/wiki/Project_Gemini).
- this spec is not complete, but probs won't change a lot soon.
- gemini transports data via TCP/IP on port 1965 because the first crewed flight of Gemini was on March 23, 1965. This means unprivileged users can run a gemini server, too.

### Requests and Responses
- Gemini terminates lines with CRLF (`\r\n`) in requests and response headers.
- Everything should be UTF-8.
- Client sends a request to server: `<URL>\r\n`.
- Server first responds with a response header: `<STATUS> <META>\r\n`.
- Speaking of status codes, some helpful ones are `20 SUCCESS`, `30/31 REDIRECT`, and `51 NOT FOUND`. Status codes with the same leading digit belong to the same category and are treated similarly in clients.
- If server returns `2x (SUCCESS)`, it will send a response body (e.g. the page requested, the file the client wishes to download, etc.) right after the response header. In such case, the `<META>` in the header should be the MIME type of the content.
- If the response body belongs to MIME type `text/*`, it should use CRLF as its linebreak. LF is also accepted.
- No support for compression or chunking of the content.
- There is no keep-alive. A TCP connection is closed right after a request and response, and must be re-initiated should the client make another request.
- Sending requests whose URL scheme is not gemini is called "proxying", and is not supported by most servers.

### `text/gemini`

- By default, the response body MIME type is `text/gemini`.
- You can also serve other types, of course, but you'll have to specify in `<META>` of the response header.
- The following list will teach you how to write `text/gemini`.

#### Line types

1. Text lines: ezpz, just normal text. Authors and servers should not "hardwrap", i.e. limit column width to e.g. 80 chars; the client should wrap a long line containing the entire paragraph into a block.
2. Link lines: any non-preformatted line starting with `=>` is a link line. It should be followed by a URL, then optionally a link description. Like this:

```
=> gemini://fkfd.me/ fkfd.me geminispace
```

which is equivalent to this in HTML:

```
<a href="gemini://fkfd.me">fkfd.me geminispace</a>
```

Expect absolute and relative links, and ones that aren't even on gemini.

3. Preformatted lines: any line between two lines that read ````` (3 backticks) is a preformatted line. Just like markdown. Like this (prefixed with a space in order not to interfere with formatting):

```
 ```
 Without preformatted lines, ASCII art wouldn't have been possible!
 ```
```

It should be rendered as monospace.

4. Heading lines: any non-preformatted line starting with 1-3 hashes is a heading line. Also, you know, sure, like markdown. Like this:

```
# h1
## h2
### h3
#### nope, not a heading
###interestingly, the whitespace is optional
```

5. Unordered list items: any non-preformatted line starting with an asterisk is an unordered list item, i.e. an item of a bullet list. Like this:

```
* list item 1
* list item 2
*whitespace is optional again
* although if I want to mimic italics it would be
*pretty* hard
* to distinguish it from list items
```

### TLS

- TLS is mandatory for Gemini.
- You must use TLS 1.2+; 1.3+ is encouraged.
- A client can trust whatever cert it sees, but the recommended approach is to implement a TOFU (Trust On First Use) system, where:
    - you trust the cert the first time you visit a site, even if it's self-signed
    - you remember it
    - every time you access the site, it sends you this very cert, so you know everything's fine
    - the client will warn the user if the server abruptly sent a different cert when its previous one hasn't expired yet: likely a MITM attack (but also likely the site admin just replaced their cert for some reason).

This eliminates the need for a CA, thus making TLS and gemini itself more accessible and widespread.

- A client can prove its identity with a "Transient client certificate".
    - on a site that asks for one, client generates and sends a cert (regular sites don't; such procedure must be manually approved by the user)
    - the cert is sent along with all subsequent requests to this host
    - server can identify this user now
    - this is like cookies in practice, but very different in implementation
    - one cert is limited to one domain
    - one cert should not exist for longer than 24 hours; it's for one session only.

## Conclusion

This is it; 4.4k words of gemini spec summarized & exemplified in ~1k words. Whether you're reading this on Gemini or the Web (or gopher), I encourage you to join this community of members who are seeking asylum from the debris of the modern web. Gemini is still in an early stage; loads of decisions to make, and lots of pitfalls that the web has fallen in to avoid. This concludes our journey around the gemini spec today; see you in low space orbit.

Oh, also, [McRoss](https://git.sr.ht/~nhanb/mcross) is an awesome GUI client.