From caf76f51b97c3f1bf4d898b693887dd387ab12fe Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 09:24:36 +0100 Subject: [PATCH 01/13] docs: move gateways and ipns specs --- .../DNSLINK_GATEWAY.md => src/http-gateways/dnslink-gateway.md | 0 .../http-gateways/gateway-redirects-file.md | 0 .../PATH_GATEWAY.md => src/http-gateways/path-gateway.md | 0 .../http-gateways/subdomain-gateway.md | 0 .../http-gateways/trustless-gateway.md | 0 ipns/IPNS_PUBSUB.md => src/ipns/ipns-pubsub-router.md | 0 ipns/IPNS.md => src/ipns/ipns-record.md | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename http-gateways/DNSLINK_GATEWAY.md => src/http-gateways/dnslink-gateway.md (100%) rename http-gateways/REDIRECTS_FILE.md => src/http-gateways/gateway-redirects-file.md (100%) rename http-gateways/PATH_GATEWAY.md => src/http-gateways/path-gateway.md (100%) rename http-gateways/SUBDOMAIN_GATEWAY.md => src/http-gateways/subdomain-gateway.md (100%) rename http-gateways/TRUSTLESS_GATEWAY.md => src/http-gateways/trustless-gateway.md (100%) rename ipns/IPNS_PUBSUB.md => src/ipns/ipns-pubsub-router.md (100%) rename ipns/IPNS.md => src/ipns/ipns-record.md (100%) diff --git a/http-gateways/DNSLINK_GATEWAY.md b/src/http-gateways/dnslink-gateway.md similarity index 100% rename from http-gateways/DNSLINK_GATEWAY.md rename to src/http-gateways/dnslink-gateway.md diff --git a/http-gateways/REDIRECTS_FILE.md b/src/http-gateways/gateway-redirects-file.md similarity index 100% rename from http-gateways/REDIRECTS_FILE.md rename to src/http-gateways/gateway-redirects-file.md diff --git a/http-gateways/PATH_GATEWAY.md b/src/http-gateways/path-gateway.md similarity index 100% rename from http-gateways/PATH_GATEWAY.md rename to src/http-gateways/path-gateway.md diff --git a/http-gateways/SUBDOMAIN_GATEWAY.md b/src/http-gateways/subdomain-gateway.md similarity index 100% rename from http-gateways/SUBDOMAIN_GATEWAY.md rename to src/http-gateways/subdomain-gateway.md diff --git a/http-gateways/TRUSTLESS_GATEWAY.md b/src/http-gateways/trustless-gateway.md similarity index 100% rename from http-gateways/TRUSTLESS_GATEWAY.md rename to src/http-gateways/trustless-gateway.md diff --git a/ipns/IPNS_PUBSUB.md b/src/ipns/ipns-pubsub-router.md similarity index 100% rename from ipns/IPNS_PUBSUB.md rename to src/ipns/ipns-pubsub-router.md diff --git a/ipns/IPNS.md b/src/ipns/ipns-record.md similarity index 100% rename from ipns/IPNS.md rename to src/ipns/ipns-record.md From 833a81796a364232e67d0588da7cb5f834aa83b7 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 09:26:15 +0100 Subject: [PATCH 02/13] docs: add moving placeholders --- http-gateways/DNSLINK_GATEWAY.md | 3 +++ http-gateways/PATH_GATEWAY.md | 3 +++ http-gateways/README.md | 42 +----------------------------- http-gateways/REDIRECTS_FILE.md | 3 +++ http-gateways/SUBDOMAIN_GATEWAY.md | 3 +++ http-gateways/TRUSTLESS_GATEWAY.md | 3 +++ ipns/IPNS.md | 3 +++ ipns/IPNS_PUBSUB.md | 3 +++ ipns/README.md | 15 +---------- 9 files changed, 23 insertions(+), 55 deletions(-) create mode 100644 http-gateways/DNSLINK_GATEWAY.md create mode 100644 http-gateways/PATH_GATEWAY.md create mode 100644 http-gateways/REDIRECTS_FILE.md create mode 100644 http-gateways/SUBDOMAIN_GATEWAY.md create mode 100644 http-gateways/TRUSTLESS_GATEWAY.md create mode 100644 ipns/IPNS.md create mode 100644 ipns/IPNS_PUBSUB.md diff --git a/http-gateways/DNSLINK_GATEWAY.md b/http-gateways/DNSLINK_GATEWAY.md new file mode 100644 index 000000000..ec3d68bf3 --- /dev/null +++ b/http-gateways/DNSLINK_GATEWAY.md @@ -0,0 +1,3 @@ +# DNSLink Gateway Specification + +Moved to https://specs.ipfs.tech/http-gateways/dnslink-gateway/ diff --git a/http-gateways/PATH_GATEWAY.md b/http-gateways/PATH_GATEWAY.md new file mode 100644 index 000000000..72a64ffc2 --- /dev/null +++ b/http-gateways/PATH_GATEWAY.md @@ -0,0 +1,3 @@ +# Path Gateway Specification + +Moved to https://specs.ipfs.tech/http-gateways/path-gateway/ diff --git a/http-gateways/README.md b/http-gateways/README.md index ac349f5c5..5216121a3 100644 --- a/http-gateways/README.md +++ b/http-gateways/README.md @@ -1,43 +1,3 @@ # Specification for HTTP Gateways -## About - -**IPFS Gateway** acts as a **bridge between traditional HTTP clients and -IPFS.** Through the gateway, users can download files, directories and other -IPLD data stored in IPFS as if they were stored in a traditional web server. - -**This directory** contains **the specification for HTTP Gateway:** -a description of HTTP interface and conventions between an opinionated subset -of IPFS and the existing HTTP ecosystem of clients, tools, and libraries. - -## **Intended audience** - -The main goal of this spec is to provide reference documentation that is -independent of specific language or existing implementation, allowing everyone -to create a compatible Gateway, tailored to their needs and use cases. - - - -# Specification index - -## HTTP - -These are "low level" gateways that expose IPFS resources over HTTP protocol. - -* [PATH_GATEWAY.md](./PATH_GATEWAY.md) ← **START HERE** -* [TRUSTLESS_GATEWAY.md](./TRUSTLESS_GATEWAY.md) - -## Web - -Special types of gateway which leverage `Host` header in addition to URL `pathname`. - -Designed for website hosting and improved interoperability with web browsers -and [origin-based security -model](https://en.wikipedia.org/wiki/Same-origin_policy). - -* [SUBDOMAIN_GATEWAY.md](./SUBDOMAIN_GATEWAY.md) -* [DNSLINK_GATEWAY.md](./DNSLINK_GATEWAY.md) -* [REDIRECTS_FILE.md](./REDIRECTS_FILE.md) +Moved to https://specs.ipfs.tech/http-gateways/ diff --git a/http-gateways/REDIRECTS_FILE.md b/http-gateways/REDIRECTS_FILE.md new file mode 100644 index 000000000..6ac0cd949 --- /dev/null +++ b/http-gateways/REDIRECTS_FILE.md @@ -0,0 +1,3 @@ +# _redirects File Specification + +Moved to https://specs.ipfs.tech/http-gateways/gateway-redirects-file/ diff --git a/http-gateways/SUBDOMAIN_GATEWAY.md b/http-gateways/SUBDOMAIN_GATEWAY.md new file mode 100644 index 000000000..2bbb4cbbf --- /dev/null +++ b/http-gateways/SUBDOMAIN_GATEWAY.md @@ -0,0 +1,3 @@ +# Subdomain Gateway Specification + +Moved to https://specs.ipfs.tech/http-gateways/subdomain-gateway/ diff --git a/http-gateways/TRUSTLESS_GATEWAY.md b/http-gateways/TRUSTLESS_GATEWAY.md new file mode 100644 index 000000000..147d2a07c --- /dev/null +++ b/http-gateways/TRUSTLESS_GATEWAY.md @@ -0,0 +1,3 @@ +# Trustless Gateway Specification + +Moved to https://specs.ipfs.tech/http-gateways/trustless-gateway/ diff --git a/ipns/IPNS.md b/ipns/IPNS.md new file mode 100644 index 000000000..52406f384 --- /dev/null +++ b/ipns/IPNS.md @@ -0,0 +1,3 @@ +# Inter-Planetary Naming System + +Moved to https://specs.ipfs.tech/ipns/ipns-record/ diff --git a/ipns/IPNS_PUBSUB.md b/ipns/IPNS_PUBSUB.md new file mode 100644 index 000000000..c0fd19578 --- /dev/null +++ b/ipns/IPNS_PUBSUB.md @@ -0,0 +1,3 @@ +# IPNS PubSub Router + +Moved to https://specs.ipfs.tech/ipns/ipns-pubsub-router/ diff --git a/ipns/README.md b/ipns/README.md index 8fc928e9f..ee2c317d8 100644 --- a/ipns/README.md +++ b/ipns/README.md @@ -1,16 +1,3 @@ # IPNS Specifications -## About - -**This directory** contains specifications related to IPNS. - -## **Intended audience** - -The goal of this spec is to provide the reference documentation that is -independent of specific language or existing implementation, allowing everyone -to create a compatible IPNS Record Publisher or Resolver. - -# Specification index - -* [IPNS.md](./IPNS.md) ← **START HERE** - * [IPNS_PUBSUB.md](./IPNS.md) - IPNS over PubSub +Moved to https://specs.ipfs.tech/ipns/ From 36076f556c7f0ff73ab54006995221f02666dff7 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 09:29:50 +0100 Subject: [PATCH 03/13] docs: clean specs, references, and add meta specs --- src/http-gateways/dnslink-gateway.md | 49 ++-- src/http-gateways/gateway-redirects-file.md | 43 +-- src/http-gateways/path-gateway.md | 129 +++------ src/http-gateways/subdomain-gateway.md | 88 +++---- src/http-gateways/trustless-gateway.md | 40 +-- src/ipns/ipns-pubsub-router.md | 198 +++++++------- src/ipns/ipns-record.md | 67 ++--- src/meta/code-of-conduct.md | 129 +++++++++ src/meta/spec-for-specs.md | 278 ++++++++++++++++++++ 9 files changed, 645 insertions(+), 376 deletions(-) create mode 100644 src/meta/code-of-conduct.md create mode 100644 src/meta/spec-for-specs.md diff --git a/src/http-gateways/dnslink-gateway.md b/src/http-gateways/dnslink-gateway.md index a618172fc..a693ff169 100644 --- a/src/http-gateways/dnslink-gateway.md +++ b/src/http-gateways/dnslink-gateway.md @@ -1,20 +1,19 @@ -# DNSLink Gateway Specification - -![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) - -**Authors**: - -- Marcin Rataj ([@lidel](https://github.com/lidel)) +--- +maturity: reliable +date: 2022-11-09 +editors: + - name: Marcin Rataj + github: lidel + - name: Thibault Meunier + github: thibmeu +--- ----- - -**Abstract** +# DNSLink Gateway Specification -DNSLink Gateway is an extension of -[PATH_GATEWAY.md](./PATH_GATEWAY.md) -that enables hosting a specific content path under a specific DNS name. +DNSLink Gateway is an extension of :cite[path-gateway] that enables hosting a +specific content path under a specific DNS name. -This document describes the delta between [PATH_GATEWAY.md](./PATH_GATEWAY.md) and this gateway type. +This document describes the delta between :cite[path-gateway] and this gateway type. In short: @@ -23,21 +22,6 @@ In short: - gateway resolves DNSLink to an immutable content root identified by a CID - HTTP response includes the data for the CID -# Table of Contents - -- [DNSLink Gateway Specification](#dnslink-gateway-specification) -- [Table of Contents](#table-of-contents) -- [HTTP API](#http-api) - - [`GET /[{path}][?{params}]`](#get-pathparams) - - [`HEAD /[{path}][?{params}]`](#head-pathparams) -- [HTTP Request](#http-request) - - [Request headers](#request-headers) - - [`Host` (request header)](#host-request-header) -- [HTTP Response](#http-response) -- [Appendix: notes for implementers](#appendix-notes-for-implementers) - - [Leveraging DNS for content routing](#leveraging-dns-for-content-routing) - - [Redirects, single-page applications, and custom 404s](#redirects-single-page-applications-and-custom-404s) - # HTTP API ## `GET /[{path}][?{params}]` @@ -53,7 +37,7 @@ Same as GET, but does not return any payload. # HTTP Request -Below MUST be implemented **in addition** to the [HTTP Request section from `PATH_GATEWAY.md`](./PATH_GATEWAY.md#http-request). +Below MUST be implemented **in addition** to "HTTP Request" of :cite[path-gateway]. ## Request headers @@ -89,7 +73,7 @@ content path: # HTTP Response -Same as [HTTP Response section in `PATH_GATEWAY.md`](./PATH_GATEWAY.md#http-response). +Same as "HTTP Response" of :cite[path-gateway]. # Appendix: notes for implementers @@ -103,4 +87,5 @@ Same as [HTTP Response section in `PATH_GATEWAY.md`](./PATH_GATEWAY.md#http-resp ## Redirects, single-page applications, and custom 404s -DNSLink Gateway implementations are free to include `_redirects` file support defined in [`REDIRECTS_FILE.md`](./REDIRECTS_FILE.md). +DNSLink Gateway implementations are free to include `_redirects` file support +defined in :cite[gateway-redirects-file]. diff --git a/src/http-gateways/gateway-redirects-file.md b/src/http-gateways/gateway-redirects-file.md index 13152d369..b862e6c83 100644 --- a/src/http-gateways/gateway-redirects-file.md +++ b/src/http-gateways/gateway-redirects-file.md @@ -1,14 +1,14 @@ -# `_redirects` File Specification - -![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) - -**Authors**: - -- Justin Johnson ([@justincjohnson](https://github.com/justincjohnson)) - ----- - -**Abstract** +--- +maturity: reliable +date: 2023-01-28 +editors: + - name: Justin Johnson + github: justincjohnson + - name: Marcin Rataj + github: lidel +--- + +# _redirects File Specification The Redirects File specification is an extension of the Subdomain Gateway and DNSLink Gateway specifications. @@ -16,27 +16,6 @@ Developers can enable URL redirects or rewrites by adding redirect rules to a fi This can be used, for example, to enable URL rewriting for hosting a single-page application, to redirect invalid URLs to a pretty 404 page, or to avoid [link rot](https://en.wikipedia.org/wiki/Link_rot) when moving to IPFS-based website hosting. -# Table of Contents - -- [File Name and Location](#file-name-and-location) -- [File Format](#file-format) - - [From](#from) - - [To](#to) - - [Status](#status) - - [Placeholders](#placeholders) - - [Splat](#splat) - - [Comments](#comments) - - [Line Termination](#line-termination) - - [Max File Size](#max-file-size) -- [Evaluation](#evaluation) - - [Subdomain or DNSLink Gateways](#subdomain-or-dnslink-gateways) - - [Order](#order) - - [No Forced Redirects](#no-forced-redirects) -- [Error Handling](#error-handling) -- [Security](#security) -- [Appendix: notes for implementers](#appendix-notes-for-implementors) - - [Test fixtures](#test-fixtures) - # File Name and Location The Redirects File MUST be named `_redirects` and stored underneath the root CID of the web site. diff --git a/src/http-gateways/path-gateway.md b/src/http-gateways/path-gateway.md index a6b16977c..6fbbea06b 100644 --- a/src/http-gateways/path-gateway.md +++ b/src/http-gateways/path-gateway.md @@ -1,14 +1,23 @@ -# Path Gateway Specification - -![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) - -**Authors**: - -- Marcin Rataj ([@lidel](https://github.com/lidel)) +--- +maturity: reliable +date: 2023-02-27 +editors: + - name: Marcin Rataj + github: lidel + - name: Adrian Lanzafame + github: lanzafame + - name: Vasco Santos + github: vasco-santos + - name: Oli Evans + github: olizilla + - name: Henrique Dias + github: hacdias + url: https://hacdias.com/ +xref: + - url +--- ----- - -**Abstract** +# Path Gateway Specification The most versatile form of IPFS Gateway is a Path Gateway. @@ -17,74 +26,9 @@ provides basic primitives for integrating IPFS resources within existing HTTP stack. **Note:** additional Web Gateways aimed for website hosting and web browsers -extend the below spec and are defined in -[SUBDOMAIN_GATEWAY.md](./SUBDOMAIN_GATEWAY.md) and -[DNSLINK_GATEWAY.md](./DNSLINK_GATEWAY.md). There is also a minimal -[TRUSTLESS_GATEWAY.md](./TRUSTLESS_GATEWAY.md) specification for use cases -where client prefers to perform all validation locally. - -# Table of Contents - -- [Path Gateway Specification](#path-gateway-specification) -- [Table of Contents](#table-of-contents) -- [HTTP API](#http-api) - - [`GET /ipfs/{cid}[/{path}][?{params}]`](#get-ipfscidpathparams) - - [`HEAD /ipfs/{cid}[/{path}][?{params}]`](#head-ipfscidpathparams) - - [only-if-cached HEAD behavior](#only-if-cached-head-behavior) - - [`GET /ipns/{name}[/{path}][?{params}]`](#get-ipnsnamepathparams) - - [`HEAD /ipns/{name}[/{path}][?{params}]`](#head-ipnsnamepathparams) -- [HTTP Request](#http-request) - - [Request Headers](#request-headers) - - [`If-None-Match` (request header)](#if-none-match-request-header) - - [`Cache-Control` (request header)](#cache-control-request-header) - - [`only-if-cached`](#only-if-cached) - - [`Accept` (request header)](#accept-request-header) - - [`Range` (request header)](#range-request-header) - - [`Service-Worker` (request header)](#service-worker-request-header) - - [Request Query Parameters](#request-query-parameters) - - [`filename` (request query parameter)](#filename-request-query-parameter) - - [`download` (request query parameter)](#download-request-query-parameter) - - [`format` (request query parameter)](#format-request-query-parameter) -- [HTTP Response](#http-response) - - [Response Status Codes](#response-status-codes) - - [`200` OK](#200-ok) - - [`206` Partial Content](#206-partial-content) - - [`301` Moved Permanently](#301-moved-permanently) - - [`400` Bad Request](#400-bad-request) - - [`404` Not Found](#404-not-found) - - [`410` Gone](#410-gone) - - [`412` Precondition Failed](#412-precondition-failed) - - [Use with only-if-cached](#use-with-only-if-cached) - - [`429` Too Many Requests](#429-too-many-requests) - - [`451` Unavailable For Legal Reasons](#451-unavailable-for-legal-reasons) - - [`500` Internal Server Error](#500-internal-server-error) - - [`504` Gateway Timeout](#504-gateway-timeout) - - [Response Headers](#response-headers) - - [`Etag` (response header)](#etag-response-header) - - [`Cache-Control` (response header)](#cache-control-response-header) - - [`Last-Modified` (response header)](#last-modified-response-header) - - [`Content-Type` (response header)](#content-type-response-header) - - [`Content-Disposition` (response header)](#content-disposition-response-header) - - [`Content-Length` (response header)](#content-length-response-header) - - [`Content-Range` (response header)](#content-range-response-header) - - [`Accept-Ranges` (response header)](#accept-ranges-response-header) - - [`Location` (response header)](#location-response-header) - - [Use in directory URL normalization](#use-in-directory-url-normalization) - - [`X-Ipfs-Path` (response header)](#x-ipfs-path-response-header) - - [`X-Ipfs-Roots` (response header)](#x-ipfs-roots-response-header) - - [`X-Content-Type-Options` (response header)](#x-content-type-options-response-header) - - [`X-Trace-Id` (response header)](#x-trace-id-response-header) - - [Response Payload](#response-payload) -- [Appendix: notes for implementers](#appendix-notes-for-implementers) - - [Content resolution](#content-resolution) - - [Finding the content root](#finding-the-content-root) - - [Traversing remaining path](#traversing-remaining-path) - - [Traversing through UnixFS](#traversing-through-unixfs) - - [Traversing through DAG-JSON and DAG-CBOR](#traversing-through-dag-json-and-dag-cbor) - - [Handling traversal errors](#handling-traversal-errors) - - [Best practices for HTTP caching](#best-practices-for-http-caching) - - [Denylists](#denylists) - - [Generated HTML with directory index](#generated-html-with-directory-index) +extend the below spec and are defined in :cite[subdomain-gateway] and +:cite[dnslink-gateway]. There is also a minimal :cite[trustless-gateway] +specification for use cases where client prefers to perform all validation locally. # HTTP API @@ -230,7 +174,11 @@ Optional, can be used for overriding the filename. When set, gateway will include it in `Content-Disposition` header and may use it for `Content-Type` calculation. -Example: `https://ipfs.io/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG?filename=hello_world.txt` +Example: + +``` +https://ipfs.io/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG?filename=hello_world.txt +``` ### `download` (request query parameter) @@ -331,8 +279,7 @@ making a new request. Error to indicate that request was formally correct, but this specific Gateway is unable to return requested data due to legal reasons. Response SHOULD -include an explanation, as noted in -[RFC7725.html#n-451-unavailable-for-legal-reasons](https://httpwg.org/specs/rfc7725.html#n-451-unavailable-for-legal-reasons). +include an explanation, as noted in Section 3 of :cite[rfc7725]. See: [Denylists](#denylists) @@ -351,7 +298,7 @@ Returned when Gateway was not able to produce response under set limits. Used for HTTP caching. An opaque identifier for a specific version of the returned payload. The unique -value must be wrapped by double quotes as noted in [RFC7232#Etag](https://httpwg.org/specs/rfc7232.html#header.etag). +value must be wrapped by double quotes as noted in Section 8.8.3 of :cite[rfc9110]. In many cases it is not enough to base `Etag` value on requested CID. @@ -399,7 +346,7 @@ Returned directive depends on requested content path and format: indicate remaining TTL of the mutable pointer such as IPNS record or DNSLink TXT record. - Implementations are free to place an upper bound on any TTL received, as - noted in [RFC 2131 Section 8](https://datatracker.ietf.org/doc/html/rfc2181#section-8). + noted in Section 8 of :cite[rfc2131]. - If TTL value is unknown, implementations are free to set it to a static value, but it should not be lower than 60 seconds. @@ -419,7 +366,7 @@ Returning this header depends on the information available: - Legacy implementations set this header to the current timestamp when reading TTL on `/ipns/` content paths was not available. This hint was used by web browsers in a process called "Calculating Heuristic Freshness" - ([RFC7234](https://tools.ietf.org/html/rfc7234#section-4.2.2)). Each browser + (Section 4.2.2 of :cite[rfc9111]). Each browser uses different heuristic, making this an inferior, non-deterministic caching strategy. @@ -436,8 +383,7 @@ Example: `Content-Type: application/vnd.ipld.car; version=1` When no explicit response format is provided with the request, and the requested data itself has no built-in content type metadata, implementations are free to perform content type sniffing based on file name -(from [URL path](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3), -or optional [`filename`](#filename-request-query-parameter) parameter) +(from :ref[url] path, or optional [`filename`](#filename-request-query-parameter) parameter) and magic bytes to improve the utility of produced responses. For example: @@ -473,8 +419,8 @@ To illustrate, `?filename=testтест.pdf` should produce: `Content-Disposition inline; filename="test____.jpg"; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82.jpg` - ASCII representation must have non-ASCII characters replaced with `_` -- UTF-8 representation must be wrapped in Percent Encoding ([RFC 3986, Section 2.1](https://www.rfc-editor.org/rfc/rfc3986.html#section-2.1)). - - NOTE: `UTF-8''` is not a typo – see [Examples in RFC5987](https://datatracker.ietf.org/doc/html/rfc5987#section-3.2.2) +- UTF-8 representation must be wrapped in Percent Encoding (Section 2.1 of :cite[rfc3986]). + - NOTE: `UTF-8''` is not a typo – see Section 3.2.3 of :cite[rfc8187]. `Content-Disposition` must be also set when a binary response format was requested: @@ -499,7 +445,7 @@ NOTE: the value may differ from the real size of requested data if compression o Returned only when request was a [`Range`](#range-request-header) request. -See [RFC7233#header.content-range](https://httpwg.org/specs/rfc7233.html#header.content-range). +See Section 14.4 of :cite[rfc9110]. ### `Accept-Ranges` (response header) @@ -554,7 +500,10 @@ This header only cares about logical roots (one per URL path segment): 3. `/ipns/en.wikipedia-on-ipfs.org/wiki/Block_of_Wikipedia_in_Turkey` → `bafkreibn6euazfvoghepcm4efzqx5l3hieof2frhp254hio5y7n3hv5rma` Final array of roots: -`X-Ipfs-Roots: bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze,bafybeihn2f7lhumh4grizksi2fl233cyszqadkn424ptjajfenykpsaiw4,bafkreibn6euazfvoghepcm4efzqx5l3hieof2frhp254hio5y7n3hv5rma` + +``` +X-Ipfs-Roots: bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze,bafybeihn2f7lhumh4grizksi2fl233cyszqadkn424ptjajfenykpsaiw4,bafkreibn6euazfvoghepcm4efzqx5l3hieof2frhp254hio5y7n3hv5rma +``` NOTE: while the first CID will change every time any article is changed, the last root (responsible for specific article or a subdirectory) may not diff --git a/src/http-gateways/subdomain-gateway.md b/src/http-gateways/subdomain-gateway.md index eca74b389..76e2f1d4c 100644 --- a/src/http-gateways/subdomain-gateway.md +++ b/src/http-gateways/subdomain-gateway.md @@ -1,16 +1,27 @@ -# Subdomain Gateway Specification - -![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) - -**Authors**: - -- Marcin Rataj ([@lidel](https://github.com/lidel)) +--- +maturity: reliable +date: 2023-01-28 +editors: + - name: Marcin Rataj + github: lidel + - name: Adrian Lanzafame + github: lanzafame + - name: Vasco Santos + github: vasco-santos + - name: Oli Evans + github: olizilla + - name: Thibault Meunier + github: thibmeu + - name: Steve Loeppky + github: BigLep +xref: + - url + - html +--- ----- - -**Abstract** +# Subdomain Gateway Specification -Subdomain Gateway is an extension of [PATH_GATEWAY.md](./PATH_GATEWAY.md) that +Subdomain Gateway is an extension of :cite[path-gateway] that enables website hosting isolated per CID/name, while remaining compatible with web browsers relative pathing and security model of the web. Below should be read as a delta on top of that spec. @@ -25,36 +36,9 @@ Summary: - Data is retrieved from IPFS in a way that is compatible with URL-based addressing - URL’s path `/` points at the content root identified by the CID -# Table of Contents - -- [Subdomain Gateway Specification](#subdomain-gateway-specification) -- [Table of Contents](#table-of-contents) -- [HTTP API](#http-api) - - [`GET /[{path}][?{params}]`](#get-pathparams) - - [`HEAD /[{path}][?{params}]`](#head-pathparams) -- [HTTP Request](#http-request) - - [Request Headers](#request-headers) - - [`Host` (request header)](#host-request-header) - - [`X-Forwarded-Proto` (request header)](#x-forwarded-proto-request-header) - - [`X-Forwarded-Host` (request header)](#x-forwarded-host-request-header) - - [Request Query Parameters](#request-query-parameters) - - [`uri` (request query parameter)](#uri-request-query-parameter) -- [HTTP Response](#http-response) - - [Response Headers](#response-headers) - - [`Location` (response header)](#location-response-header) - - [Use in interop with Path Gateway](#use-in-interop-with-path-gateway) - - [Use in URI router](#use-in-uri-router) -- [Appendix: notes for implementers](#appendix-notes-for-implementers) - - [Migrating from Path to Subdomain Gateway](#migrating-from-path-to-subdomain-gateway) - - [DNS label limits](#dns-label-limits) - - [Security considerations](#security-considerations) - - [URI router](#uri-router) - - [Redirects, single-page applications, and custom 404s](#redirects-single-page-applications-and-custom-404s) - # HTTP API -The API is a superset of [PATH_GATEWAY.md](./PATH_GATEWAY.md), the differences -are documented below. +The API is a superset of :cite[path-gateway], the differences are documented below. The main one is that Subdomain Gateway expects CID to be present in the `Host` header. @@ -70,7 +54,7 @@ Same as GET, but does not return any payload. # HTTP Request -Below MUST be implemented **in addition** to the [HTTP Request section from `PATH_GATEWAY.md`](./PATH_GATEWAY.md#http-request). +Below MUST be implemented **in addition** to "HTTP Request" of :cite[path-gateway]. ## Request Headers @@ -107,7 +91,7 @@ Converting `Host` into a content path depends on the nature of requested resourc valid content path, gateway MUST attempt to [migrate from Path to Subdomain Gateway](#migrating-from-path-to-subdomain-gateway). - Finally, if it is impossible to construct a content path from `Host`, - return HTTP Error [`400` Bad Request](./PATH_GATEWAY.md#400-bad-request). + return HTTP Error `400` Bad Request, as seen in :cite[path-gateway]. ### `X-Forwarded-Proto` (request header) @@ -147,18 +131,17 @@ See [URI router](#uri-router) section for usage and implementation details. # HTTP Response -Below MUST be implemented **in addition** to the [HTTP Response section from `PATH_GATEWAY.md`](./PATH_GATEWAY.md#http-response). +Below MUST be implemented **in addition** to "HTTP Response" of :cite[path-gateway]. ## Response Headers ### `Location` (response header) -Below MUST be implemented **in addition** to -[`Location` requirements defined in `PATH_GATEWAY.md`](./PATH_GATEWAY.md#location-response-header). +Below MUST be implemented **in addition** to `Location` requirements defined in :cite[path-gateway]. #### Use in interop with Path Gateway -Returned with [`301` Moved Permanently](./PATH_GATEWAY.md#301-moved-permanently) when `Host` header does +Returned with `301` Moved Permanently (:cite[path-gateway]) when `Host` header does not follow the subdomain naming convention, but the requested URL path happens to be a valid `/ipfs/{cid}` or `/ipfs/{name}` content path. @@ -185,7 +168,7 @@ See: [URI router](#uri-router) ## Migrating from Path to Subdomain Gateway -Subdomain Gateway MUST implement a redirect on paths defined in [`PATH_GATEWAY.md`](./PATH_GATEWAY.md). +Subdomain Gateway MUST implement a redirect on paths defined in :cite[path-gateway]. HTTP redirect will route path requests to correct subdomains on the same domain name, unless [`X-Forwarded-Host`](#x-forwarded-host-request-header) is present. @@ -203,8 +186,8 @@ breaking legacy clients that are unable to follow HTTP 301 redirects. ## DNS label limits DNS labels, must be case-insensitive, and up to a maximum of 63 characters -[per label](https://datatracker.ietf.org/doc/html/rfc2181#section-11). -Representing CIDs within these limits requires some care. +per label (Section 11 of :cite[rfc2181]). Representing CIDs within these limits +requires some care. Base32 multibase encoding is used for CIDs to ensure case-insensitve, URL safe characters are used. @@ -246,10 +229,8 @@ Subdomain gateway implementations MUST provide URI router for `ipfs://` and `ipns://` protocol schemes, allowing external apps to resolve these native addresses on a gateway. -The `/ipfs/?uri=%s` endpoint MUST be compatible with -[`registerProtocolHandler`](https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers), -present in web browsers. The value passed in `%s` should be -[percent-encoded](https://url.spec.whatwg.org/#string-utf-8-percent-encode). +The `/ipfs/?uri=%s` endpoint MUST be compatible with :ref[registerProtocolHandler(scheme, url)], +present in web browsers. The value passed in `%s` should be :ref[UTF-8 percent-encode]. **Example** @@ -270,4 +251,5 @@ From there, regular subdomain gateway logic applies. ## Redirects, single-page applications, and custom 404s -Subdomain Gateway implementations are free to include `_redirects` file support defined in [`REDIRECTS_FILE.md`](./REDIRECTS_FILE.md). +Subdomain Gateway implementations are free to include `_redirects` file +support defined in :cite[gateway-redirects-file]. \ No newline at end of file diff --git a/src/http-gateways/trustless-gateway.md b/src/http-gateways/trustless-gateway.md index 782865206..ff30b304c 100644 --- a/src/http-gateways/trustless-gateway.md +++ b/src/http-gateways/trustless-gateway.md @@ -1,16 +1,14 @@ -# Trustless Gateway Specification - -![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) - -**Authors**: - -- Marcin Rataj ([@lidel](https://github.com/lidel)) +--- +maturity: reliable +date: 2022-11-09 +editors: + - name: Marcin Rataj + github: lidel +--- ----- - -**Abstract** +# Trustless Gateway Specification -Trustless Gateway is a minimal _subset_ of [PATH_GATEWAY.md](./PATH_GATEWAY.md) +Trustless Gateway is a minimal _subset_ of :cite[path-gateway] that allows light IPFS clients to retrieve data behind a CID and verify its integrity without delegating any trust to the gateway itself. @@ -20,23 +18,9 @@ The minimal implementation means: - no path traversal or recursive resolution, no UnixFS/IPLD decoding server-side - response type is always fully verifiable: client can decide between a raw block or a CAR stream -# Table of Contents - -- [Trustless Gateway Specification](#trustless-gateway-specification) -- [Table of Contents](#table-of-contents) -- [HTTP API](#http-api) - - [`GET /ipfs/{cid}[?{params}]`](#get-ipfscidparams) - - [`HEAD /ipfs/{cid}[?{params}]`](#head-ipfscidparams) -- [HTTP Request](#http-request) - - [HTTP Request Headers](#http-request-headers) - - [`Accept` (request header)](#accept-request-header) -- [HTTP Response](#http-response) - - [HTTP Response Headers](#http-response-headers) - - [`Content-Disposition` (response header)](#content-disposition-response-header) - # HTTP API -A subset of [HTTP API from `PATH_GATEWAY.md`](./PATH_GATEWAY.md#http-api). +A subset of "HTTP API" of :cite[path-gateway]. ## `GET /ipfs/{cid}[?{params}]` @@ -48,7 +32,7 @@ Same as GET, but does not return any payload. # HTTP Request -Same as in [PATH_GATEWAY.md](./PATH_GATEWAY.md#http-request), but with limited number of supported response types. +Same as in :cite[path-gateway], but with limited number of supported response types. ## HTTP Request Headers @@ -66,7 +50,7 @@ Below response types MUST to be supported: # HTTP Response -Below MUST be implemented **in addition** to the [HTTP Response section from `PATH_GATEWAY.md`](./PATH_GATEWAY.md#http-response). +Below MUST be implemented **in addition** to "HTTP Response" of :cite[path-gateway]. ## HTTP Response Headers diff --git a/src/ipns/ipns-pubsub-router.md b/src/ipns/ipns-pubsub-router.md index bf47365e2..cccb0e64d 100644 --- a/src/ipns/ipns-pubsub-router.md +++ b/src/ipns/ipns-pubsub-router.md @@ -1,101 +1,97 @@ -# ![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) IPNS PubSub Router - -Authors: - -- Adin Schmahmann ([@aschmahmann](https://github.com/aschmahmann)) - -Reviewers: - ------ - -# Abstract - -[Inter-Planetary Naming System (IPNS)](./IPNS.md) is a naming system responsible for the creating, reading and updating of mutable pointers to data. -IPNS consists of a public/private asymmetric cryptographic key pair, a record type and a protocol. -Part of the protocol involves a routing layer that is used for the distribution and discovery of new or updated IPNS records. - -The IPNS PubSub router uses [libp2p PubSub](https://github.com/libp2p/specs/tree/master/pubsub) as a base, and adds persistence on top of it to ensure IPNS updates are always available to a connected network. -An inherent property of the IPNS PubSub Router is that IPNS records are republishable by peers other than the peer that originated the record. -This implies that as long as a peer on the network has an IPNS record it can be made available to other peers (although the records may be ignored if they are received after the IPNS record's End-of-Life/EOL). - -# Organization of this document - -- [Introduction](#introduction) -- [Protocol Overview](#pubsub-protocol-overview) -- [Protocol](#protocol) -- [Implementations](#implementations) - -# Introduction - -Each time a node publishes an updated IPNS record for a particular key it is propagated by the router into the network where network nodes can choose to accept or reject the new record. -When a node attempts to retrieve an IPNS record from the network it uses the router to query for the IPNS record(s) associated with the IPNS key; the node then validates the received records. - -In this spec we address building a router based on a PubSub system, particularly focusing on libp2p PubSub. - -# PubSub Protocol Overview - -The protocol has four components: - -- [IPNS Records and Validation](./IPNS.md) -- [libp2p PubSub](https://github.com/libp2p/specs/tree/master/pubsub) -- Translating an IPNS record name to/from a PubSub topic -- Layering persistence onto libp2p PubSub - -# Translating an IPNS record name to/from a PubSub topic - -For a given IPNS local record key described in the IPNS Specification the PubSub topic is: - -**Topic format:** `/record/base64url-unpadded(key)` - -where base64url-unpadded is an unpadded base64url as specified in [IETF RFC 4648](https://tools.ietf.org/html/rfc4648) - -# Layering persistence onto libp2p PubSub - -libp2p PubSub does not have any notion of persistent data built into it. However, we can layer persistence on top of PubSub by utilizing [libp2p Fetch](https://github.com/libp2p/specs/tree/master/fetch). - -The protocol has the following steps: - -1. Start State: Node `A` subscribes to the PubSub topic `t` corresponding to the local IPNS record key `k` -2. `A` notices that a node `B` has connected to it and subscribed to `t` -3. Some time passes (might be 0 seconds, or could use a more complex system to determine the duration) -4. `A` sends `B` a Fetch request for `k` -5. If Fetch returns a record that supersedes `A`'s current record then `A` updates its record and Publishes it to the network - -Note: PubSub does not guarantee that a message sent by a peer `A` will be received by a peer `B` and it's possible -(e.g. in systems like [gossipsub](https://github.com/libp2p/specs/tree/master/pubsub/gossipsub)) -that this is true even if `A` and `B` are already connected. Therefore, whenever `A` notices **any** node that has -connected to it and subscribed to `t` it should run the Fetch protocol as described above. However, developers may have routers -with properties that allow the amount of time in step 3 to increase arbitrarily large (including infinite) amounts. - -# Protocol - -A node `A` putting and getting updates to an IPNS key `k`, with computed PubSub topic `t` - -1. PubSub subscribe to `t` -2. Run the persistence protocol, both to fetch data and return data to those that request it -3. When updating a record do a PubSub Publish and keep the record locally -4. When receiving a record if it's better than the current record keep it and republish the message -5. (Optional) Periodically republish the best record available - -Note: 5 is optional because it is not necessary. However, receiving duplicate records are already handled efficiently -by the above logic and properly running the persistence protocol can be difficult (as in the example below). Periodic -republishing can then act as a fall-back plan in the event of errors in the persistence protocol. - -Persistence Error Example: - -1. `B` connects to `A` -2. `A` gets the latest record (`R1`) from `B` -3. `B` then disconnects from `A` -4. `B` publishes `R2` -5. `B` reconnects to `A` - -If `A`'s checking of when `B` reconnects has problems it could miss `R2` (e.g. if it polled subscribed peers -every 10 seconds) - -# Implementations - -- Kubo - - - - - - - - +--- +maturity: reliable +date: 2022-11-09 +editors: + - name: Adin Schmahmann + github: aschmahmann + - name: Marcin Rataj + github: lidel +xref: + - ipns-record +--- + +# IPNS PubSub Router + + +:ref[InterPlanetary Naming System (IPNS)] is a naming system responsible for the creating, reading and updating of mutable pointers to data. +IPNS consists of a public/private asymmetric cryptographic key pair, a record type and a protocol. +Part of the protocol involves a routing layer that is used for the distribution and discovery of new or updated IPNS records. + +The IPNS PubSub router uses [libp2p PubSub](https://github.com/libp2p/specs/tree/master/pubsub) as a base, and adds persistence on top of it to ensure IPNS updates are always available to a connected network. +An inherent property of the IPNS PubSub Router is that IPNS records are republishable by peers other than the peer that originated the record. +This implies that as long as a peer on the network has an IPNS record it can be made available to other peers (although the records may be ignored if they are received after the IPNS record's End-of-Life/EOL). + +# Introduction + +Each time a node publishes an updated IPNS record for a particular key it is propagated by the router into the network where network nodes can choose to accept or reject the new record. +When a node attempts to retrieve an IPNS record from the network it uses the router to query for the IPNS record(s) associated with the IPNS key; the node then validates the received records. + +In this spec we address building a router based on a PubSub system, particularly focusing on libp2p PubSub. + +# PubSub Protocol Overview + +The protocol has four components: + +- IPNS Records and Validation (:cite[ipns-record]) +- [libp2p PubSub](https://github.com/libp2p/specs/tree/master/pubsub) +- Translating an IPNS record name to/from a PubSub topic +- Layering persistence onto libp2p PubSub + +# Translating an IPNS record name to/from a PubSub topic + +For a given IPNS local record key described in the IPNS Specification the PubSub topic is: + +**Topic format:** `/record/base64url-unpadded(key)` + +where base64url-unpadded is an unpadded base64url as specified in :cite[rfc4648]. + +# Layering persistence onto libp2p PubSub + +libp2p PubSub does not have any notion of persistent data built into it. However, we can layer persistence on top of PubSub by utilizing [libp2p Fetch](https://github.com/libp2p/specs/tree/master/fetch). + +The protocol has the following steps: + +1. Start State: Node `A` subscribes to the PubSub topic `t` corresponding to the local IPNS record key `k` +2. `A` notices that a node `B` has connected to it and subscribed to `t` +3. Some time passes (might be 0 seconds, or could use a more complex system to determine the duration) +4. `A` sends `B` a Fetch request for `k` +5. If Fetch returns a record that supersedes `A`'s current record then `A` updates its record and Publishes it to the network + +Note: PubSub does not guarantee that a message sent by a peer `A` will be received by a peer `B` and it's possible +(e.g. in systems like [gossipsub](https://github.com/libp2p/specs/tree/master/pubsub/gossipsub)) +that this is true even if `A` and `B` are already connected. Therefore, whenever `A` notices **any** node that has +connected to it and subscribed to `t` it should run the Fetch protocol as described above. However, developers may have routers +with properties that allow the amount of time in step 3 to increase arbitrarily large (including infinite) amounts. + +# Protocol + +A node `A` putting and getting updates to an IPNS key `k`, with computed PubSub topic `t` + +1. PubSub subscribe to `t` +2. Run the persistence protocol, both to fetch data and return data to those that request it +3. When updating a record do a PubSub Publish and keep the record locally +4. When receiving a record if it's better than the current record keep it and republish the message +5. (Optional) Periodically republish the best record available + +Note: 5 is optional because it is not necessary. However, receiving duplicate records are already handled efficiently +by the above logic and properly running the persistence protocol can be difficult (as in the example below). Periodic +republishing can then act as a fall-back plan in the event of errors in the persistence protocol. + +Persistence Error Example: + +1. `B` connects to `A` +2. `A` gets the latest record (`R1`) from `B` +3. `B` then disconnects from `A` +4. `B` publishes `R2` +5. `B` reconnects to `A` + +If `A`'s checking of when `B` reconnects has problems it could miss `R2` (e.g. if it polled subscribed peers +every 10 seconds) + +# Implementations + +- Kubo + - + - + - + - diff --git a/src/ipns/ipns-record.md b/src/ipns/ipns-record.md index 45fd6c067..9fdaef27c 100644 --- a/src/ipns/ipns-record.md +++ b/src/ipns/ipns-record.md @@ -1,48 +1,35 @@ -# ![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) IPNS - Inter-Planetary Naming System - -**Authors(s)**: - -- Vasco Santos ([@vasco-santos](https://github.com/vasco-santos)) -- Steven Allen ([@Stebalien](https://github.com/Stebalien)) -- Marcin Rataj ([@lidel](https://github.com/lidel)) - ------ - -**Abstract** - -IPFS is powered by content-addressed data, which by nature is immutable: changing an object would change its hash, and consequently its address, making it a different object altogether. However, there are several use cases where we benefit from having mutable data. This is where IPNS gets into the equation. - -IPNS records provide cryptographically verifiable, mutable pointers to objects. - -## Organization of this document - -- [Introduction](#introduction) -- [IPNS Keys](#ipns-name) - - [Key Types](#key-types) - - [Key Serialization Format](#key-serialization-format) -- [IPNS Name](#ipns-name) - - [String Representation](#string-representation) -- [IPNS Record](#ipns-record) - - [Record Serialization Format](#record-serialization-format) - - [Record Size Limit](#record-size-limit) - - [Backward Compatibility](#backward-compatibility) -- [Protocol](#protocol) - - [Overview](#overview) - - [Record Creation](#record-creation) - - [Record Verification](#record-verification) -- [Integration with IPFS](#integration-with-ipfs) +--- +maturity: reliable +date: 2023-02-13 +editors: + - name: Vasco Santos + github: vasco-santos + - name: Steve Allen + github: Stebalien + - name: Marcin Rataj + github: lidel + - name: Henrique Dias + github: hacdias + url: https://hacdias.com/ + - name: Gus Eggert + github: guseggert +--- + +# InterPlanetary Naming System + +The InterPlanetary File System (IPFS) is powered by content-addressed data, which by nature is immutable: changing an object would change its hash, and consequently its address, making it a different object altogether. However, there are several use cases where we benefit from having mutable data. This is where the InterPlanetary Naming System (IPNS) gets into the equation. IPNS records provide cryptographically verifiable, mutable pointers to objects. ## Introduction Each time a file is modified, its content address changes. As a consequence, the address previously used for getting that file needs to be updated by who is using it. As this is not practical, IPNS was created to solve the problem. -IPNS is based on [SFS](http://en.wikipedia.org/wiki/Self-certifying_File_System). It consists of a PKI namespace, where a name is simply the hash of a public key. As a result, whoever controls the private key has full control over the name. Accordingly, records are signed by the private key and then distributed across the network (in IPFS, via the routing system). This is an egalitarian way to assign mutable names on the Internet at large, without any centralization whatsoever, or certificate authorities. +:dfn[InterPlanetary Naming System (IPNS)] is based on [Self-certifying File System (SFS)](http://en.wikipedia.org/wiki/Self-certifying_File_System). It consists of a PKI namespace, where a name is simply the hash of a public key. As a result, whoever controls the private key has full control over the name. Accordingly, records are signed by the private key and then distributed across the network (in IPFS, via the routing system). This is an egalitarian way to assign mutable names on the Internet at large, without any centralization whatsoever, or certificate authorities. ## IPNS Keys ### Key Types -Implementations MUST support Ed25519 with signatures defined in [RFC8032](https://www.rfc-editor.org/rfc/rfc8032#section-5.1). +Implementations MUST support Ed25519 with signatures defined in :cite[rfc8032]. Ed25519 is the current default key type. Implementations SHOULD support RSA if they wish to interoperate with legacy @@ -134,7 +121,7 @@ A logical IPNS record is a data structure containing the following fields: - When `validityType = 0` - Expiration date of the record with nanoseconds precision. Expiration time should match the publishing medium's window. - For example, IPNS records published on the DHT should have an expiration time set to within 48 hours after publication. Setting the expiration time to longer than 48 hours will not have any effect, as DHT peers only keep records for up to 48 hours. - - Represented as an ASCII string that follows notation from [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) (`1970-01-01T00:00:00.000000001Z`). + - Represented as an ASCII string that follows notation from :cite[rfc3339] (`1970-01-01T00:00:00.000000001Z`). - Implementations MUST include this value in both `IpnsEntry.validity` and inside the DAG-CBOR document at `IpnsEntry.data[validity]`. - **Sequence** (uint64) - Represents the current version of the record (starts at 0). @@ -251,7 +238,7 @@ Once the record is created, it is ready to be spread through the network. This w The means of distribution are left unspecified. Implementations MAY choose to publish signed record using multiple routing systems, such as -[libp2p Kademlia DHT](https://github.com/libp2p/specs/tree/master/kad-dht) or [PubSub](./IPNS_PUBSUB.md) (see [Routing record](#routing-record)). +[libp2p Kademlia DHT](https://github.com/libp2p/specs/tree/master/kad-dht) or :cite[ipns-pubsub-router] (see [Routing record](#routing-record)). On the other side, each peer must be able to get a record published by another node. It only needs to have the unique identifier used to publish the record to the network. Taking into account the routing system being used, we may obtain a set of occurrences of the record from the network. In this case, records can be compared using the sequence number, in order to obtain the most recent one. @@ -270,7 +257,7 @@ Creating a new IPNS record MUST follow the below steps: - This is paramount: this CBOR will be used for signing. 3. Store DAG-CBOR in `IpnsEntry.data`. - If you want to store additional metadata in the record, add it under unique keys at `IpnsEntry.data`. - - The order of fields impacts signature verification. If you are using an alternative CBOR implementation, make sure the CBOR field order follows [RFC7049](https://www.rfc-editor.org/rfc/rfc7049) sorting rules: length and then bytewise. The order of fields impacts signature verification. + - The order of fields impacts signature verification. If you are using an alternative CBOR implementation, make sure the CBOR field order follows :cite[rfc7049] sorting rules: length and then bytewise. The order of fields impacts signature verification. 4. If your public key can't be inlined inside the IPNS Name, include a serialized copy in `IpnsEntry.pubKey` - This step SHOULD be skipped for Ed25519, and any other key types that are inlined inside of [IPNS Name](#ipns-name) itself. 5. Create `IpnsEntry.signatureV2` @@ -317,12 +304,12 @@ A legacy convention that implementers MAY want to follow is to store serialized **Key format:** `/ipns/base32()` -Note: Base32 according to the [RFC4648](https://tools.ietf.org/html/rfc4648). +Note: Base32 according to the :cite[rfc4648]. ### Routing Record The routing record is spread across the network according to the available routing systems. -The two routing systems currently available in IPFS are the [libp2p Kademlia DHT](https://github.com/libp2p/specs/tree/master/kad-dht) and [IPNS over PubSub](./IPNS_PUBSUB.md). +The two routing systems currently available in IPFS are the [libp2p Kademlia DHT](https://github.com/libp2p/specs/tree/master/kad-dht) and :cite[ipns-pubsub-router]. **Key format:** `/ipns/BINARY_ID` diff --git a/src/meta/code-of-conduct.md b/src/meta/code-of-conduct.md new file mode 100644 index 000000000..10ff423b9 --- /dev/null +++ b/src/meta/code-of-conduct.md @@ -0,0 +1,129 @@ +--- +date: 2015-03-19 +editors: + - name: Juan Benet + github: jbenet + - name: Harlan T Wood + github: harlantwood + - name: Richard Littauer + github: RichardLitt + - name: Michelle Hertzfeld + github: meiqimichelle + - name: Matt Zumwalt + github: flyingzumwalt + - name: Hector Sanjuan + github: hsanjuan + - name: Jim Garrison + github: garrison +--- + +# IPFS Community Code of Conduct + +We believe that our mission is best served in an environment that is friendly, safe, and accepting, and free from +intimidation or harassment. Towards this end, certain behaviors and practices will not be tolerated. + +:::note + +This document was [copied from GitHub](https://github.com/ipfs/community/commits/master/code-of-conduct.md), the +editiors listed are the contributors to that file in chronological order. + +::: + +## tl;dr + +- Be respectful. +- We're here to help: abuse@ipfs.io +- Abusive behavior is never tolerated. +- Violations of this code may result in swift and permanent expulsion from the IPFS community. +- "Too long, didn't read" is not a valid excuse for not knowing what is in this document. + +## Scope + +We expect all members of the IPFS community to abide by this Code of Conduct at all times in all IPFS community venues, online and in person, and in one-on-one communications pertaining to IPFS affairs. + +This policy covers the usage of IPFS public infrastructure, including the IPFS.io HTTP gateways, as well as other IPFS websites, IPFS related events, and any other services offered by or on behalf of the IPFS community. It also +applies to behavior in the context of the IPFS Open Source project communities, including but not limited to public GitHub repositories, IRC channels, social media, mailing lists, and public events. + +This Code of Conduct is in addition to, and does not in any way nullify or invalidate, any other terms or conditions related to use of IPFS services. + +The definitions of various subjective terms such as "discriminatory", "hateful", or "confusing" will be decided at the sole discretion of the [IPFS abuse team](#contact-info). + +## Friendly Harassment-Free Space + +We are committed to providing a friendly, safe and welcoming environment for all, regardless of gender identity, sexual orientation, disability, ethnicity, religion, age, physical appearance, body size, race, or similar personal characteristics. + +We ask that you please respect that people have differences of opinion regarding technical choices, and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a single right answer. A difference of technology preferences is not a license to be rude. + +Any spamming, trolling, flaming, baiting, or other attention-stealing behavior is not welcome, and will not be tolerated. + +Harassing other users is never tolerated, whether via public or private media. + +Avoid using offensive or harassing nicknames, or other identifiers that might detract from a friendly, safe, and welcoming environment for all. + +Harassment includes, but is not limited to: any behavior that threatens or demeans another person or group, or produces an unsafe environment; harmful or prejudicial verbal or written comments related to gender, gender expression, gender identity, sexual orientation, disability, ethnicity, religion, age, physical appearance, body size, race, or similar personal characteristics; inappropriate use of nudity, sexual images, and/or sexually explicit language in public spaces; threats of physical or non-physical harm; deliberate intimidation, stalking or following; harassing photography or recording; sustained disruption of talks or other events; inappropriate physical contact; and unwelcome sexual attention. + +Media shared through public infrastructure run by the IPFS team must not contain illegal or infringing content. You should only publish content via IPFS public infrastructure if you have the right to do so. This includes complying with all software license agreements or other intellectual property restrictions. You will be solely responsible for any violation of laws or +others’ intellectual property rights. + +## Reporting Violations of this Code of Conduct + +If you believe someone is harassing you or has otherwise violated this Code of Conduct, please [contact us](#contact-info) to send us an abuse report. If this is the initial report of a problem, please include as much detail as possible. It is easiest for us to address issues when we have more context. + +If you are at an event organized by the IPFS community, contact a _duty officer_ or event staff. To learn more about our procedures handling incidents and reports at events, read the [procedures for in-person events](code-of-conduct-procedures-for-events.md) + +## Copyright Violations + +We respect the intellectual property of others and ask that you do too. If you believe any content or other materials available through public IPFS infrastructure violates a copyright held by you and you would like to submit a notice pursuant to the Digital Millennium Copyright Act or other similar international law, you can submit a notice to the [abuse team](#contact-info) for service. + +(We will add a physical mailing address here when we acquire one). + +Please make sure your notice meets the Digital Millennium Copyright Act requirements. + +## Consequences + +All content published to public IPFS infrastructure is hosted at the sole discretion of the IPFS team. + +Unacceptable behavior from any community member will not be tolerated. + +Anyone asked to stop unacceptable behavior is expected to comply immediately. + +If a community member engages in unacceptable behavior, the IPFS team may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event or service). + +## Addressing Grievances + +If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify the IPFS team. We will do our best to ensure that your grievance is handled appropriately. + +In general, we will choose the course of action that we judge as being most in the interest of fostering a safe and friendly community. + +On IRC, let one of the ops know if you think that someone has transgressed against the Code of Conduct. If you would like to be an op and promise to help maintain and abide by the code, please let us know. + +## Contact Info + +Please contact abuse@ipfs.io if you need to report a problem or address a grievance related to an abuse report. + +We will keep all matters confidential and they will only be shared within the team, with the exception of legal counsel when deemed necessary, or unless given explicit permission by the reporter. + +If you prefer, you can contact any of the abuse team members separately. The abuse team is formed by: + +- molly@ipfs.io +- dietrich@ipfs.io +- michael@ipfs.io +- ebony@ipfs.io +- hector@ipfs.io + +When contacting an individual directly, they will ask for explicit permission to share the details with the rest of the team. When not granted, they will keep details of the matters as confidential as possible (particularly private or identity information) but they may still share broad strokes as necessary to resolve the issue. + +You are also encouraged to contact us if you are curious about something that might be "on the line" between appropriate and inappropriate content. We are happy to provide guidance to help you be a successful part of our community. + +## Events + +Please see our [Code of Conduct Events Addendum](https://github.com/ipfs/community/commits/master/code-of-conduct-for-events.md) in the original repo. + +## Changes + +This is a living document and may be updated from time to time. Please refer to the git history for this document to view the changes. + +## Credit and License +This Code of Conduct is based on the [npm Code of Conduct](https://www.npmjs.com/policies/conduct) and the [CodeOfConduct4Lib](https://github.com/code4lib/code-of-conduct/blob/master/code_of_conduct.md), which itself is based on the [example policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment) from the [Geek Feminism wiki](http://geekfeminism.wikia.com/), created by the Ada Initiative and other volunteers. + +This document may be reused under a [Creative Commons Attribution-ShareAlike License](http://creativecommons.org/licenses/by-sa/4.0/). diff --git a/src/meta/spec-for-specs.md b/src/meta/spec-for-specs.md new file mode 100644 index 000000000..618d732bc --- /dev/null +++ b/src/meta/spec-for-specs.md @@ -0,0 +1,278 @@ +--- +date: 2023-03-14 +editors: + - name: Robin Berjon + email: robin@berjon.com + url: https://berjon.com/ + github: darobin + twitter: robinberjon + mastodon: "@robin@mastodon.social" + affiliation: + name: Protocol Labs + url: https://protocol.ai/ +maturity: stable +xref: + - dom + - test-methodology +--- + +# Spec for Specs + +This document specifies the format and system used to create and maintain specifications for +the interplanetary stack. + +## Structure + +Interplanetary specs are designed to be easy to write and maintain while still providing support for +document production features expected from Internet standards. A :dfn[spec] is a Markdown document enriched +with a small number of additional directives (a deliberate goal being to avoid the proliferation of +ad hoc syntax) and a specialised processor that knows how to resolve and extract metadata that is +useful to support rich interlinking in a standards suite. + +The name of the Markdown file matters, because it will be used as the :ref[spec]'s :ref[shortname]. +The :dfn[shortname] of a :ref[spec] is the key identifier that is used to refer to it when citing that +:ref[spec] or importing its definitions. The :ref[shortname] for this :ref[spec] is `spec-for-specs` +which means that you can cite it using `:cite[spec-for-specs]` which comes out as :cite[spec-for-specs] +(a :ref[spec] citing itself is not all that useful, really, but you can *also* do it from other +:ref[specs], which is kind of the point). The :ref[shortname] SHOULD be unique inside interplanetary +:ref[specs], and ideally in the entirety of the relevant standards universe, though that can at times +prove challenging. + +### Frontmatter + +A :ref[spec] MUST being with :ref[frontmatter]. :dfn[Frontmatter] is a preamble to the document placed +right at the start, delimited with `---` and containing YAML data (:cite[YAML]). The :ref[frontmatter] +for this :ref[spec] looks like this: + +```yaml +--- +date: 1977-03-15 +editors: + - name: Robin Berjon + email: robin@berjon.com + url: https://berjon.com/ + github: darobin + twitter: robinberjon + mastodon: "@robin@mastodon.social" + affiliation: + name: Protocol Labs + url: https://protocol.ai/ +maturity: stable +xref: + - dom + - test-methodology +--- +``` + +The :ref[frontmatter] MUST contain an `editors` field, which is an array of objects describing people +who are responsible for editing this given :ref[spec]. The `editors` field MUST contain at least one +person. The fields that describe a person are `name`, `email`, `url`, `github`, `twitter`, `mastodon`, +and `affiliation` which is in turn an object with fields `name` and `url`. Each person as well as the +affiliation MUST have a `name`; every other field is OPTIONAL. + +The `xref` field exemplified above is described in the [references](#refs) section. + +The `maturity` field indicates the document's stability. This list is subject to revision, but the +maturity levels currently supported are: +- ![draft](https://img.shields.io/badge/status-draft-yellow.svg?style=flat-square) +- ![WIP](https://img.shields.io/badge/status-wip-orange.svg?style=flat-square) +- ![reliable](https://img.shields.io/badge/status-reliable-green.svg?style=flat-square) +- ![stable](https://img.shields.io/badge/status-stable-brightgreen.svg?style=flat-square) +- ![permanent](https://img.shields.io/badge/status-permanent-blue.svg?style=flat-square) +- ![deprecated](https://img.shields.io/badge/status-deprecated-red.svg?style=flat-square) + +The `date` field is a `YYYY-MM-DD` specification of the last dated change to the spec. + +### Title & Sections + +A :ref[spec] MUST have a title, which is to say an `h1` heading (`# Some Title` in Markdown). It also +SHOULD have only one such title (every other heading should be `h2` or more) and have the title right +after the :ref[frontmatter]. The behaviour of multiple titles or titles positioned at random places in +the :ref[spec] is undefined and has been shown to disappoint kittens under experimental conditions. + +Sections in a :ref[spec] are nested by using various heading depths. Note that nesting levels are +enforced automatically. If for instance you have an `h5` following an `h2`, it will be promoted to an +`h3` (recursively if it had nested `h6`s of its own). + +All of the content between the `h1` spec title and the first subheading of the document is considered +to be the abstract for the document and will be incorporated into the header material. + +Sections automatically get an identifier based on their heading. This is convenient, but it can cause +broken links when the section heading changes. If you wish to specify your own ID for a section you can +do so by appending `{#your-id}` to the heading, like so: + +```md +### My Cool Section {#cool} +``` + +## Testable Assertions + +Specifications SHOULD make use of :cite[RFC2119] keywords such as MUST or MUST NOT in order to express +conformance expectations as :ref[testable assertion]s. + +All you need to do to avail yourself of these keywords is to type them in all caps, no markup required. +Additionally, if you use one the processor will automatically add a reference to :cite[RFC2119]. The +available RFC2119 keywords are: + +* MUST +* MUST NOT +* SHOULD +* SHOULD NOT +* SHALL +* SHALL NOT +* MAY +* REQUIRED +* NOT REQUIRED +* RECOMMENDED +* NOT RECOMMENDED +* OPTIONAL + +It is probably a bad idea to use the SHALL variants, and generally it is best to stick to MUST, SHOULD, MAY, +and their negations. In an ideal world, a :ref[spec] would stick to only using MUST and MUST NOT because +optionality in standards is harmful. In practice, however, some flexibilty can prove necessary. + +:::note + +I highly recommend reading [*A Method for Writing Testable Conformance Requirements*](https://www.w3.org/TR/test-methodology/) +(:cite[test-methodology]). Hidden behind that fanciful, almost enticingly romantic title is a treasure trove +of advice in writing good specification language. The core tenet of that document is simple: a good :ref[spec] +is a testable one, because tests are the empirical ground truth of interoperability. And in order to make a +:ref[spec] testable, it needs to be built from :ref[testable assertion]s and there is an art to writing those +effectively, which includes the judicious application of RFC2119 keywords. + +::: + +## Special Blocks + +A number of additional structural constructs are available to capture common blocks that are +useful in specs: issues, warnings, notes, and examples. + +An issue looks like this: + +:::issue + +This is a big, big problem. + +::: + +And the code for it is: + +```md +:::issue + +This is a big, big problem. + +::: +``` + +A warning looks like this: + +:::warning + +Be careful!!! + +Thar be dragons! + +::: + +And the code for it is: + +```md +:::warning + +Be careful!!! + +Thar be dragons! + +::: +``` + +A note looks like this: + +:::note + +Really, you want to pay attention to these things, because they kind of tend to matter, you know. + +::: + +And the code for it is: + +```md +:::note + +Really, you want to pay attention to these things, because they kind of tend to matter, +you know. + +::: +``` + +An example looks like this: + +:::example + +And then it's just `document.getElementById('foo')`. + +::: + +And the code for it is: + +```md +:::example + +And then it's just `document.getElementById('foo')`. + +::: +``` + +When including code, the best option is to specify the code's language as part of the code fence. This enables Prism to +kick in and to carry out syntax highlighting. + +## Definitions + +A :dfn[definition]{also="dfn,def"} is a key concept in a specification that can be referenced from other parts of the +spec or in other specs. The definition is created with a `:dfn[defined term]` directive. Some definitions can benefit +from having synonyms, and these can be specified as a comma-separated list with an `also` attribute as in +`:dfn[defined term]{also="term, def"}`. + +Plurals are handled for you (for English-language specs), so that you can reference :ref[definitions] without trouble. + +## References {#refs} + +### Definitions + +There are two primary types of references: to :ref[definitions] and to full documents that get added to the spec's +bibliographic references section. + +Once a :ref[definition] has been created, it can be referenced with `:ref[definition]`. This includes the synonyms it +was givem, for instance :ref[def]. + +It's also possible to reference definitions from other specs by importing those other specs by referencing their :ref[shortnames] +in the `xref` section of the YAML :ref[frontmatter]: + +```yaml +xref: + - dom + - spec-for-specs +``` + +Definitions are automatically extracted from each interplanetary :ref[spec] and stored in the same repository, under +`refs/dfn`. You can grep in there to find what you need to import if you are unsure which :ref[spec] defines a given +term. For :ref[specs] from the broader standards universe, you can use the [xref tool](https://respec.org/xref/) that +is part of [ReSpec](https://respec.org/) to look them up. Definition from any spec in the +[xref tool](https://respec.org/xref/) can be imported and used in an interplanetary :ref[spec]. This typically covers +definitions from the W3C, IETF, WHATWG, ECMA TC39, the Khronos Group, Unicode, and an assortment of others. + +Once that's done, you can reference, say, the DOM concept of :ref[element] with just `:ref[element]` as if it were +defined locally. + +### Bibliographic + +Citing specs or more generally documents like :cite[html], :cite[rfc8890], :cite[privacy-principles], or :cite[spec-for-specs] +is accomplished using the shortname in a +`:cite[shortname]` block, as in `:cite[html], :cite[rfc8890], :cite[privacy-principles], or :cite[spec-for-specs]`. The idea +is to use this mechanism to easily provide context when you are referring to notions defined in another document but not +specifically a :ref[definition] in particular. + +Simply by citing a given document it will be added to the bibliographic reference section that is automatically generated +at the end of your :ref[spec]. You can use any :ref[shortname] listed in [Specref](https://www.specref.org/) (there are +over 50k docs there) as well as any :ref[shortname] from the interplanetary space. From d37cb8ad36a1d4fa9cc1ada1d73ee6d18ef3dbe8 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 Mar 2023 09:30:03 +0100 Subject: [PATCH 04/13] chore: set-up generator, styles, indexes Co-authored-by: Robin Berjon --- .config.json | 6 ++ .gitignore | 1 + Makefile | 13 ++- src/_includes/footer.html | 16 ++++ src/_includes/head.html | 11 +++ src/_includes/header.html | 15 ++++ src/css/index.css | 166 +++++++++++++++++++++++++++++++++++ src/css/specs.css | 131 +++++++++++++++++++++++++++ src/http-gateways/index.html | 55 ++++++++++++ src/index.html | 156 ++++++++++++++++++++++++++++++++ src/ipns/index.html | 23 +++++ src/ipns/ipns-record.md | 2 +- src/meta/index.html | 25 ++++++ template.html | 18 ++++ 14 files changed, 636 insertions(+), 2 deletions(-) create mode 100644 .config.json create mode 100644 .gitignore create mode 100644 src/_includes/footer.html create mode 100644 src/_includes/head.html create mode 100644 src/_includes/header.html create mode 100644 src/css/index.css create mode 100644 src/css/specs.css create mode 100644 src/http-gateways/index.html create mode 100644 src/index.html create mode 100644 src/ipns/index.html create mode 100644 src/meta/index.html create mode 100644 template.html diff --git a/.config.json b/.config.json new file mode 100644 index 000000000..e3a0b4f76 --- /dev/null +++ b/.config.json @@ -0,0 +1,6 @@ +{ + "input": "src", + "output": "out", + "template": "template.html", + "baseURL": "https://specs.ipfs.tech" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..466e24805 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +out/ \ No newline at end of file diff --git a/Makefile b/Makefile index 8ed9b4f43..34e1f3133 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,15 @@ -all: superlinter +SPEC_GENERATOR_VER=v1.1.2 + +all: website + +clean: + rm -rf ./out + +website: clean + npx spec-generator@$(SPEC_GENERATOR_VER) -c .config.json + +watch: clean + npx spec-generator@$(SPEC_GENERATOR_VER) -c .config.json -w superlinter: docker run --rm -e VALIDATE_ALL_CODEBASE=false -e RUN_LOCAL=true -e VALIDATE_MARKDOWN=true -e MARKDOWN_CONFIG_FILE=".markdownlint.json" -e LINTER_RULES_PATH="." -v $(shell pwd):/tmp/lint github/super-linter:v4 diff --git a/src/_includes/footer.html b/src/_includes/footer.html new file mode 100644 index 000000000..26e5351e9 --- /dev/null +++ b/src/_includes/footer.html @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/src/_includes/head.html b/src/_includes/head.html new file mode 100644 index 000000000..dfa3a3ff6 --- /dev/null +++ b/src/_includes/head.html @@ -0,0 +1,11 @@ + + + + + + {% if title != 'Home' %}{{ title }} | {% endif %}IPFS Standards + + + + + \ No newline at end of file diff --git a/src/_includes/header.html b/src/_includes/header.html new file mode 100644 index 000000000..234d9dcbc --- /dev/null +++ b/src/_includes/header.html @@ -0,0 +1,15 @@ +{% include 'head.html' %} + + + +
+
+

