A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Gemini is Solutionism at its Worst (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://マリウス.com/gemini-is-solutionism-at-its-worst/">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>Gemini is Solutionism at its Worst</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://マリウス.com/gemini-is-solutionism-at-its-worst/" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p class="post-content-excerpt">While I don’t care too much about ideas and projects that I believe to be
  71. dead ends or maybe even doomed to fail eventually, a recent interaction on
  72. <a href="https://マリウス.com/superhighway84">Superhighway84</a> got me to write down a few thoughts on
  73. why I believe Project Gemini is a really bad idea.</p>
  74. <div class="post-content-body">
  75. <p>It all started with a simple post by someone on
  76. <a href="https://マリウス.com/superhighway84">Superhighway84</a> who shared a link to their Gemini site. While
  77. I was interested to see what that person was writing about and working on, I
  78. couldn’t, because that person did not share a HTTP link, with the Gemini URL
  79. as an alternative to it. Instead, it was only a Gemini URL.</p>
  80. <p>Up until a while ago, people were trying out Gemini and only used it as sort of
  81. a mirror for their HTTP content, meaning that everyone could browse their site
  82. one way or the other. However, it seems that more and more people these days
  83. have limited either all or parts of their publishing activity to Gemini. One
  84. better known example I stumbled upon is Drew DeVault, who has been publishing
  85. Gemini-exclusive content for a while now.</p>
  86. <p>As long as projects like Gemini don’t make it harder for people, that aren’t
  87. interested in them, to continue using the internet the way they’re comfortable
  88. with, I don’t have much of an opinion on them. However, with Gemini seemingly
  89. taking over more and more chunks of the things I consume, I felt like pointing
  90. out a few things about the project that I believe make it a really bad idea to
  91. pursue.</p>
  92. <p>My reply to the person’s post on Superhighway84 was the following:</p>
  93. <blockquote>
  94. <p>Hey there,</p>
  95. <p>let me throw in some unpopular opinion, if I might.</p>
  96. <p>I understand where people promoting the smol web (a.k.a Gemini) are coming from
  97. and I feel the same pain on a daily basis. The modern web sucks.
  98. However, I feel like Gemini is <em>solutionism at its worst</em>. If you compare a
  99. single HTTP/1.1 request with a Gemini request you will find out that it’s not
  100. the protocol that’s the issue. HTTP can be made incredibly light. In fact, it
  101. can be so light that even embedded devices (e.g. Arduinos) these days know how
  102. to talk it.</p>
  103. <p>What Gemini is doing, is saying “we don’t need no videos, images, stylesheets,
  104. nor JavaScripts, because we want to have a lightweight web experience, so we
  105. throw all that crap out!”. Fine, sounds great. But why does it require a new
  106. protocol for that? Why couldn’t one simply build on top of existing HTTP
  107. infrastructure, throw away all the baggage and instead implement a new
  108. Content-Type, which existing browsers then could parse?</p>
  109. <p>Existing infrastructure could have been extended to offer a more lightweight
  110. experience of the web that doesn’t come with JS, CSS or anything else. People
  111. then could decide whether they want to go the extra mile of installing Lagrange
  112. or any other dedicated Gemini browser, or simply have a browser extension that
  113. would take care of rendering the Content-Type properly. But Gemini forces people
  114. into a completely different stack. Different servers. Different browsers. Heck,
  115. not even it’s “markdown” is actual markdown, because&amp;mldr;</p>
  116. <blockquote>
  117. <p>There are actually many subtly different and incompatible variants of Markdown
  118. in existence, so unlike TLS all the different libraries are not guaranteed to
  119. behave similarly.</p>
  120. </blockquote>
  121. <p>&amp;mldr; and that’s why it’s obviously a good idea to introduce <strong>another</strong> variant
  122. of Markdown. Makes sense?</p>
  123. <p>Pretty much everything that is being described in the Gemini FAQ could have been
  124. solved on top of already existing protocols and technologies, making it more
  125. available to people. (<a href="https://gemini.circumlunar.space/docs/faq.gmi">https://gemini.circumlunar.space/docs/faq.gmi</a>)</p>
  126. <p>Also, Gemini is asking the wrong questions. For example:</p>
  127. <blockquote>
  128. <p>Why not just use a subset of HTTP and HTML?</p>
  129. </blockquote>
  130. <p>The question here shouldn’t be why not to use a subset of HTTP <em>and</em> HTML, but
  131. rather, why not build <em>on top of</em> HTTP with a different markup layer other than
  132. HTML. We have APIs using HTTP with JSON instead of HTML, for example.</p>
  133. <p>Hence, Gemini, its own text/gemini format, and most of its design choices are
  134. addressing problems that don’t really exist. It’s not significantly different to
  135. existing HTTP infrastructure to justify introducing a new protocol - and it even
  136. depends on it for e.g. offering large files for download.</p>
  137. <p>It’s also not IPFS or ZeroNet. It’s not a blockchain. It’s not bittorrent. It
  138. feels like the people working on/running Gemini infrastructure don’t want to
  139. actually solve the issues with the modern day web and instead just wanted to be
  140. different, for the sake of being different. But unlike for example DAT, that has
  141. truly been different, Gemini however follows the same outdated ideas and
  142. principles that have been around since the 80s and imposes restrictions on
  143. everything they’re not comfortable solving, e.g. file downloads or data
  144. submission.</p>
  145. <p>To me Gemini feels like today’s over-hyped computer version of Teletext.</p>
  146. </blockquote>
  147. <p>In order to make it clear what I mean by <em>building on top of existing HTTP
  148. infrastructure</em>, let me give an actual example.<br>
  149. When your web browser requests a website, it has to connect to the server
  150. hosting that website. That’s usually a TCP connection on port 80 or 443,
  151. depending on whether or not that website is using any sort of transport
  152. encryption. To keep it simple I’m not going into the details of SSL/TLS
  153. here, however, as it’s an encapsulation around the HTTP protocol, requesting
  154. content is identical no matter if the connection is encrypted or not.</p>
  155. <p>Let’s assume I’d like to browse
  156. <a href="http://motherfuckingwebsite.com">motherfuckingwebsite.com</a>. As soon as I enter
  157. the URL in my browser’s address bar, my browser is going to do pretty much the
  158. same that I’ll be doing here using the <code>telnet</code> command:</p>
  159. <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh">telnet motherfuckingwebsite.com <span class="m">80</span>
  160. Trying 108.62.0.112...
  161. Connected to motherfuckingwebsite.com.
  162. Escape character is <span class="s1">'^]'</span>.
  163. GET /index.html HTTP/1.1
  164. Host: motherfuckingwebsite.com
  165. </code></pre></div><p>That’s it.
  166. That’s the bare minimum that this server accepts in order for me to request
  167. the website from it. Most of the time however, browsers will send more
  168. information, like for example the <code>User-Agent</code>, the <code>Accept</code>, <code>Accept-Encoding</code>
  169. and <code>Accept-Language</code> headers, maybe some <code>Cache-Control</code> info, and more
  170. things, depending on which browser you use. While these bits of
  171. information are helping the communication, it’s not like requesting
  172. content without them wouldn’t work at all. The request that I typed into
  173. <code>telnet</code> does not contain any of these headers, yet the server successfully
  174. returns the website that I’m requesting, and even tells me how to interpret this
  175. response:</p>
  176. <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh">HTTP/1.1 <span class="m">200</span> OK
  177. Connection: Keep-Alive
  178. Keep-Alive: <span class="nv">timeout</span><span class="o">=</span>5, <span class="nv">max</span><span class="o">=</span><span class="m">100</span>
  179. content-type: text/html
  180. last-modified: Sun, <span class="m">18</span> Jan <span class="m">2015</span> 00:04:33 GMT
  181. accept-ranges: bytes
  182. content-length: <span class="m">5108</span>
  183. date: Sun, <span class="m">16</span> Jan <span class="m">2022</span> 22:10:29 GMT
  184. server: LiteSpeed
  185. &lt;!DOCTYPE html&gt;
  186. &lt;html&gt;
  187. &lt;head&gt;
  188. &lt;meta <span class="nv">charset</span><span class="o">=</span><span class="s2">"utf-8"</span>&gt;
  189. &lt;meta <span class="nv">name</span><span class="o">=</span><span class="s2">"viewport"</span> <span class="nv">content</span><span class="o">=</span><span class="s2">"width=device-width, initial-scale=1"</span>&gt;
  190. &lt;!-- FOR THE CURIOUS: This site was made by @thebarrytone. Don<span class="s1">'t tell my mom. --&gt;
  191. </span><span class="s1">
  192. </span><span class="s1"> &lt;title&gt;Motherfucking Website&lt;/title&gt;
  193. </span><span class="s1">&lt;/head&gt;
  194. </span><span class="s1">
  195. </span><span class="s1">&lt;body&gt;
  196. </span><span class="s1"> &lt;header&gt;
  197. </span><span class="s1"> &lt;h1&gt;This is a motherfucking website.&lt;/h1&gt;
  198. </span><span class="s1"> &lt;aside&gt;And it'</span>s fucking perfect.&lt;/aside&gt;
  199. &lt;/header&gt;
  200. &lt;h2&gt;Seriously, what the fuck <span class="k">else</span> <span class="k">do</span> you want?&lt;/h2&gt;
  201. &lt;p&gt;You probably build websites and think your shit is special. You think your <span class="m">13</span> megabyte parallax-ative home page is going to get you some fucking Awwward banner you can glue to the top corner of your site. You think your 40-pound jQuery file and <span class="m">83</span> polyfills give IE7 a boner because it finally has box-shadow. Wrong, motherfucker. Let me describe your perfect-ass website:&lt;/p&gt;
  202. &lt;ul&gt;
  203. &lt;li&gt;Shit<span class="s1">'s lightweight and loads fast&lt;/li&gt;
  204. </span><span class="s1"> &lt;li&gt;Fits on all your shitty screens&lt;/li&gt;
  205. </span><span class="s1"> &lt;li&gt;Looks the same in all your shitty browsers&lt;/li&gt;
  206. </span><span class="s1"> &lt;li&gt;The motherfucker'</span>s accessible to every asshole that visits your site&lt;/li&gt;
  207. &lt;li&gt;Shit<span class="s1">'s legible and gets your fucking point across (if you had one instead of just 5mb pics of hipsters drinking coffee)&lt;/li&gt;
  208. </span><span class="s1"> &lt;/ul&gt;
  209. </span><span class="s1">
  210. </span><span class="s1"> &lt;h3&gt;Well guess what, motherfucker:&lt;/h3&gt;
  211. </span><span class="s1">
  212. </span><span class="s1"> &lt;p&gt;You. Are. Over-designing. Look at this shit. It'</span>s a motherfucking website. Why the fuck <span class="k">do</span> you need to animate a fucking trendy-ass banner flag when I hover over that useless piece of shit? You spent hours on it and added <span class="m">80</span> kilobytes to your fucking site, and some motherfucker jabbing at it on their iPad with fat sausage fingers will never see that shit. Not to mention blind people will never see that shit, but they don<span class="s1">'t see any of your shitty shit.&lt;/p&gt;
  213. </span><span class="s1">
  214. </span><span class="s1"> &lt;p&gt;You never knew it, but this is your perfect website. Here'</span>s why.&lt;/p&gt;
  215. &lt;h2&gt;It<span class="s1">'s fucking lightweight&lt;/h2&gt;
  216. </span><span class="s1">
  217. </span><span class="s1"> &lt;p&gt;This entire page weighs less than the gradient-meshed facebook logo on your fucking Wordpress site. Did you seriously load 100kb of jQuery UI just so you could animate the fucking background color of a div? You loaded all 7 fontfaces of a shitty webfont just so you could say "Hi." at 100px height at the beginning of your site? You piece of shit.&lt;/p&gt;
  218. </span><span class="s1">
  219. </span><span class="s1"> &lt;h2&gt;It'</span>s responsive&lt;/h2&gt;
  220. &lt;p&gt;You dumbass. You thought you needed media queries to be responsive, but no. Responsive means that it responds to whatever motherfucking screensize it<span class="s1">'s viewed on. This site doesn'</span>t care <span class="k">if</span> you<span class="s1">'re on an iMac or a motherfucking Tamagotchi.&lt;/p&gt;
  221. </span><span class="s1">
  222. </span><span class="s1"> &lt;h2&gt;It fucking works&lt;/h2&gt;
  223. </span><span class="s1">
  224. </span><span class="s1"> &lt;p&gt;Look at this shit. You can read it ... that is, if you can read, motherfucker. It makes sense. It has motherfucking hierarchy. It'</span>s using HTML5 tags so you and your bitch-ass browser know what the fuck<span class="s1">'s in this fucking site. That'</span>s semantics, motherfucker.&lt;/p&gt;
  225. &lt;p&gt;It has content on the fucking screen. Your site has three bylines and link to your dribbble account, but you spread it over <span class="m">7</span> full screens and make me click some bobbing button to show me how cool the jQuery ScrollTo plugin is.&lt;/p&gt;
  226. &lt;p&gt;Cross-browser compatibility? Load this motherfucker in IE6. I fucking dare you.&lt;/p&gt;
  227. &lt;h2&gt;This is a website. Look at it. You<span class="s1">'ve never seen one before.&lt;/h2&gt;
  228. </span><span class="s1">
  229. </span><span class="s1"> &lt;p&gt;Like the man who'</span>s never grown out his beard has no idea what his <span class="nb">true</span> natural state is, you have no fucking idea what a website is. All you have ever seen are shitty skeuomorphic bastardizations of what should be text communicating a fucking message. This is a real, naked website. Look at it. It<span class="s1">'s fucking beautiful.&lt;/p&gt;
  230. </span><span class="s1">
  231. </span><span class="s1"> &lt;h3&gt;Yes, this is fucking satire, you fuck&lt;/h3&gt;
  232. </span><span class="s1">
  233. </span><span class="s1"> &lt;p&gt;I'</span>m not actually saying your shitty site should look like this. What I<span class="s1">'m saying is that all the problems we have with websites are &lt;strong&gt;ones we create ourselves&lt;/strong&gt;. Websites aren'</span>t broken by default, they are functional, high-performing, and accessible. You <span class="nb">break</span> them. You son-of-a-bitch.&lt;/p&gt;
  234. &lt;blockquote <span class="nv">cite</span><span class="o">=</span><span class="s2">"https://www.vitsoe.com/us/about/good-design"</span>&gt;<span class="s2">"Good design is as little design as possible."</span>&lt;br&gt;
  235. - some German motherfucker
  236. &lt;/blockquote&gt;
  237. &lt;hr&gt;
  238. &lt;h2&gt;Epilogue&lt;/h2&gt;
  239. &lt;p&gt;From the philosophies expressed <span class="o">(</span>poorly<span class="o">)</span> above, &lt;a <span class="nv">href</span><span class="o">=</span><span class="s2">"http://txti.es"</span>&gt;txti&lt;/a&gt; was created. You should try it today to make your own motherfucking websites.&lt;/p&gt;
  240. &lt;!-- yes, I know...wanna fight about it? --&gt;
  241. &lt;script&gt;
  242. <span class="o">(</span><span class="k">function</span><span class="o">(</span>i,s,o,g,r,a,m<span class="o">){</span>i<span class="o">[</span><span class="s1">'GoogleAnalyticsObject'</span><span class="o">]=</span>r<span class="p">;</span>i<span class="o">[</span>r<span class="o">]=</span>i<span class="o">[</span>r<span class="o">]||</span><span class="k">function</span><span class="o">(){</span>
  243. <span class="o">(</span>i<span class="o">[</span>r<span class="o">]</span>.q<span class="o">=</span>i<span class="o">[</span>r<span class="o">]</span>.q<span class="o">||[])</span>.push<span class="o">(</span>arguments<span class="o">)}</span>,i<span class="o">[</span>r<span class="o">]</span>.l<span class="o">=</span>1*new Date<span class="o">()</span><span class="p">;</span><span class="nv">a</span><span class="o">=</span>s.createElement<span class="o">(</span>o<span class="o">)</span>,
  244. <span class="nv">m</span><span class="o">=</span>s.getElementsByTagName<span class="o">(</span>o<span class="o">)[</span>0<span class="o">]</span><span class="p">;</span>a.async<span class="o">=</span>1<span class="p">;</span>a.src<span class="o">=</span>g<span class="p">;</span>m.parentNode.insertBefore<span class="o">(</span>a,m<span class="o">)</span>
  245. <span class="o">})(</span>window,document,<span class="s1">'script'</span>,<span class="s1">'//www.google-analytics.com/analytics.js'</span>,<span class="s1">'ga'</span><span class="o">)</span><span class="p">;</span>
  246. ga<span class="o">(</span><span class="s1">'create'</span>, <span class="s1">'UA-45956659-1'</span>, <span class="s1">'motherfuckingwebsite.com'</span><span class="o">)</span><span class="p">;</span>
  247. ga<span class="o">(</span><span class="s1">'send'</span>, <span class="s1">'pageview'</span><span class="o">)</span><span class="p">;</span>
  248. &lt;/script&gt;
  249. &lt;/body&gt;
  250. &lt;/html&gt;
  251. </code></pre></div><p>On the other hand, according to its specification, a request on the Gemini
  252. protocol looks like this:</p>
  253. <blockquote>
  254. <p>2 Gemini requests</p>
  255. <p>Gemini requests are a single CRLF-terminated line with the following structure:</p>
  256. <p>&lt;URL&gt;&lt;CR&gt;&lt;LF&gt;</p>
  257. <p>&lt;URL&gt; is a UTF-8 encoded absolute URL, including a scheme, of maximum length
  258. 1024 bytes. The request MUST NOT begin with a U+FEFF byte order mark.</p>
  259. <p>Sending an absolute URL instead of only a path or selector is effectively
  260. equivalent to building in a HTTP “Host” header. It permits virtual hosting of
  261. multiple Gemini domains on the same IP address. It also allows servers to
  262. optionally act as proxies. Including schemes other than “gemini” in requests
  263. allows servers to optionally act as protocol-translating gateways to e.g. fetch
  264. gopher resources over Gemini. Proxying is optional and the vast majority of
  265. servers are expected to only respond to requests for resources at their own
  266. domain(s).</p>
  267. <p>Clients MUST NOT send anything after the first occurrence of &lt;CR&gt;&lt;LF&gt; in a
  268. request, and servers MUST ignore anything sent after the first occurrence of a
  269. &lt;CR&gt;&lt;LF&gt;.</p>
  270. </blockquote>
  271. <p>When comparing the most minimal version of an HTTP request with a standard
  272. Gemini request, it turns out that the only difference is a single additionally
  273. required header (<code>Host</code>) and a few additional characters (<code>GET</code> and <code>HTTP/1.1</code>)
  274. in the HTTP request. Hence, Gemini’s argument of being <em>“lighter than the web”</em>
  275. doesn’t make that much of a difference at all from a protocol perspective, and
  276. it certainly does not justify <strong>completely replacing existing infrastructure and
  277. standards that humans have mutually agreed upon</strong>.</p>
  278. <p><em>“But what about the response and the content?"</em>, you might be wondering.
  279. Well, it’s a similar story there. By default, regular HTTP servers will include
  280. all sorts of information in their response that will allow the browser to
  281. process it more easily/without a lot of <em>guesstimating</em>. However, it would
  282. nevertheless be possible to bend existing HTTP servers to only include the bare
  283. minimum additional info in their response, that would still allow a modern
  284. browser to process the data.</p>
  285. <p>As for the actual content, it is easily possible to configure a modern HTTP
  286. server like nginx to respond with nothing but pure Markdown. Users could then
  287. install either of the
  288. <a href="https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-webext/">dozens</a>
  289. of
  290. <a href="https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/">extensions</a>
  291. available for their web browser, to be able to visit the Markdown-only websites
  292. more comfortably. If Gemini would have gone that path, people interested in <em>the
  293. smol internet</em> would still be able to develop custom tailored clients that only
  294. work with these type of websites, and that would not include all the baggage that
  295. comes with any modern browser. Everybody else, on the other hand, could continue
  296. using the tools their familiar with and would still be able to to consume the
  297. content.</p>
  298. <p>Gemini instead opted for a different direction, which <strong>actively excludes people</strong>,
  299. while it <strong>does not deliver anything new nor beneficial</strong> that would justify
  300. dismissing existing standards and infrastructure in first place. Gemini is
  301. solutionism at its worst and is more about exclusion of the mainstream over
  302. bringing actual technological advancement, let alone fixing the issues it
  303. baselessly claims to be fixing. Gemini does not bring new ideas to the table,
  304. but instead uses decade old concepts from HTTP and Gopher, to implement a
  305. castrated and badly designed version of its own, just for the sake of it not
  306. being HTTP nor Gopher.</p>
  307. <blockquote>
  308. <p>To me, Gemini looks like a mix of Gopher and HTTP/0.9 and it’s a mystery to me
  309. why you would rather write a new protocol so similar to those rather than just
  310. stick to what already exists.<br>
  311. – <a href="https://curl.se/mail/lib-2020-11/0084.html">Daniel Stenberg, founder and lead developer of cURL</a></p>
  312. </blockquote>
  313. <p><em>“But&amp;mldr; but&amp;mldr; it takes user privacy <strong>very seriously</strong>?"</em><br>
  314. Okay, how so? Let’s quickly check the FAQ:</p>
  315. <blockquote>
  316. <p>2.1.2 Privacy</p>
  317. <p>Gemini is designed with an acute awareness that the modern web is a privacy
  318. disaster, and that the internet is not a safe place for plaintext. Things like
  319. browser fingerprinting and Etag-based “supercookies” are an important cautionary
  320. tale: user tracking can and will be snuck in via the backdoor using protocol
  321. features which were not designed to facilitate it. Thus, protocol designers must
  322. not only avoid designing in tracking features (which is easy), but also assume
  323. active malicious intent and avoid designing anything which could be subverted to
  324. provide effective tracking. This concern manifests as a deliberate
  325. non-extensibility in many parts of the Gemini protocol.</p>
  326. </blockquote>
  327. <p>Turns out, neither the FAQ nor the protocol precisely pin-point how exactly
  328. Gemini takes <em>privacy seriously</em>. They call out typical buzzwords like
  329. <em>supercookies</em> and <em>fingerprinting</em> and suggest that due to the protocol’s
  330. <em>non-extensibility</em> Gemini is more privacy-focused than the <em>modern web</em>. Then,
  331. on the other hand, Gemini users
  332. <a href="https://curl.se/mail/lib-2020-11/0083.html">write things like this</a>:</p>
  333. <blockquote>
  334. <ul>
  335. <li>Certificate verification. Gemini servers rarely use certificates with
  336. trust chain from certificates in /etc/ssl/certs; self-signed
  337. certificates are the norm. Option -k should be the default for gemini
  338. protocol.</li>
  339. </ul>
  340. </blockquote>
  341. <p>Ah yes, that is how <em>taking privacy seriously</em> looks like. Besides, what about
  342. the visitor’s IP address? Gemini servers can certaily see that. Nowhere in its
  343. official documentation Gemini seems to care about telling users this detail, let
  344. alone whether or not they’re able to browse via Tor or if there’s any client
  345. that would support Tor right out-of-the-box.</p>
  346. <p>Also, what if I wrote my own Gemini server – judging by its protocol that’s
  347. something one could do within a few hours – that would attach
  348. per-initial-request generated hashes to all links?
  349. Thereby, when a user visits my Gemini site, they would get a unique
  350. hash assigned, which would then be sent to my server every time they follow a
  351. link to a different subsite. I could track the user’s browsing behaviour across
  352. my site, just like HTTP sites do these days. If I store these requests,
  353. plus the IP address the user is coming from, I would already gather some
  354. interesting data points.<br>
  355. What if I would perform a quick investigation of the TCP/IP packets
  356. additionally? E.g. the initial packet size, the window- and segment-size, the
  357. initial TTL, individual flags? I could make my Gemini server use such
  358. fingerprinting techniques to gather more info and store that as well. If I’d
  359. be really up to something, I could have all sorts of additional checks and
  360. scans running for every new connection. Even if the user would connect through
  361. a NATted IP, I could eventually gain enough intel to be able to tell
  362. with relatively high confidence if a request was made by a visitor I’ve seen
  363. before or not, especially with such a small user-base (as compared to HTTP).
  364. Let alone all the still to be discovered exploits within individual client
  365. implementations, that might as well lead to potential privacy or even security
  366. risks.</p>
  367. <p>Bottom line is, if you agree that the modern web has become an awful place,
  368. let’s work on changing that for everyone, instead of abandoning it like a
  369. bunch of billionaires trying to escape to a different place, before this
  370. one collapses.</p>
  371. <p>The reason this website looks the way it does, is not because it follows the
  372. latest online trends, but because it’s everything that is required to efficiently
  373. transport information from me to you, using tools that we’re both familiar with,
  374. while staying out of both our ways.<br>
  375. If you don’t like how modern websites track their users and flood them with
  376. ads, then don’t do that on your website, contribute to projects like
  377. uBlock Origin, Privacy Badger and Tor, and stop using websites that <strong>do</strong> track
  378. their users or spam them with ads.
  379. If you don’t like JavaScript, don’t use it or use it in a way in which
  380. your site will still function even without it, and stop using websites that won’t
  381. even load without JavaScript enabled.
  382. If you’re not a fan of CSS, don’t use it, nobody forces you to style your HTML
  383. and most browsers include a fairly accessible default stylesheet.
  384. Heck, if you’re as much of a purist as the Gemini folks claim to be and don’t
  385. want neither videos nor images on your website, simply don’t put any there.
  386. <a href="http://motherfuckingwebsite.com">motherfuckingwebsite.com</a> is a perfect example
  387. of a website that uses none of all that while still functioning flawlessly.</p>
  388. <p>Ultimately, serving content solely via Gemini will only lead to it becoming
  389. <strong>less</strong> accessible and available to other people. Moving to Gemini is the
  390. opposite of inclusive, it’s exclusive. It’s a step in the wrong direction.</p>
  391. </article>
  392. <hr>
  393. <footer>
  394. <p>
  395. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  396. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  397. </svg> Accueil</a> •
  398. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  399. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  400. </svg> Suivre</a> •
  401. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  402. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  403. </svg> Pro</a> •
  404. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  405. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  406. </svg> Email</a> •
  407. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  408. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  409. </svg> Légal</abbr>
  410. </p>
  411. <template id="theme-selector">
  412. <form>
  413. <fieldset>
  414. <legend><svg class="icon icon-brightness-contrast">
  415. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  416. </svg> Thème</legend>
  417. <label>
  418. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  419. </label>
  420. <label>
  421. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  422. </label>
  423. <label>
  424. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  425. </label>
  426. </fieldset>
  427. </form>
  428. </template>
  429. </footer>
  430. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  431. <script>
  432. function loadThemeForm(templateName) {
  433. const themeSelectorTemplate = document.querySelector(templateName)
  434. const form = themeSelectorTemplate.content.firstElementChild
  435. themeSelectorTemplate.replaceWith(form)
  436. form.addEventListener('change', (e) => {
  437. const chosenColorScheme = e.target.value
  438. localStorage.setItem('theme', chosenColorScheme)
  439. toggleTheme(chosenColorScheme)
  440. })
  441. const selectedTheme = localStorage.getItem('theme')
  442. if (selectedTheme && selectedTheme !== 'undefined') {
  443. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  444. }
  445. }
  446. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  447. window.addEventListener('load', () => {
  448. let hasDarkRules = false
  449. for (const styleSheet of Array.from(document.styleSheets)) {
  450. let mediaRules = []
  451. for (const cssRule of styleSheet.cssRules) {
  452. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  453. continue
  454. }
  455. // WARNING: Safari does not have/supports `conditionText`.
  456. if (cssRule.conditionText) {
  457. if (cssRule.conditionText !== prefersColorSchemeDark) {
  458. continue
  459. }
  460. } else {
  461. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  462. continue
  463. }
  464. }
  465. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  466. }
  467. // WARNING: do not try to insert a Rule to a styleSheet you are
  468. // currently iterating on, otherwise the browser will be stuck
  469. // in a infinite loop…
  470. for (const mediaRule of mediaRules) {
  471. styleSheet.insertRule(mediaRule.cssText)
  472. hasDarkRules = true
  473. }
  474. }
  475. if (hasDarkRules) {
  476. loadThemeForm('#theme-selector')
  477. }
  478. })
  479. </script>
  480. </body>
  481. </html>