A place to cache linked articles (think custom and personal wayback machine)
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

index.html 38KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  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>
  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,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>HTTP is obsolete. It's time for the distributed, permanent web (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="https://blog.neocities.org/its-time-for-the-permanent-web.html">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. HTTP is obsolete. It's time for the distributed, permanent web (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="https://blog.neocities.org/its-time-for-the-permanent-web.html">Source originale du contenu</a></h3>
  445. <p>
  446. <img src="https://blog.neocities.org/neocitiesandipfs.jpg"/>
  447. </p>
  448. <p>
  449. Early this year, the <a href="https://archive.org/">Internet Archive</a> put out <a href="http://blog.archive.org/2015/02/11/locking-the-web-open-a-call-for-a-distributed-web/">a call for a distributed web</a>. We heard them loud and clear.
  450. </p>
  451. <p>
  452. Today I'm making an announcement that begins our long journey to the future of the web. A web that is faster, more secure, more robust, and more permanent.
  453. </p>
  454. <p>
  455. <a href="https://neocities.org">Neocities</a> has collaborated with <a href="http://ipn.io/">Protocol Labs</a> to become the first major site to implement <a href="http://ipfs.io">IPFS</a> in production. Starting today, all Neocities web sites are available for viewing, archiving, and hosting by any IPFS node in the world. When another IPFS node chooses to host a site from Neocities, that version of the site will continue to be available, even if Neocities shuts down or stops hosting it. The more IPFS nodes seed Neocities sites, the more available (and redundant) Neocities sites become. And the less centrally dependent the sites are on us to continue existing.
  456. </p>
  457. <p>
  458. What is IPFS? From their README:
  459. </p>
  460. <blockquote>
  461. <strong><a href="http://ipfs.io">IPFS</a> is a distributed file system that seeks to connect all computing devices with the same system of files.</strong> In some ways, this is similar to the original aims of the Web, but IPFS is actually more similar to a single bittorrent swarm exchanging git objects.
  462. IPFS could become a new major subsystem of the internet. If built right, it could complement or replace HTTP. It could complement or replace even more. It sounds crazy. It is crazy.
  463. </blockquote>
  464. <p>
  465. IPFS is still in the alpha stages of development, so we're calling this an experiment for now. It hasn't replaced our existing site storage (yet). Like with any complex new technology, there's a lot of improvements to make. But IPFS isn't vaporware, it works right now. You can <a href="http://ipfs.io/docs/install/">try it out on your own computer</a>, and already can use it to <a href="https://neocities.org/permanent-web">help us serve and persist Neocities sites</a>.
  466. </p>
  467. <p>
  468. The message I want to send couldn't possibly be more audacious: I strongly believe <a href="http://ipfs.io">IPFS</a> <i>is</i> the replacement to HTTP (and many other things), and now's the time to start trying it out. Replacing HTTP sounds crazy. It is crazy! But <strong>HTTP is broken</strong>, and the craziest thing we could possibly do is continue to use it forever. We need to apply state-of-the-art computer science to the distribution problem, and design a better protocol for the web.
  469. </p>
  470. <h3>Part 1: What's wrong with HTTP?</h3>
  471. <p>
  472. The Hypertext Transfer Protocol (HTTP) has unified the entire world into a single global information protocol, standardizing how we distribute and present information to eachother.
  473. </p>
  474. <p>
  475. It is inconceivable for me to even think about what life would be like without it. HTTP dropped the cost of publishing content to almost nothing, an innovation that took a sledgehammer to the top-down economic, political, and cultural control over distribution of information (music, ideas, video, news, games, everything). As a result of liquifying information and making it the publication of it more egalitarian and accessible, HTTP has made almost everything about our culture better.
  476. </p>
  477. <p>
  478. I love HTTP, and I always will. It truly stands among the greatest and most important inventions of all time.
  479. </p>
  480. <p>
  481. But while HTTP has achieved many things, it's usefulness as a foundation for the distribution and persistence of the sum of human knowledge isn't just showing some cracks, it's crumbling to pieces right in front of us. The way HTTP distributes content is <strong>fundamentally flawed</strong>, and no amount of performance tuneups or forcing <a href="https://threatpost.com/apple-leaves-cnnic-root-in-ios-osx-certificate-trust-lists/112086">broken</a> CA SSL or whatever are going to fix that. <a href="https://http2.github.io/">HTTP/2</a> is a welcome improvement, but it's a conservative update to a technology that's beginning to show its age. To have a better future for the web, we need more than a spiced up version of HTTP, we need a new foundation. And per the governance model of cyberspace, that means we need a new protocol. <a href="http://ipfs.io">IPFS</a>, I'm strongly hoping, becomes that new protocol.
  482. </p>
  483. <h3>HTTP is brittle</h3>
  484. <p>
  485. <a href="http://en.wikipedia.org/wiki/CERN_httpd#/media/File:First_Web_Server.jpg"><img src="https://blog.neocities.org/images/first-web-server.jpg"/></a>
  486. </p>
  487. <p>
  488. This is a picture of the first HTTP web server in the world. It was Tim Berners-Lee's NeXT computer at CERN.
  489. </p>
  490. <p>
  491. Pasted on the machine is an ominous sticker: <strong>"This machine is a server, do not power it down!!"</strong>.
  492. </p>
  493. <p>
  494. The reason it couldn't be powered down is that web sites on other servers were starting to link to it. Once they linked to it, they then depended on that machine continuing to exist. If the machine was powered down, the links stopped working. If the machine failed or was no longer accessible at the same location, a far worse thing happened: the chain between sites becomes permanently broken, and the ability to access that content is lost forever. That sticker perfectly highlights the biggest problem with HTTP: it erodes.
  495. </p>
  496. <p>
  497. Tim's NeXT cube is now a museum piece. The first of millions of future dead web servers.
  498. </p>
  499. <p>
  500. You've seen the result:
  501. </p>
  502. <p>
  503. <img src="https://blog.neocities.org/images/permanentweb404.png"/>
  504. </p>
  505. <p>
  506. Even if you've never read the HTTP spec, you probably know what 404 means. It's the error code used by HTTP to indicate that the site is no longer on the server at that location. Usually you're not even that lucky. More often, there isn't even a server there anymore to tell you that the content you're looking for is gone, and it has no way to help you find it. And unless the <a href="https://archive.org">Internet Archive</a> backed it up, you'll never find it again. It becomes lost, forever.
  507. </p>
  508. <p>
  509. The older a web page is, the more likely it is you'll see 404 pages. They're the cold-hearted digital tombstones of a dying web, betraying nothing about what knowledge, beauty, or irreverent stupidity may have once resided there.
  510. </p>
  511. <p>
  512. <img src="https://blog.neocities.org/images/moshtoyanni.jpg"/>
  513. </p>
  514. <p>
  515. One of my favorite sites from the 90s web was <a href="http://www.angelfire.com/ct/moshtoyanni/">Mosh to Yanni</a>, and viewing the site today gives a very strong example of how inadequate HTTP is for maintaining links between sites. All the static content stored with the site still loads, and my modern browser still renders the page (HTML, unlike HTTP, has excellent lasting power). But any links offsite or to dynamically served content are dead. For every weird example like this, there are countless examples of incredibly useful content that have also long since vanished. Whether eroding content is <a href="http://www.cultdeadcow.com/oldskool/mrt/Tversus.html">questionable crap</a> or <a href="http://web.archive.org/web/20030203172328/eyetap.org/wearcam/icwc98/keynote.html">timelessly useful</a>, it's still our history, and we're losing it fast.
  516. </p>
  517. <p>
  518. The reason this happens is simple: <strong>centrally managed web servers inevitably shut down</strong>. The domain changes ownership, or the company that ran it goes out of business. Or the computer crashes, without having a backup to restore the content with. Having everyone run their own personal HTTP server doesn't solve this. If anything, it probably makes it worse.
  519. </p>
  520. <hr/>
  521. <h3>HTTP encourages hypercentralization</h3>
  522. <p>The result of this erosion of data has been further dependence on larger, more organized centralized services. Their short-term availability tends to be (mostly) good due to redundant backups. But this still doesn't address long-term availability, and creates a whole new set of problems.</p>
  523. <p>
  524. We've come a long way since John Perry Barlow's <a href="http://ipfs.io/ipfs/QmVDWmkM87NfR85WE1LvfwfJLRcMEtfNnCBiCJQRePP7Ly">A Declaration of the Independence of Cyberspace</a>. As our electronic country becomes more influential and facilitates the world with more information, governments and corporations alike have started to pry into HTTP's flaws, using them to spy on us, monetize us, and block our access to any content that represents a threat to them, legitimate or otherwise.
  525. </p>
  526. <p>
  527. <img src="https://blog.neocities.org/images/centralized-decentralized-distributed.jpg"/>
  528. </p>
  529. <p>
  530. The web we were intended to have was <strong>decentralized</strong>, but the web we have today is very quickly becoming <strong>centralized</strong>, as <a href="http://www.bbc.com/news/world-us-canada-34082393">billions of users become dependent on a small handful of services</a>.
  531. </p>
  532. <p>Regardless of whether you think this is a legitimate tradeoff, this was not how HTTP was intended to be used. Organizations like the NSA (and our future robot overlords) now only have to intercept our communications at a few sources to spy on us. It makes it easy for governments to censor content at their borders by blocking the ability for sites to access these highly centralized resources. It also puts our communications at risk of being interrupted by <a href="https://github.com/blog/1796-denial-of-service-attacks">DDoS attacks</a>.
  533. </p>
  534. <p>
  535. Distributing the web would make it less malleable by a small handful of powerful organizations, and that improves both our freedom and our independence. It also reduces the risk of the "one giant shutdown" that takes a massive amount of data with it.
  536. </p>
  537. <h3>HTTP is inefficient</h3>
  538. <p>As of this writing, Gangnam Style now has over 2,344,327,696 views. Go ahead, watch it again. I'll wait for you.</p>
  539. <p>
  540. <iframe src="https://www.youtube.com/embed/9bZkp7q19f0" frameborder="0" allowfullscreen="">VIDEO</iframe>
  541. </p>
  542. <p>
  543. Let's make some assumptions. The video clocks in at 117 Megabytes. That means (at most) 274,286,340,432 Megabytes, or 274.3 Petabytes of data for the video file alone has been sent since this was published. If we assume a total expense of 1 cent per gigabyte (this would include bandwidth and all of the server costs), $2,742,860 has been spent on distributing this one file so far.
  544. </p>
  545. <p>
  546. That's not too bad... if you're Google. But if you're a smaller site, the cost to serve this much data would be astronomical, especially when bandwidth rates for small players start around $0.12 per gigabyte and go as high a $0.20 in Asia. I've spent the better part of my work at Neocities battling expensive bandwidth to ensure we can keep running our infrastructure at low cost.
  547. </p>
  548. <p>
  549. HTTP lowered the price of publishing, but it still costs money, and these costs can really add up. Distributing this much data from central datacenters is potentially very expensive if not done at economies of scale.
  550. </p>
  551. <p>
  552. What if, instead of always serving this content from datacenters, we could turn every computer on an ISP's network into a streaming CDN? With a video as popular as Gangnam Style, it could even be completely downloaded from within an ISP's network, not requiring numerous hops over the internet backbone. This is one of the many things IPFS is capable of improving (we'll discuss this in a bit).
  553. </p>
  554. <h3>HTTP creates overdependence on the Internet backbone</h3>
  555. <p>
  556. When content is hypercentralized, it makes us highly dependent on the internet backbones to the datacenters functioning. Aside from making it easy for governments to block and censor content, there are also reliability problems. Even with redundancies, major backbones sometimes get <a href="http://en.wikipedia.org/wiki/2008_submarine_cable_disruption">damaged</a>, or <a href="https://blog.cloudflare.com/why-google-went-offline-today-and-a-bit-about/">routing tables go haywire</a>, and <a href="https://www.youtube.com/watch?v=VlKisWR74mU">the consequences can be drastic</a>.
  557. </p>
  558. <p>I got a weird taste of that a few months ago, when Neocities slowed down after a car crashed into a fiber uplink we use in Canada (no suspects yet, but a few <a href="https://blog.neocities.org/images/rickycar.jpg">promising leads</a>). I've also heard stories where hunters have shot at the fiber cables connecting the eastern Oregon datacenters (the enormous ones that store a <em>lot</em> of data), requiring engineers to show up on snowmobiles with cross country skis to repair the fiber lines. Since I wrote this post, details have emerged on a <a href="http://www.thedailybeast.com/articles/2015/07/04/who-s-cutting-california-internet-cables-the-fbi-has-no-idea.html">sophisticated attack on fiber lines</a> happening in the Bay Area. The point is, the internet backbone isn't perfect, it's easy to attack it, and it's easy for service to get affected by a few important fiber lines getting cut.
  559. </p>
  560. <h3>Part 2: How IPFS solves these problems</h3>
  561. <p>
  562. We've discussed HTTP's problems (and the problems of hypercentralization). Now let's talk about how IPFS, and how it can help improve the web.
  563. </p>
  564. <p>
  565. IPFS fundamentally changes the way we look for things, and this is it's key feature. With HTTP, you search for locations. With IPFS, you search for <em>content</em>.
  566. </p>
  567. <p>
  568. Let me show you an example. This is a file on a server I run: <a href="https://neocities.org/img/neocitieslogo.svg">https://neocities.org/img/neocitieslogo.svg</a>. Your browser first finds the location (IP address) of the server, then asks my server for the file using the path name. With that design, only the owner (me) can determine that this is the file you're looking for, and you are forced to trust that I don't change it on you by moving the file, or shutting the server down.
  569. </p>
  570. <p>
  571. Instead of looking for a centrally-controlled location and asking it what it thinks /img/neocitieslogo.svg is, what if we instead asked a distributed network of millions of computers not for the name of a file, but for <em>the content that is supposed to be in the file?</em>
  572. </p>
  573. <p>
  574. This is precisely what IPFS does.
  575. </p>
  576. <p>
  577. When neocitieslogo.svg is added to my IPFS node, it gets a new name: <a href="http://ipfs.io/ipfs/QmXGTaGWTT1uUtfSb2sBAvArMEVLK4rQEcQg5bv7wwdzwU">QmXGTaGWTT1uUtfSb2sBAvArMEVLK4rQEcQg5bv7wwdzwU</a>. That name is actually a <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">cryptographic hash</a>, which has been computed from the contents of that file. That hash is guaranteed by cryptography to <i>always</i> only represent the contents of that file. If I change that file by even one bit, the hash will become something completely different.
  578. </p>
  579. <p>
  580. When I ask the IPFS distributed network for that hash, it efficiently (20 hops for a network of 10,000,000) finds the nodes that have the data using a <a href="https://en.wikipedia.org/wiki/Distributed_hash_table">Distributed Hash Table</a>, retrieves it, and verifies using the hash that it's the correct data. Early DHT designs had issues with <a href="https://en.wikipedia.org/wiki/Sybil_attack">Sybil attacks</a>, but we have <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.68.4986">new ways</a> to address them, and I'm very confident this is a solvable problem (unlike the problems with HTTP, which are just going to be broken forever).
  581. </p>
  582. <p>
  583. IPFS is general purpose, and has little in the way of storage limitations. It can serve files that are large or small. It automatically breaks up larger files into smaller chunks, allowing IPFS nodes to download (or stream) files from not just one server like with HTTP, but hundreds of them simultaneously. The IPFS network becomes a finely-grained, trustless, distributed, easily federated Content Delivery Network (CDN). This is useful for pretty much everything involving data: images, video streaming, distributed databases, entire operating systems, blockchains, backups of 8 inch floppy disks, and most important for us, <strong>static web sites</strong>.
  584. </p>
  585. <p>
  586. IPFS files can also be special IPFS directory objects, which allow you to use human readable filenames (which transparently link to other IPFS hashes). You can load the directory's index.html by default, the same way a standard HTTP server does. Using directory objects, IPFS allows you to make static web sites exactly the same way you make them today. It's a single command to add your web site to an IPFS node: <code>ipfs add -r yoursitedirectory</code>. After that, it's available from any IPFS node without requiring you to link to any hashes in the HTML (<a href="http://ipfs.io/ipfs/QmcKi2ae3uGb1kBg1yBpsuwoVqfmcByNdMiZ2pukxyLWD8/">example</a>, and <a href="http://ipfs.io/ipfs/QmZwebpGTFPRTaab9t5Y5JuwrbuzCzqWLwdeUGDR8N3hn8">example with index.html renamed</a>).
  587. </p>
  588. <h4>Federating data with IPFS</h4>
  589. <p>
  590. IPFS doesn't require every node to store all of the content that has ever been published to IPFS. Instead, you choose what data you want to help persist. Think of it like bookmarks, except instead of bookmarking a link to a site that will eventually fail, you back up the entire site for yourself, and volunteer to help to serve the content to others that want to look at it.
  591. </p>
  592. <p>If a lot of nodes host a little bit, these little bits quickly add up to more space, bandwidth and availablity than any centralized HTTP service could ever possibly provide. The distributed web will quickly become the fastest, most available, and largest store of data on the planet earth. And nobody will have the power to "burn books" by turning it all off. This Library of Alexandria is <em>never</em> going to burn down.
  593. </p>
  594. <p>Copying, storing and helping serve web sites from other IPFS nodes is easy. It just takes a single command and the hash of the site: <code>ipfs pin add -r QmcKi2ae3uGb1kBg1yBpsuwoVqfmcByNdMiZ2pukxyLWD8</code>. IPFS takes care of the rest.</p>
  595. <h4>IPNS</h4>
  596. <p>
  597. IPFS hashes represent <a href="https://en.wikipedia.org/wiki/Persistent_data_structure">immutable data</a>, which means they cannot be changed without the hash being different. <strong>This is a good thing</strong> because it encourages data persistence, but we still need a way to find the latest IPFS hash representing your site. IPFS accomplishes this using a special feature called <strong>IPNS</strong>.
  598. </p>
  599. <p>
  600. IPNS allows you to use a private key to sign a reference to the IPFS hash representing the latest version of your site using a public key hash (pubkeyhash for short). If you've used Bitcoin before, you're familiar with this - a Bitcoin address is also a pubkeyhash. With our Neocities IPFS node, I signed the image of Penelope (our site mascot) and you can load it using our IPNS pubkeyhash for that node: <a href="http://ipfs.io/ipns/QmTodvhq9CUS9hH8rirt4YmihxJKZ5tYez8PtDmpWrVMKP">QmTodvhq9CUS9hH8rirt4YmihxJKZ5tYez8PtDmpWrVMKP</a>.
  601. </p>
  602. <p>
  603. IPNS isn't done yet, so if that link doesn't work, don't fret. Just know that I will be able to change what that pubkeyhash points to, but the pubkeyhash will always remain the same. When it's done, it will solve the site updating problem.
  604. </p>
  605. <p>
  606. Now we just need to make the location of these sites human-readable, and we've got all the pieces we need.
  607. </p>
  608. <h4>Human-readable mutable addressing</h4>
  609. <p>
  610. IPFS/IPNS hashes are big, ugly strings that aren't easy to memorize. So IPFS allows you to use the existing Domain Name System (DNS) to provide human-readable links to IPFS/IPNS content. It does this by allowing you to insert the hash into a TXT record on your nameserver (if you have a command line handy, run this: <code>dig TXT ipfs.git.sexy</code>). You can see this in action by visiting <a href="http://ipfs.io/ipns/ipfs.git.sexy/">http://ipfs.io/ipns/ipfs.git.sexy/</a>.
  611. </p>
  612. <p>
  613. Going forward, IPFS has plans to also support <a href="http://namecoin.info/">Namecoin</a>, which could theoretically be used to create a completely decentralized, distributed web that has no requirements for a central authority in the entire chain. No ICANN, no central servers, no politics, no expensive certificate "authorities", and no choke points. It sounds crazy. It is crazy. And yet, it's completely possible with today's technology!
  614. </p>
  615. <h4>IPFS HTTP gateway: The bridge between the old web and the new</h4>
  616. <p>
  617. The IPFS implementation ships with an HTTP gateway I've been using to show examples, allowing current web browsers to access IPFS until the browsers implement IPFS directly (too early? I don't care). With the IPFS HTTP gateway (and a little nginx shoe polish), we don't have to wait. We can soon start switching over to IPFS for storing, distributing, and serving web sites.
  618. </p>
  619. <h3>How we're using IPFS now</h3>
  620. <p>
  621. Our initial implementation of IPFS is experimental and modest, for now. Neocities will be publishing an IPFS hash once per day when sites are updated, accessible from every site profile. This hash will point to the latest version of the site, and be accessible via our IPFS HTTP gateway. Because the IPFS hash changes for each update, this also enables us to provide an archive history for all the sites, something we automagically just get from the way that IPFS works anyways.
  622. </p>
  623. <h3>How we'll use IPNS in the future</h3>
  624. <p>
  625. Long-term, if things go well, we want to use IPFS for storing all of our sites, and issue IPNS keys for each site. This would enable users to publish content to their site independently of us. If we do it right, <strong>even if Neocities doesn't exist anymore, our users can still update their sites</strong>. We effectively take our user's central dependence on our servers and smash it to pieces, permanently ruining our plans for centralized world domination forever. It sounds awesome. It is awesome!
  626. </p>
  627. <p>It's still early, and there's much work to do before <a href="http://ipfs.io/">IPFS</a> can replace HTTP without needing to describe the idea as <a href="http://www.youtube.com/watch?v=tjgtLSHhTPg">crazy</a>. But there's no time like the present to plan for the future. It's time for us to get to work. Accept the <a href="https://archive.org/">Internet Archive</a>'s challenge: <strong>distribute the web</strong>.</p>
  628. </article>
  629. </section>
  630. <nav id="jumpto">
  631. <p>
  632. <a href="/david/blog/">Accueil du blog</a> |
  633. <a href="https://blog.neocities.org/its-time-for-the-permanent-web.html">Source originale</a> |
  634. <a href="/david/stream/2019/">Accueil du flux</a>
  635. </p>
  636. </nav>
  637. <footer>
  638. <div>
  639. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  640. <p>
  641. Bonjour/Hi!
  642. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  643. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  644. </p>
  645. <p>
  646. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  647. </p>
  648. <p>
  649. Voici quelques articles choisis :
  650. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  651. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  652. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  653. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  654. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  655. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  656. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  657. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  658. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  659. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  660. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  661. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  662. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  663. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  664. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  665. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  666. </p>
  667. <p>
  668. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  669. </p>
  670. <p>
  671. Je ne traque pas ta navigation mais mon
  672. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  673. conserve des logs d’accès.
  674. </p>
  675. </div>
  676. </footer>
  677. <script type="text/javascript">
  678. ;(_ => {
  679. const jumper = document.getElementById('jumper')
  680. jumper.addEventListener('click', e => {
  681. e.preventDefault()
  682. const anchor = e.target.getAttribute('href')
  683. const targetEl = document.getElementById(anchor.substring(1))
  684. targetEl.scrollIntoView({behavior: 'smooth'})
  685. })
  686. })()
  687. </script>