{{ title }}

+

{{ description }}

+
+
diff --git a/src/css/index.css b/src/css/index.css new file mode 100644 index 000000000..8ee142d61 --- /dev/null +++ b/src/css/index.css @@ -0,0 +1,166 @@ + +body { + margin: 0; + padding: 0; + font-size: 1rem; + line-height: 1.5; + font-family: var(--body-family); + font-weight: 300; +} + +nav { + background: var(--ipfs-gradient-0-background-image); +} +nav > div { + max-width: var(--max-page-width); + margin: 0 auto; + padding: 1rem 1rem; +} +nav img, +nav a { + vertical-align: middle; +} +nav a { + color: var(--ipfs-off-white); + text-decoration: none; + /* font-size: var(--size-h5); */ + font-weight: var(--weight-semi-bold); +} + +header { + background: var(--ipfs-brand-gradient); +} +header > div { + max-width: var(--max-page-width); + margin: 0 auto; + padding: 3rem 1rem; +} +header h1 { + font-size: var(--size-h2); + font-weight: var(--weight-semi-bold); + margin-top: 0; + line-height: 1; + color: var(--ipfs-off-white); +} +header img.logo { + margin-bottom: 2rem; +} +header p { + color: var(--ipfs-off-white); + max-width: var(--max-readable-width); +} + +main { + max-width: var(--max-page-width); + margin: 4rem auto 0; + padding: 0 1rem; +} + +.basic-grid { + display: grid; + column-gap: 4rem; + row-gap: 4rem; + grid-template-columns: repeat(1, minmax(0,1fr)); +} +@media (min-width: 640px) { + .basic-grid { + grid-template-columns: repeat(2, minmax(0,1fr)); + } +} + +h2.pitch-title { + color: var(--fg); + text-align: center; + margin-top: 9rem; + font-weight: var(--weight-regular); + font-size: var(--size-h2); + margin-bottom: 1rem; + line-height: 1; +} +.pitch-subtitle { + text-align: center; + font-size: var(--size-h5); + font-weight: var(--weight-light); + margin-bottom: 4rem; + line-height: 1.2; +} +.pitch { + background: var(--stark-bg); + color: var(--stark-fg); + padding: 0 1rem; +} +.pitch h3 { + text-align: center; + margin-bottom: 1rem; +} +.pitch h3::after { + width: 3rem; + height: 0.5rem; + background: var(--ipfs-teal); + display: block; + content: " "; + margin: 0.5rem auto; +} + +main > section { + margin-top: 9rem; +} +h2 { + font-size: var(--size-h2); + font-weight: var(--weight-semi-bold); + margin-bottom: 1rem; +} +main > section section { + background: var(--stark-bg); + color: var(--stark-fg); + padding: 0 1rem; +} +h3 { + font-size: var(--size-h3); + font-weight: var(--weight-semi-bold); + margin-bottom: 1rem; +} +h3 a { + color: inherit; +} + +a { + color: var(--highlight-colour); + transition: color 0.2s; +} +a:hover { + color: var(--ipfs-yellow); +} +dt { + font-style: normal; + font-weight: bold; +} +dt a { + text-decoration-color: var(--ipfs-stone-grey); + display: block; +} +dd { + font-style: normal; + margin-left: 1rem; + margin-bottom: .6rem; +} + + +footer { + margin-top: 4rem; + text-align: center; + color: var(--ipfs-ash-grey); + background: var(--stark-bg); + border-top: 1px solid var(--ipfs-jade); +} +footer > div { + max-width: var(--max-page-width); + margin: 0 auto; + padding: 1rem 1rem 3rem 1rem; +} +footer a { + text-decoration: none; +} +footer img { + vertical-align: text-bottom; +} diff --git a/src/css/specs.css b/src/css/specs.css new file mode 100644 index 000000000..d509482b1 --- /dev/null +++ b/src/css/specs.css @@ -0,0 +1,131 @@ + + +:root { + --size-mono: 0.9em; +} + +body { + max-width: var(--max-readable-width); + margin: 0 auto; + padding: 0 0 0 0; + line-height: 1.5; +} + +#ipseity-back-to-root { + margin-bottom: 2rem; + background: var(--standard-gradient); + padding-left: 1rem; + font-weight: 600; + font-size: 0.9rem; +} + +#ipseity-back-to-root a { + color: var(--ipfs-off-white); + text-decoration: none; + transition: color 0.2s; +} + +#ipseity-back-to-root a:hover { + color: var(--ipfs-yellow); +} + +header { + background-image: url(/img/ipfs-standards.svg); + background-repeat: no-repeat; + background-size: 100px; + background-position-x: right; + margin-bottom: 3rem; + border-bottom: 0.25rem solid var(--ipfs-turquoise); + padding-bottom: 2rem; +} + +header dt { + font-weight: var(--weight-regular); + text-decoration: underline; +} + +header dd img { + opacity: 0.5; + transition: opacity .5s; + background: var(--contrast-bg); + border-radius: 2px; + vertical-align: sub; +} + +header dd img:hover { + opacity: 1; +} + +header dd a { + text-decoration: none; +} + +h1 { + max-width: calc(100% - (100px + 1rem)); + font-weight: var(--weight-semi-bold); + line-height: 1; + margin: 0.15rem 0 0 0; +} + +h2, h3, h4, h5, h6 { + margin: 3rem 0 0 0; + font-weight: var(--weight-semi-bold); +} + +:is(h2, h3, h4, h5, h6) bdi.secno { + color: var(--ipfs-ash-grey); +} + +p#last-modified { + color: var(--ipfs-ash-grey); + margin-top: 0rem; + font-size: 1.6rem; +} + +p { + margin: 1rem 0; +} + +.header-wrapper { + display: flex; + align-items: baseline; +} + +.header-wrapper + section > .header-wrapper > :is(h3, h4, h5, h6) { + margin-top: 1rem; +} + +.self-link::after { + color: var(--ipfs-ash-grey); +} + +.self-link:hover::after { + color: var(--ipfs-yellow); +} + +@media only screen and (max-width: 816px) { + body { + margin-left: 1rem; + margin-right: 1rem; + font-size: 1rem; + } + + #ipseity-back-to-root { + margin: 0 -1rem 2rem -1rem; + } + + header { + background-size: 50px; + } + + p#last-modified { + margin-top: -0.8rem; + font-size: 1.2rem; + } +} + +@media print { + body { + font-size: 1rem; + } +} diff --git a/src/http-gateways/index.html b/src/http-gateways/index.html new file mode 100644 index 000000000..842cfe063 --- /dev/null +++ b/src/http-gateways/index.html @@ -0,0 +1,55 @@ +--- +title: HTTP Gateways +description: | + IPFS Gateway acts as a bridge between traditional HTTP clients and IPFS. Through the gateway, users can download files, + directories and other IPLD data stored in IPFS as if they were stored in a traditional web server. +--- + +{% include 'header.html' %} + +
+

