From db6d950c5f07448cc1af764f74679b396cfc3325 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 7 Mar 2024 12:55:39 +0100 Subject: [PATCH 1/4] routing: add missing response headers --- src/routing/http-routing-v1.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/routing/http-routing-v1.md b/src/routing/http-routing-v1.md index 9c60c7fc2..d4921cb5e 100644 --- a/src/routing/http-routing-v1.md +++ b/src/routing/http-routing-v1.md @@ -71,6 +71,13 @@ This API uses a standard version prefix in the path, such as `/v1/...`. If a bac - `404` (Not Found): must be returned if no matching records are found. - `422` (Unprocessable Entity): request does not conform to schema or semantic constraints. +#### Response Headers + +- `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). +- `Last-Modified`: the timestamp of the resolution. +- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses that do whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). +- `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. + #### Response Body ```json @@ -108,6 +115,13 @@ represented as a CIDv1 encoded with `libp2p-key` codec. - `404` (Not Found): must be returned if no matching records are found. - `422` (Unprocessable Entity): request does not conform to schema or semantic constraints. +#### Response Headers + +- `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). +- `Last-Modified`: the timestamp of the resolution. +- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses that do whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). +- `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. + #### Response Body ```json @@ -148,7 +162,9 @@ Each object in the `Peers` list is a record conforming to the [Peer Schema](#pee #### Response Headers - `Etag`: a globally unique opaque string used for HTTP caching. MUST be derived from the protobuf record returned in the body. -- `Cache-Control: max-age={TTL}`: cache TTL returned with :ref[IPNS Record] that has `IpnsEntry.data[TTL] > 0`. When present, SHOULD match the TTL value from the record. When record was not found (HTTP 404) or has no TTL (value is `0`), implementation SHOULD default to `max-age=60`. +- `Cache-Control: public, max-age={TTL}`: cache TTL returned with :ref[IPNS Record] that has `IpnsEntry.data[TTL] > 0`. When present, SHOULD match the TTL value from the record. When record was not found (HTTP 404) or has no TTL (value is `0`), implementation SHOULD default to `max-age=60`. Implementations MAY also include other derivatives, such as `stale-while-revalidate` and `stale-if-error`. +- `Expires: {SIGNATURE_EXPIRATION}`: header with time when the signature expires. +- `Last-Modified`: with the timestamp of the resolution. #### Response Body From d4eb5d5f14a823581aec3bd2ec4b78ef9adc4c54 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 18 Mar 2024 23:26:03 +0100 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> --- src/routing/http-routing-v1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routing/http-routing-v1.md b/src/routing/http-routing-v1.md index d4921cb5e..59b7951f5 100644 --- a/src/routing/http-routing-v1.md +++ b/src/routing/http-routing-v1.md @@ -75,7 +75,7 @@ This API uses a standard version prefix in the path, such as `/v1/...`. If a bac - `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). - `Last-Modified`: the timestamp of the resolution. -- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses that do whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). +- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). - `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. #### Response Body @@ -119,7 +119,7 @@ represented as a CIDv1 encoded with `libp2p-key` codec. - `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). - `Last-Modified`: the timestamp of the resolution. -- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses that do whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). +- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). - `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. #### Response Body From 415158fcde93e723bc9b78f1e160d57719b9663d Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 22 Mar 2024 20:30:32 +0100 Subject: [PATCH 3/4] chore: editorial clarifications --- src/routing/http-routing-v1.md | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/routing/http-routing-v1.md b/src/routing/http-routing-v1.md index 59b7951f5..d515852a7 100644 --- a/src/routing/http-routing-v1.md +++ b/src/routing/http-routing-v1.md @@ -4,7 +4,7 @@ description: > Delegated routing is a mechanism for IPFS implementations to use for offloading content routing, peer routing and naming to another process/server. This specification describes an HTTP API for delegated routing of content, peers, and IPNS. -date: 2023-08-31 +date: 2024-03-22 maturity: reliable editors: - name: Gus Eggert @@ -74,8 +74,12 @@ This API uses a standard version prefix in the path, such as `/v1/...`. If a bac #### Response Headers - `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). -- `Last-Modified`: the timestamp of the resolution. -- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). +- `Last-Modified`: the timestamp of the resolution, allowing CDNs and load balancers to support inexpensive update checks via `If-Modified-Since` +- `Cache-Control: public, max-age={ttl}, public, stale-while-revalidate={max-ttl}, stale-if-error={max-ttl}`: meaningful cache TTL returned with the response. + - The `max-age` SHOULD be shorter for responses whose resolution ended in no results (e.g. 15 seconds), + and longer for responses that have results (e.g. 5 minutes). + - Implementations SHOULD include `max-ttl`, set to the maximum cache window of the underlying routing system. + For example, if Amino DHT results are returned, `stale-while-revalidate` SHOULD be set to `172800` (48h, which at the time of writing this specification, is the provider record expiration window). - `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. #### Response Body @@ -118,8 +122,12 @@ represented as a CIDv1 encoded with `libp2p-key` codec. #### Response Headers - `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). -- `Last-Modified`: the timestamp of the resolution. -- `Cache-Control: public, max-age={TTL}`: cache TTL returned with the response. When present, it SHOULD be short for responses whose resolution ended in no results (e.g. 15 seconds), and MAY be longer for responses that have results (e.g. 5 minutes). +- `Last-Modified`: the timestamp of the resolution, allowing CDNs and load balancers to support inexpensive update checks via `If-Modified-Since` +- `Cache-Control: public, max-age={ttl}, public, stale-while-revalidate={max-ttl}, stale-if-error={max-ttl}`: meaningful cache TTL returned with the response. + - When present, `ttl` SHOULD be shorter for responses whose resolution ended in no results (e.g. 15 seconds), + and longer for responses that have results (e.g. 5 minutes). + - Implementations SHOULD include `max-ttl`, set to the maximum cache window of the underlying routing system. + For example, if Amino DHT results are returned, `stale-while-revalidate` SHOULD be set to `172800` (48h, which at the time of writing this specification, is the provider record expiration window). - `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. #### Response Body @@ -162,9 +170,12 @@ Each object in the `Peers` list is a record conforming to the [Peer Schema](#pee #### Response Headers - `Etag`: a globally unique opaque string used for HTTP caching. MUST be derived from the protobuf record returned in the body. -- `Cache-Control: public, max-age={TTL}`: cache TTL returned with :ref[IPNS Record] that has `IpnsEntry.data[TTL] > 0`. When present, SHOULD match the TTL value from the record. When record was not found (HTTP 404) or has no TTL (value is `0`), implementation SHOULD default to `max-age=60`. Implementations MAY also include other derivatives, such as `stale-while-revalidate` and `stale-if-error`. +- `Cache-Control: public, max-age={ttl}, public, stale-while-revalidate={sig-ttl}, stale-if-error={sig-ttl}`: meaningful cache TTL returned with :ref[IPNS Record] + - The `max-age` value in seconds SHOULD match duration from `IpnsEntry.data[TTL]`, if present and bigger than `0`. Otherwise, implementation SHOULD default to `max-age=60`. + - Implementations SHOULD include `sig-ttl`, set to the remaining number of seconds the returned IPNS Record is valid. - `Expires: {SIGNATURE_EXPIRATION}`: header with time when the signature expires. -- `Last-Modified`: with the timestamp of the resolution. +- `Last-Modified`: the timestamp of cacheable resolution, allowing CDNs and load balancers to support inexpensive update checks via `If-Modified-Since` +- `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. #### Response Body From 814166dfe7efac6a285705d5c512ee3f8ff426cd Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 22 Mar 2024 20:42:21 +0100 Subject: [PATCH 4/4] define HTTP-date timestamp --- src/routing/http-routing-v1.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routing/http-routing-v1.md b/src/routing/http-routing-v1.md index d515852a7..edd30cea3 100644 --- a/src/routing/http-routing-v1.md +++ b/src/routing/http-routing-v1.md @@ -74,7 +74,7 @@ This API uses a standard version prefix in the path, such as `/v1/...`. If a bac #### Response Headers - `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). -- `Last-Modified`: the timestamp of the resolution, allowing CDNs and load balancers to support inexpensive update checks via `If-Modified-Since` +- `Last-Modified`: an HTTP-date timestamp ([RFC9110, Section 5.6.7](https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7)) of the resolution, allowing HTTP proxies and CDNs to support inexpensive update checks via `If-Modified-Since` - `Cache-Control: public, max-age={ttl}, public, stale-while-revalidate={max-ttl}, stale-if-error={max-ttl}`: meaningful cache TTL returned with the response. - The `max-age` SHOULD be shorter for responses whose resolution ended in no results (e.g. 15 seconds), and longer for responses that have results (e.g. 5 minutes). @@ -122,7 +122,7 @@ represented as a CIDv1 encoded with `libp2p-key` codec. #### Response Headers - `Content-Type`: the content type of this response, which MUST be `application/json` or `application/x-ndjson` (see [streaming](#streaming)). -- `Last-Modified`: the timestamp of the resolution, allowing CDNs and load balancers to support inexpensive update checks via `If-Modified-Since` +- `Last-Modified`: an HTTP-date timestamp ([RFC9110, Section 5.6.7](https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7)) of the resolution, allowing HTTP proxies and CDNs to support inexpensive update checks via `If-Modified-Since` - `Cache-Control: public, max-age={ttl}, public, stale-while-revalidate={max-ttl}, stale-if-error={max-ttl}`: meaningful cache TTL returned with the response. - When present, `ttl` SHOULD be shorter for responses whose resolution ended in no results (e.g. 15 seconds), and longer for responses that have results (e.g. 5 minutes). @@ -173,8 +173,8 @@ Each object in the `Peers` list is a record conforming to the [Peer Schema](#pee - `Cache-Control: public, max-age={ttl}, public, stale-while-revalidate={sig-ttl}, stale-if-error={sig-ttl}`: meaningful cache TTL returned with :ref[IPNS Record] - The `max-age` value in seconds SHOULD match duration from `IpnsEntry.data[TTL]`, if present and bigger than `0`. Otherwise, implementation SHOULD default to `max-age=60`. - Implementations SHOULD include `sig-ttl`, set to the remaining number of seconds the returned IPNS Record is valid. -- `Expires: {SIGNATURE_EXPIRATION}`: header with time when the signature expires. -- `Last-Modified`: the timestamp of cacheable resolution, allowing CDNs and load balancers to support inexpensive update checks via `If-Modified-Since` +- `Expires:`: an HTTP-date timestamp ([RFC9110, Section 5.6.7](https://www.rfc-editor.org/rfc/rfc9110#section-5.6.7)) when the validity of IPNS Record expires (if `ValidityType=0`, when signature expires) +- `Last-Modified`: an HTTP-date timestamp of when cacheable resolution occured: allows HTTP proxies and CDNs to support inexpensive update checks via `If-Modified-Since` - `Vary: Accept`: allows intermediate caches to play nicely with the different possible content types. #### Response Body