Skip to content

Commit 110bf46

Browse files
authored
Merge pull request #517 from ipfs/rvagg/trustless-update
docs(trustless): clarify streaming gateway behavior & response headers
2 parents bb946b4 + 0ba155e commit 110bf46

File tree

2 files changed

+100
-16
lines changed

2 files changed

+100
-16
lines changed

src/http-gateways/path-gateway.md

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,23 @@ description: >
44
The comprehensive low-level HTTP Gateway enables the integration of IPFS
55
resources into the HTTP stack through /ipfs and /ipns namespaces, supporting
66
both deserialized and verifiable response types.
7-
date: 2024-04-17
7+
date: 2025-10-13
88
maturity: reliable
99
editors:
1010
- name: Marcin Rataj
1111
github: lidel
1212
url: https://lidel.org/
1313
affiliation:
14-
name: Protocol Labs
15-
url: https://protocol.ai/
14+
name: Shipyard
15+
url: https://ipshipyard.com
16+
former_editors:
17+
- name: Henrique Dias
18+
github: hacdias
19+
url: https://hacdias.com/
20+
affiliation:
21+
name: Shipyard
22+
url: https://ipshipyard.com
23+
thanks:
1624
- name: Adrian Lanzafame
1725
github: lanzafame
1826
affiliation:
@@ -28,12 +36,6 @@ editors:
2836
affiliation:
2937
name: Protocol Labs
3038
url: https://protocol.ai/
31-
- name: Henrique Dias
32-
github: hacdias
33-
url: https://hacdias.com/
34-
affiliation:
35-
name: Protocol Labs
36-
url: https://protocol.ai/
3739
xref:
3840
- url
3941
- trustless-gateway
@@ -332,6 +334,11 @@ Gateways MUST use 404 to signal that content is not available, particularly
332334
when the gateway is [non recursive](#recursive-vs-non-recursive-gateways), and only provides access to a known
333335
dataset, so that it can assess that the requested content is not part of it.
334336

337+
NOTE: Gateways MUST return 404 for missing root blocks. However, for streaming
338+
responses (such as CAR), once HTTP 200 OK status is sent, gateways cannot
339+
change it. If a child block is missing during streaming, the gateway SHOULD
340+
terminate the stream. Clients MUST verify response completeness.
341+
335342
### `410` Gone
336343

337344
Error to indicate that request was formally correct, but this specific Gateway
@@ -639,6 +646,10 @@ Indicates the original, requested content path before any path resolution and tr
639646

640647
Example: `X-Ipfs-Path: /ipns/k2..ul6/subdir/file.txt`
641648

649+
This header SHOULD be returned with deserialized responses.
650+
Implementations MAY omit it with trustless response types
651+
(`application/vnd.ipld.raw` and `application/vnd.ipld.car`).
652+
642653
### `X-Ipfs-Roots` (response header)
643654

644655
Used for HTTP caching.
@@ -668,6 +679,15 @@ NOTE: while the first CID will change every time any article is changed,
668679
the last root (responsible for specific article or a subdirectory) may not
669680
change at all, allowing for smarter caching beyond what standard Etag offers.
670681

682+
This header SHOULD be returned with deserialized responses.
683+
Implementations MAY omit it with trustless response types
684+
(`application/vnd.ipld.raw` and `application/vnd.ipld.car`).
685+
686+
NOTE: Gateways that stream responses (e.g., CAR) without pre-resolving the
687+
entire path MAY only include the root CID for simple `/ipfs/{cid}` requests, or
688+
MAY omit this header for path requests where intermediate CIDs are not known
689+
when headers are sent.
690+
671691
### `X-Content-Type-Options` (response header)
672692

673693
Optional, present in certain response types:

src/http-gateways/trustless-gateway.md

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@ description: >
44
The minimal subset of HTTP Gateway response types facilitates data retrieval
55
via CID and ensures integrity verification, all while eliminating the need to
66
trust the gateway itself.
7-
date: 2025-03-06
7+
date: 2025-10-13
88
maturity: reliable
99
editors:
1010
- name: Marcin Rataj
1111
github: lidel
1212
affiliation:
1313
name: Shipyard
1414
url: https://ipshipyard.com
15-
- name: Henrique Dias
16-
github: hacdias
1715
- name: Héctor Sanjuán
1816
github: hsanjuan
1917
affiliation:
2018
name: Shipyard
2119
url: https://ipshipyard.com
20+
former_editors:
21+
- name: Henrique Dias
22+
github: hacdias
23+
thanks:
24+
- name: Rod Vagg
25+
github: rvagg
2226
xref:
2327
- url
2428
- path-gateway
@@ -39,7 +43,7 @@ The minimal implementation means:
3943
- for raw blocks:
4044
- data is requested by CID, only supported path is `/ipfs/{cid}`
4145
- no path traversal or recursive resolution
42-
- for CAR files:
46+
- for CARs:
4347
- the pathing behavior is identical to :cite[path-gateway]
4448

4549
# HTTP API
@@ -108,6 +112,13 @@ gateway implementations.
108112

109113
:::
110114

115+
### `Cache-Control: only-if-cached` (request header)
116+
117+
Trustless gateways, particularly non-recursive ones serving from a local block
118+
store, are well-suited for :cite[path-gateway]'s `Cache-Control: only-if-cached`
119+
request header. When received, gateway SHOULD return HTTP 412 if the root block
120+
is not immediately available.
121+
111122
## Request Query Parameters
112123

113124
### :dfn[`format`] (request query parameter)
@@ -123,15 +134,19 @@ A Client SHOULD include the `format` query parameter in the request URL, in
123134
addition to the `Accept` header. This provides the best interoperability and
124135
ensures consistent HTTP cache behavior across various gateway implementations.
125136

137+
When both the `Accept` header and `format` parameter are present, a specific
138+
`Accept` value (e.g., `application/vnd.ipld.raw`) SHOULD take precedence over
139+
`format`. Wildcards (e.g., `*/*`, `application/*`) are not specific and do not
140+
take precedence (as specified in :cite[path-gateway]).
141+
126142
:::
127143

128144
### :dfn[`dag-scope`] (request query parameter)
129145

130146
Optional, `dag-scope=(block|entity|all)` with default value `all`, only available for CAR requests.
131147

132148
Describes the shape of the DAG fetched the terminus of the specified path whose blocks
133-
are included in the returned CAR file after the blocks required to traverse
134-
path segments.
149+
are included in the returned CAR stream after the blocks required to traverse path segments.
135150

136151
- `block` - Only the root block at the end of the path is returned after blocks
137152
required to verify the specified path segments.
@@ -248,6 +263,34 @@ Below MUST be implemented **in addition** to "HTTP Response" of
248263
:cite[path-gateway], with special attention to the "Response Status Codes" and
249264
the "Recursive vs non-recursive gateways" sections.
250265

266+
## Response Status Codes
267+
268+
Trustless Gateways MUST follow the response status codes defined in :cite[path-gateway], including:
269+
270+
### `404 Not Found`
271+
272+
A Trustless Gateway MUST return `404 Not Found` when the **root block** (the CID in the request path) is not available in the gateway's storage.
273+
274+
This applies to:
275+
- HEAD requests for any CID
276+
- GET requests for raw blocks (`application/vnd.ipld.raw`)
277+
- GET requests for CAR streams (`application/vnd.ipld.car`) when the root block is missing
278+
279+
For non-recursive Trustless Gateways (such as those serving from a local block store), this definitively signals that the requested content is not part of the gateway's dataset.
280+
281+
### Streaming and Missing Child Blocks
282+
283+
For CAR responses, once a gateway begins streaming (after successfully loading the root block), it has committed to HTTP `200 OK`. If a child block is encountered as missing during DAG traversal:
284+
285+
- The gateway SHOULD terminate the stream (potentially with an incomplete CAR)
286+
- Clients MUST verify CAR completeness and handle incomplete streams as retrieval failures
287+
288+
This follows the streaming principle stated in the [`entity-bytes`](#entity-bytes-request-query-parameter) section above.
289+
290+
### `500 Internal Server Error`
291+
292+
A Trustless Gateway SHOULD return `500 Internal Server Error` only for genuine server errors, not for content unavailability. Examples include storage backend failures, resource exhaustion, or unexpected internal errors.
293+
251294
## Response Headers
252295

253296
### `Content-Type` (response header)
@@ -264,12 +307,33 @@ If a CAR stream was requested:
264307

265308
MUST be returned and set to `attachment` to ensure requested bytes are not rendered by a web browser.
266309

310+
When no custom `filename` is provided:
311+
- CAR responses should use `filename="<cid>.car"`
312+
- Raw block responses should use `filename="<cid>.bin"`
313+
267314
### `Content-Location` (response header)
268315

269316
Same as in :cite[path-gateway], SHOULD be returned when Trustless Gateway
270317
supports more than a single response format and the `format` query parameter is
271318
missing or does not match well-known format from `Accept` header.
272319

320+
### `Etag` (response header)
321+
322+
MUST be returned and follow the recommendations in :cite[path-gateway].
323+
324+
:::note
325+
326+
**Implementation Variance**: Etag generation for CAR responses is
327+
implementation-specific. Different gateways may generate different Etags for
328+
identical requests due to variations in what parameters are included (e.g.,
329+
`order`, `dups`) and how they are encoded in the Etag calculation.
330+
331+
As a result, `If-None-Match` conditional requests may not work across different
332+
gateway implementations. Clients SHOULD NOT assume Etags are portable between
333+
gateways.
334+
335+
:::
336+
273337
# Block Responses (application/vnd.ipld.raw)
274338

275339
An opaque bytes matching the requested block CID
@@ -466,7 +530,7 @@ that the endpoint corresponds to a trustless gateway.
466530
For block requests (signaled by `?format=raw` and `Accept: application/vnd.ipld.raw`), when supported, it MUST return `200 OK`
467531
and an empty body.
468532

469-
For CAR requests (signaled by `?format=car` and `Accept: application/vnd.ipld.car`), when supported, it MUST return `200 OK` and a valid CAR file with CAR Header `roots` set to `bafkqaaa`. Identity block MAY be skipped in the CAR Data section.
533+
For CAR requests (signaled by `?format=car` and `Accept: application/vnd.ipld.car`), when supported, it MUST return `200 OK` and a valid CAR with CAR Header `roots` set to `bafkqaaa`. Identity block MAY be skipped in the CAR Data section.
470534

471535
This specific identity CID is special for probing. Other random
472536
identity CIDs MAY not be handled.

0 commit comments

Comments
 (0)