HTTP

+

+ Low-level gateways that expose IPFS resources over HTTP protocol. +

+
+
Path Gateways
+
+ The most versatile form of IPFS Gateway is a Path Gateway. It exposes namespaces like /ipfs/ and + /ipns/ under an HTTP server root and provides basic primitives for integrating IPFS resources + within the existing HTTP stack. +
+
Trustless Gateways
+
+ Trustless Gateways are a minimal subset of Path Gateways + that allow light IPFS clients to retrieve data behind a CID and verify its integrity without delegating any + trust to the gateway itself. +
+
+

Web

+

+ Designed for website hosting and improved interoperability with web browsers and + origin-based security model. +

+
+
DNSLink Gateways
+
+ DNSLink Gateways are an extension of Path Gateways that enable hosting a + specific content path under a specific DNS name. +
+
Subdomain Gateways
+
+ Subdomain Gateways are an extension of Path Gateways that + enable website hosting isolated per CID/name, while remaining compatible with web browsers relative pathing and + the security model of the web. +
+
Redirects File
+
+ The Redirects File specification is an extension of the Subdomain Gateway and DNSLink Gateway specifications that + enables URL redirects or rewrites by adding redirect rules to a0 file stored underneath the root CID of a web + site. +
+
+
+ +{% include 'footer.html' %} diff --git a/src/index.html b/src/index.html new file mode 100644 index 000000000..b3fe0d367 --- /dev/null +++ b/src/index.html @@ -0,0 +1,156 @@ +--- +title: Home +--- + +{% include 'head.html' %} + +
+
+ +

