Skip to content

Commit 8330f40

Browse files
committed
fix(IPIP-0523): expand rationale and update specs
- clarify format is URL query param, Accept is HTTP header - expand Compatibility with HTTP caching rationale - add Security and Alternatives sections - update precedence rule in both path-gateway and trustless-gateway
1 parent 824cf89 commit 8330f40

File tree

2 files changed

+89
-27
lines changed

2 files changed

+89
-27
lines changed

src/http-gateways/trustless-gateway.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,15 @@ Same as [`format`](https://specs.ipfs.tech/http-gateways/path-gateway/#format-re
128128
- `format=car``application/vnd.ipld.car`
129129
- `format=ipns-record``application/vnd.ipfs.ipns-record`
130130

131+
When both `Accept` HTTP header and `format` query parameter are present,
132+
`format` SHOULD take precedence.
133+
131134
:::note
132135

133136
A Client SHOULD include the `format` query parameter in the request URL, in
134137
addition to the `Accept` header. This provides the best interoperability and
135138
ensures consistent HTTP cache behavior across various gateway implementations.
136139

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-
142140
:::
143141

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

src/ipips/ipip-0523.md

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
---
2-
title: "IPIP-0523: Prefer format request param over Accept header"
2+
title: "IPIP-0523: Prefer format param over Accept header"
33
date: 2025-11-26
44
ipip: proposal
55
editors:
66
- name: Alex Potsides
77
github: achingbrain
88
url: https://achingbrain.net
99
affiliation:
10-
name: Shipyard
11-
url: https://ipshipyard.com
10+
name: Shipyard
11+
url: https://ipshipyard.com
12+
- name: Marcin Rataj
13+
github: lidel
14+
affiliation:
15+
name: Shipyard
16+
url: https://ipshipyard.com
1217
relatedIssues:
1318
- https://github.com/ipfs/specs/issues/521
1419
order: 523
@@ -17,51 +22,110 @@ tags: ['ipips']
1722

1823
## Summary
1924

20-
Prefer the `format` request param over the Accept header
25+
Prefer the `?format=` URL query parameter over the `Accept:` HTTP request header.
2126

2227
## Motivation
2328

24-
The [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept)
25-
header can be sent with an HTTP request to provide a prioritized list of
26-
response formats the client will accept for a given resource.
29+
The [`Accept`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept)
30+
HTTP request header can be sent with an HTTP request to provide a prioritized
31+
list of response formats the client will accept for a given resource.
2732

28-
The [format](https://specs.ipfs.tech/http-gateways/path-gateway/#format-request-query-parameter)
29-
request query parameter can also be sent to an IPFS HTTP Gateway to provide the
33+
The [`format`](https://specs.ipfs.tech/http-gateways/path-gateway/#format-request-query-parameter)
34+
URL query parameter can also be sent to an IPFS HTTP Gateway to provide the
3035
same information, and is typically done when sending an HTTP header is difficult
31-
or impractical, for example in a browser.
36+
or impractical, for example when using a browser address bar.
3237

3338
The existing [Path Gateway](https://specs.ipfs.tech/http-gateways/path-gateway/#format-request-query-parameter) and [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/#format-request-query-parameter) specs say:
3439

3540
> When both the Accept header and format parameter are present, a specific Accept value (e.g., application/vnd.ipld.raw) SHOULD take precedence over format.
3641
37-
This makes it impossible for browsers to use the `format` request query
38-
parameter, since they will always send an `Accept` header which would then cause
39-
the `format` request query parameter to be ignored.
42+
This makes it impossible for browsers to use the `format` URL query parameter,
43+
since they will always send an `Accept` HTTP header which would then cause
44+
the `format` URL query parameter to be ignored.
4045

4146
## Detailed design
4247

43-
The priority of `format` vs `Accept` should be reversed, so as to always prefer
44-
`format` over `Accept` if it is present.
48+
The priority of the `format` URL query parameter vs the `Accept` HTTP header is
49+
reversed in both :cite[path-gateway] and :cite[trustless-gateway] specs: the
50+
`format` URL query parameter SHOULD always take precedence over the `Accept`
51+
HTTP header when both are present.
52+
53+
This simplifies the specification by removing the previous wildcard exception
54+
logic. Implementations no longer need to distinguish between specific `Accept`
55+
header values (e.g., `application/vnd.ipld.raw`) and wildcards (e.g., `*/*`)
56+
when determining precedence.
4557

4658
## Design rationale
4759

48-
Browsers will always send an `Accept` header that contains specific values so it
49-
cannot be allowed to take priority over the `format` request query parameter.
60+
Browsers will always send an `Accept` HTTP header that contains specific values
61+
so it cannot be allowed to take priority over the `format` URL query parameter.
5062

5163
### User benefit
5264

53-
Users will be able to use the `format` request query parameter to control the
65+
Users will be able to use the `format` URL query parameter to control the
5466
response type of requests made from browser address bars.
5567

5668
### Compatibility
5769

58-
This is a breaking change.
70+
This change simplifies precedence rules by making the `format` URL query
71+
parameter always take priority over the `Accept` HTTP header when both are
72+
present.
73+
74+
In practice, this is largely compatible with existing web browser use cases.
75+
Browsers send `Accept` HTTP headers with wildcards (e.g., `*/*` or
76+
`text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`), and
77+
the previous spec already treated wildcards as non-specific, allowing `format`
78+
to take precedence. This means browser address bar usage with `?format=` was
79+
already working as expected.
80+
81+
In recent years we also realized that HTTP cache implementations are often
82+
flawed, and virtually all HTTP clients add explicit `?format=` anyway to ensure
83+
a unique HTTP cache key is used for each URL. This provides extra protection
84+
from poorly written or configured software and CDNs that comingle different
85+
response types under the same cache key (e.g., deserialized response, raw block,
86+
and CAR being cached and returned based on what was requested and cached first).
87+
By prioritizing `?format=` we ensure deterministic HTTP caching behavior across
88+
the ecosystem, making it easier to deploy and reason about HTTP trustless
89+
gateways.
90+
91+
The actual breakage is limited to edge cases where a client sends both a
92+
specific `Accept` HTTP header (e.g., `Accept: application/vnd.ipld.raw`) and a
93+
different `format` URL query parameter (e.g., `?format=car`). Previously, the
94+
specific `Accept` header value would win; now `format` wins. This scenario is
95+
rare in practice and arguably represents a client misconfiguration.
96+
97+
The primary impact is on [gateway-conformance](https://github.com/ipfs/gateway-conformance/)
98+
tests, which explicitly test the old precedence behavior. A minor version bump
99+
of gateway-conformance is required to update these tests.
100+
101+
### Security
102+
103+
This change has no security implications. It only affects which response format
104+
is returned when a client sends conflicting format preferences, and does not
105+
change authentication, authorization, or data integrity behaviors.
106+
107+
### Alternatives
108+
109+
**Keep status quo with wildcard exception**: The previous spec already had a
110+
carve-out where wildcards (e.g., `*/*`, `application/*`) in the `Accept` HTTP
111+
header did not take precedence over the `format` URL query parameter. This meant
112+
browser use cases were effectively supported, since browsers include wildcards
113+
in their default `Accept` HTTP headers.
114+
115+
This alternative was rejected because:
116+
117+
1. The wildcard exception adds implementation complexity
118+
2. The resulting behavior is harder to reason about and document
119+
3. The simpler rule ("format always wins") is easier to understand and implement
120+
4. Real-world browser use cases work identically under both rules
59121

60122
## Test fixtures
61123

62-
Implementers can either write own test that prefers the format query param over
63-
any present Accept header, or run the [gateway-conformance](https://github.com/ipfs/gateway-conformance/)
64-
test suite, which includes tests for this scenario since [gateway-conformance/pull/252](https://github.com/ipfs/gateway-conformance/pull/252).
124+
Implementers can either write own test that prefers the `format` URL query
125+
parameter over any present `Accept` HTTP header, or run the
126+
[gateway-conformance](https://github.com/ipfs/gateway-conformance/) test suite,
127+
which includes tests for this scenario since
128+
[gateway-conformance/pull/252](https://github.com/ipfs/gateway-conformance/pull/252).
65129

66130
### Copyright
67131

0 commit comments

Comments
 (0)