IPFS Standards

+

+ The purpose of IPFS Standards is to foster interoperability between independent implementations of + the IPFS stack by producing Internet-grade specifications and test suites. +

+
+
+ +
+

Specifying IPFS and the Interplanetary stack.

+

+ The technology that powers the content-addressable web is being standardized here. +

+ + +
+

Specifications

+

+ The specifications are broken up into multiple areas that cover the stack. +

+
+
+

HTTP Gateways

+

+ IPFS Gateway acts as a bridge between traditional HTTP clients and IPFS. Through the gateway, users can download files, + directories and other IPLD data stored in IPFS as if they were stored in a traditional web server. +

+
+
Path Gateways
+
+ The most versatile form of IPFS Gateway is a Path Gateway. It exposes namespaces like /ipfs/ and + /ipns/ under an HTTP server root and provides basic primitives for integrating IPFS resources + within the existing HTTP stack. +
+
Trustless Gateways
+
+ Trustless Gateways are a minimal subset of Path Gateways + that allow light IPFS clients to retrieve data behind a CID and verify its integrity without delegating any + trust to the gateway itself. +
+
DNSLink Gateways
+
+ DNSLink Gateways are an extension of Path Gateways that enable hosting a + specific content path under a specific DNS name. +
+
Subdomain Gateways
+
+ Subdomain Gateways are an extension of Path Gateways that + enable website hosting isolated per CID/name, while remaining compatible with web browsers relative pathing and + the security model of the web. +
+
Redirects File
+
+ The Redirects File specification is an extension of the Subdomain Gateway and DNSLink Gateway specifications that + enables URL redirects or rewrites by adding redirect rules to a0 file stored underneath the root CID of a web + site. +
+
+
+
+

InterPlanetary Naming System

+

+ The InterPlanetary Naming System (IPNS) is a naming system responsible for creating, reading and updating mutable pointers to data. +

+ +
+
IPNS Record and Protocol
+
+ Specifies the IPNS protocol in a language-agnostic manner, allowing everyone to create a compatible IPNS Record Publisher + or Resolver. +
+
IPNS PubSub Router
+
+ Specifies how to publish and retrieve IPNS records using libp2p PubSub router. +
+
+ +
+
+

Meta

+

+ Meta contains all the non-technical documents that conspire to make the standards + project work: what the core values are, what the governance model is, how to produce documents, + etc. +

+
+
Code of Conduct
+
+ The code of conduct that all community participants are held to. +
+
Spec for Specs
+
+ Specifies the format and system used to create and maintain specifications for + the interplanetary stack. +
+ +
+
+
+
+
+ +{% include 'footer.html' %} diff --git a/src/ipns/index.html b/src/ipns/index.html new file mode 100644 index 000000000..a5e977a7b --- /dev/null +++ b/src/ipns/index.html @@ -0,0 +1,23 @@ +--- +title: InterPlanetary Naming System +description: | + The InterPlanetary Naming System (IPNS) is a naming system responsible for creating, reading and updating mutable pointers to data. +--- + +{% include 'header.html' %} + +
+
+
IPNS Record and Protocol
+
+ Specifies the IPNS protocol in a language-agnostic manner, allowing everyone to create a compatible IPNS Record Publisher + or Resolver. +
+
IPNS PubSub Router
+
+ Specifies how to publish and retrieve IPNS records using libp2p PubSub router. +
+
+
+ +{% include 'footer.html' %} diff --git a/src/ipns/ipns-record.md b/src/ipns/ipns-record.md index 9fdaef27c..ceab75c7d 100644 --- a/src/ipns/ipns-record.md +++ b/src/ipns/ipns-record.md @@ -15,7 +15,7 @@ editors: github: guseggert --- -# InterPlanetary Naming System +# IPNS Record and Protocol The InterPlanetary File System (IPFS) is powered by content-addressed data, which by nature is immutable: changing an object would change its hash, and consequently its address, making it a different object altogether. However, there are several use cases where we benefit from having mutable data. This is where the InterPlanetary Naming System (IPNS) gets into the equation. IPNS records provide cryptographically verifiable, mutable pointers to objects. diff --git a/src/meta/index.html b/src/meta/index.html new file mode 100644 index 000000000..7ffa96f37 --- /dev/null +++ b/src/meta/index.html @@ -0,0 +1,25 @@ +--- +title: Meta +description: | + Meta contains all the non-technical documents that conspire to make the standards + project work: what the core values are, what the governance model is, how to produce documents, + etc. +--- + +{% include 'header.html' %} + +
+
+
Code of Conduct
+
+ The code of conduct that all community participants are held to. +
+
Spec for Specs
+
+ Specifies the format and system used to create and maintain specifications for + the interplanetary stack. +
+
+
+ +{% include 'footer.html' %} diff --git a/template.html b/template.html new file mode 100644 index 000000000..e8f3f9410 --- /dev/null +++ b/template.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + ${body} + + From 3b910b1e7e9fe0f980efa27caaa99b652ef59a29 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 21 Mar 2023 18:39:38 +0100 Subject: [PATCH 05/13] =?UTF-8?q?chore:=20gateway-redirects-file=20?= =?UTF-8?q?=E2=86=92=20web-redirects-file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Making it clear these are Web redirects. --- http-gateways/REDIRECTS_FILE.md | 2 +- src/http-gateways/dnslink-gateway.md | 2 +- src/http-gateways/index.html | 2 +- src/http-gateways/subdomain-gateway.md | 2 +- .../{gateway-redirects-file.md => web-redirects-file.md} | 8 ++++---- src/index.html | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename src/http-gateways/{gateway-redirects-file.md => web-redirects-file.md} (93%) diff --git a/http-gateways/REDIRECTS_FILE.md b/http-gateways/REDIRECTS_FILE.md index 6ac0cd949..3cc26eced 100644 --- a/http-gateways/REDIRECTS_FILE.md +++ b/http-gateways/REDIRECTS_FILE.md @@ -1,3 +1,3 @@ # _redirects File Specification -Moved to https://specs.ipfs.tech/http-gateways/gateway-redirects-file/ +Moved to https://specs.ipfs.tech/http-gateways/web-redirects-file/ diff --git a/src/http-gateways/dnslink-gateway.md b/src/http-gateways/dnslink-gateway.md index a693ff169..20fbad1e1 100644 --- a/src/http-gateways/dnslink-gateway.md +++ b/src/http-gateways/dnslink-gateway.md @@ -88,4 +88,4 @@ Same as "HTTP Response" of :cite[path-gateway]. ## Redirects, single-page applications, and custom 404s DNSLink Gateway implementations are free to include `_redirects` file support -defined in :cite[gateway-redirects-file]. +defined in :cite[web-redirects-file]. diff --git a/src/http-gateways/index.html b/src/http-gateways/index.html index 842cfe063..8f1381e0a 100644 --- a/src/http-gateways/index.html +++ b/src/http-gateways/index.html @@ -43,7 +43,7 @@

Web

enable website hosting isolated per CID/name, while remaining compatible with web browsers relative pathing and the security model of the web. -
Redirects File
+
Redirects File
The Redirects File specification is an extension of the Subdomain Gateway and DNSLink Gateway specifications that enables URL redirects or rewrites by adding redirect rules to a0 file stored underneath the root CID of a web diff --git a/src/http-gateways/subdomain-gateway.md b/src/http-gateways/subdomain-gateway.md index 76e2f1d4c..d1781ea3a 100644 --- a/src/http-gateways/subdomain-gateway.md +++ b/src/http-gateways/subdomain-gateway.md @@ -252,4 +252,4 @@ From there, regular subdomain gateway logic applies. ## Redirects, single-page applications, and custom 404s Subdomain Gateway implementations are free to include `_redirects` file -support defined in :cite[gateway-redirects-file]. \ No newline at end of file +support defined in :cite[web-redirects-file]. \ No newline at end of file diff --git a/src/http-gateways/gateway-redirects-file.md b/src/http-gateways/web-redirects-file.md similarity index 93% rename from src/http-gateways/gateway-redirects-file.md rename to src/http-gateways/web-redirects-file.md index b862e6c83..57550d541 100644 --- a/src/http-gateways/gateway-redirects-file.md +++ b/src/http-gateways/web-redirects-file.md @@ -8,9 +8,9 @@ editors: github: lidel --- -# _redirects File Specification +# Web _redirects File Specification -The Redirects File specification is an extension of the Subdomain Gateway and DNSLink Gateway specifications. +The Web Redirects File specification is an extension of the Subdomain Gateway and DNSLink Gateway specifications. Developers can enable URL redirects or rewrites by adding redirect rules to a file named `_redirects` stored underneath the root CID of their web site. @@ -115,11 +115,11 @@ Rules MUST be evaluated in order, redirecting or rewriting using the first match ## No Forced Redirects -All redirect logic MUST only be evaluated if the requested path is not present in the DAG. This means that any performance impact associated with checking for the existence of a Redirects File or evaluating redirect rules will only be incurred for non-existent paths. +All redirect logic MUST only be evaluated if the requested path is not present in the DAG. This means that any performance impact associated with checking for the existence of a `_redirects` file or evaluating redirect rules will only be incurred for non-existent paths. # Error Handling -If the Redirects File exists but there is an error reading or parsing it, the errors MUST be returned to the user with a 500 HTTP status code. +If the `_redirects` file exists but there is an error reading or parsing it, the errors MUST be returned to the user with a 500 HTTP status code. # Security diff --git a/src/index.html b/src/index.html index b3fe0d367..0d99fffc8 100644 --- a/src/index.html +++ b/src/index.html @@ -93,7 +93,7 @@

HTTP Gateways

enable website hosting isolated per CID/name, while remaining compatible with web browsers relative pathing and the security model of the web.
-
Redirects File
+
Redirects File
The Redirects File specification is an extension of the Subdomain Gateway and DNSLink Gateway specifications that enables URL redirects or rewrites by adding redirect rules to a0 file stored underneath the root CID of a web From 1795a464749baaa57a7ad7e7d0df586daee853b5 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 21 Mar 2023 18:55:57 +0100 Subject: [PATCH 06/13] chore: adjust linter for ipseity --- .markdownlint.json | 3 +++ src/ipns/ipns-pubsub-router.md | 1 - src/meta/code-of-conduct.md | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.markdownlint.json b/.markdownlint.json index 886f33100..a2d4d0494 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,8 +1,11 @@ { "single-h1": false, + "ul-style": false, "no-bare-urls": false, + "no-duplicate-heading": false, "no-emphasis-as-header": false, "fenced-code-language": false, "blanks-around-lists": false, + "single-trailing-newline": false, "line-length": false } diff --git a/src/ipns/ipns-pubsub-router.md b/src/ipns/ipns-pubsub-router.md index cccb0e64d..980183d2d 100644 --- a/src/ipns/ipns-pubsub-router.md +++ b/src/ipns/ipns-pubsub-router.md @@ -12,7 +12,6 @@ xref: # IPNS PubSub Router - :ref[InterPlanetary Naming System (IPNS)] is a naming system responsible for the creating, reading and updating of mutable pointers to data. IPNS consists of a public/private asymmetric cryptographic key pair, a record type and a protocol. Part of the protocol involves a routing layer that is used for the distribution and discovery of new or updated IPNS records. diff --git a/src/meta/code-of-conduct.md b/src/meta/code-of-conduct.md index 10ff423b9..c15559fa8 100644 --- a/src/meta/code-of-conduct.md +++ b/src/meta/code-of-conduct.md @@ -124,6 +124,7 @@ Please see our [Code of Conduct Events Addendum](https://github.com/ipfs/communi This is a living document and may be updated from time to time. Please refer to the git history for this document to view the changes. ## Credit and License + This Code of Conduct is based on the [npm Code of Conduct](https://www.npmjs.com/policies/conduct) and the [CodeOfConduct4Lib](https://github.com/code4lib/code-of-conduct/blob/master/code_of_conduct.md), which itself is based on the [example policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment) from the [Geek Feminism wiki](http://geekfeminism.wikia.com/), created by the Ada Initiative and other volunteers. This document may be reused under a [Creative Commons Attribution-ShareAlike License](http://creativecommons.org/licenses/by-sa/4.0/). From e414200bfee3689de1300f427239492d62d40f94 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 22 Mar 2023 09:36:44 +0100 Subject: [PATCH 07/13] fix: ipns overview image --- src/css/specs.css | 4 ++++ {img => src/img}/ipns-overview.png | Bin src/ipns/ipns-record.md | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) rename {img => src/img}/ipns-overview.png (100%) diff --git a/src/css/specs.css b/src/css/specs.css index d509482b1..ee0c4404e 100644 --- a/src/css/specs.css +++ b/src/css/specs.css @@ -86,6 +86,10 @@ p { margin: 1rem 0; } +img { + max-width: 100%; +} + .header-wrapper { display: flex; align-items: baseline; diff --git a/img/ipns-overview.png b/src/img/ipns-overview.png similarity index 100% rename from img/ipns-overview.png rename to src/img/ipns-overview.png diff --git a/src/ipns/ipns-record.md b/src/ipns/ipns-record.md index ceab75c7d..642618097 100644 --- a/src/ipns/ipns-record.md +++ b/src/ipns/ipns-record.md @@ -226,7 +226,7 @@ legacy logic. ### Overview -![IPNS overview](../img/ipns-overview.png) +![IPNS overview](/img/ipns-overview.png) Taking into consideration a p2p network, each peer should be able to publish [IPNS records](#ipns-record) to the network, as well as to resolve the IPNS records published by other peers. From a83be9ef5db6c7e19a8e492a712a5000ed4be09b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 22 Mar 2023 10:19:43 +0100 Subject: [PATCH 08/13] chore: use npm install -g instead of npx --- Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 34e1f3133..0a645642c 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,14 @@ all: website clean: rm -rf ./out -website: clean - npx spec-generator@$(SPEC_GENERATOR_VER) -c .config.json +install: + npm install -g spec-generator@$(SPEC_GENERATOR_VER) -watch: clean - npx spec-generator@$(SPEC_GENERATOR_VER) -c .config.json -w +website: clean install + spec-generator -c .config.json + +watch: clean install + spec-generator -c .config.json -w superlinter: docker run --rm -e VALIDATE_ALL_CODEBASE=false -e RUN_LOCAL=true -e VALIDATE_MARKDOWN=true -e MARKDOWN_CONFIG_FILE=".markdownlint.json" -e LINTER_RULES_PATH="." -v $(shell pwd):/tmp/lint github/super-linter:v4 From 87a3bcf19e0e879c302840f8e141afd356c9b0dc Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 22 Mar 2023 11:07:32 +0100 Subject: [PATCH 09/13] feat: add canonical link Requires https://github.com/darobin/spec-generator/pull/1 --- template.html | 1 + 1 file changed, 1 insertion(+) diff --git a/template.html b/template.html index e8f3f9410..eaeef008c 100644 --- a/template.html +++ b/template.html @@ -4,6 +4,7 @@ + From 018914985da44f682816b89511e22bd384d129d3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 24 Mar 2023 00:14:41 +0100 Subject: [PATCH 10/13] chore: spec-generator@v1.1.3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0a645642c..8fc4376e3 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SPEC_GENERATOR_VER=v1.1.2 +SPEC_GENERATOR_VER=v1.1.3 all: website From 2ff5e989e011fbbef4b44ab9c775d5c23b1459f5 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 24 Mar 2023 08:53:49 +0100 Subject: [PATCH 11/13] chore: trigger build From f5bf30f0125cfa61a0baecafb099bea3ff59792c Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 24 Mar 2023 09:50:16 +0100 Subject: [PATCH 12/13] feat: canonical for everyone --- src/_includes/head.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_includes/head.html b/src/_includes/head.html index dfa3a3ff6..3aa1b9954 100644 --- a/src/_includes/head.html +++ b/src/_includes/head.html @@ -4,6 +4,7 @@ {% if title != 'Home' %}{{ title }} | {% endif %}IPFS Standards + From 396f8c09bfcb3e4c5869b7adb11d210cf1b24010 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Sat, 25 Mar 2023 09:16:06 +0100 Subject: [PATCH 13/13] chore: update spec-generator version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8fc4376e3..fe123f520 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SPEC_GENERATOR_VER=v1.1.3 +SPEC_GENERATOR_VER=v1.1.4 all: website