Skip to content

Commit 60e5668

Browse files
committed
feat(gateway): IPIP-0524 Gateway.AllowCodecConversion config option
Wire up boxo's AllowCodecConversion config to control codec conversion behavior per IPIP-0524. When false (default), the gateway returns 406 Not Acceptable if the requested format doesn't match the block's codec. Clients should fetch raw blocks (`?format=raw`) and convert client-side. Ref: ipfs/specs#524 Ref: ipfs/boxo#1077 Ref: ipfs/gateway-conformance#254
1 parent d29c0b9 commit 60e5668

File tree

11 files changed

+58
-14
lines changed

11 files changed

+58
-14
lines changed

.github/workflows/gateway-conformance.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
steps:
4242
# 1. Download the gateway-conformance fixtures
4343
- name: Download gateway-conformance fixtures
44-
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.8
44+
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@376504c31aae5e2d47c23cb1e131a7573a7e3a7f # TODO: switch to release tag once https://github.com/ipfs/gateway-conformance/pull/254 ships
4545
with:
4646
output: fixtures
4747

@@ -93,7 +93,7 @@ jobs:
9393

9494
# 6. Run the gateway-conformance tests
9595
- name: Run gateway-conformance tests
96-
uses: ipfs/gateway-conformance/.github/actions/test@v0.8
96+
uses: ipfs/gateway-conformance/.github/actions/test@376504c31aae5e2d47c23cb1e131a7573a7e3a7f # TODO: switch to release tag once https://github.com/ipfs/gateway-conformance/pull/254 ships
9797
with:
9898
gateway-url: http://127.0.0.1:8080
9999
subdomain-url: http://localhost:8080
@@ -127,7 +127,7 @@ jobs:
127127
steps:
128128
# 1. Download the gateway-conformance fixtures
129129
- name: Download gateway-conformance fixtures
130-
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@v0.8
130+
uses: ipfs/gateway-conformance/.github/actions/extract-fixtures@376504c31aae5e2d47c23cb1e131a7573a7e3a7f # TODO: switch to release tag once https://github.com/ipfs/gateway-conformance/pull/254 ships
131131
with:
132132
output: fixtures
133133

@@ -199,7 +199,7 @@ jobs:
199199

200200
# 9. Run the gateway-conformance tests over libp2p
201201
- name: Run gateway-conformance tests over libp2p
202-
uses: ipfs/gateway-conformance/.github/actions/test@v0.8
202+
uses: ipfs/gateway-conformance/.github/actions/test@376504c31aae5e2d47c23cb1e131a7573a7e3a7f # TODO: switch to release tag once https://github.com/ipfs/gateway-conformance/pull/254 ships
203203
with:
204204
gateway-url: http://127.0.0.1:8092
205205
args: --specs "trustless-gateway,-trustless-ipns-gateway" -skip 'TestGatewayCar/GET_response_for_application/vnd.ipld.car/Header_Content-Length'

config/gateway.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const (
1010
DefaultDisableHTMLErrors = false
1111
DefaultExposeRoutingAPI = true
1212
DefaultDiagnosticServiceURL = "https://check.ipfs.network"
13+
DefaultAllowCodecConversion = false
1314

1415
// Gateway limit defaults from boxo
1516
DefaultRetrievalTimeout = gateway.DefaultRetrievalTimeout
@@ -72,6 +73,12 @@ type Gateway struct {
7273
// be overridden per FQDN in PublicGateways.
7374
DeserializedResponses Flag
7475

76+
// AllowCodecConversion enables automatic conversion between codecs when
77+
// the requested format differs from the block's native codec (e.g.,
78+
// converting dag-pb or dag-cbor to dag-json). When disabled, the gateway
79+
// returns 406 Not Acceptable for codec mismatches per IPIP-0524.
80+
AllowCodecConversion Flag
81+
7582
// DisableHTMLErrors disables pretty HTML pages when an error occurs. Instead, a `text/plain`
7683
// page will be sent with the raw error message.
7784
DisableHTMLErrors Flag

core/corehttp/gateway.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ func getGatewayConfig(n *core.IpfsNode) (gateway.Config, map[string][]string, er
268268
// Initialize gateway configuration, with empty PublicGateways, handled after.
269269
gwCfg := gateway.Config{
270270
DeserializedResponses: cfg.Gateway.DeserializedResponses.WithDefault(config.DefaultDeserializedResponses),
271+
AllowCodecConversion: cfg.Gateway.AllowCodecConversion.WithDefault(config.DefaultAllowCodecConversion),
271272
DisableHTMLErrors: cfg.Gateway.DisableHTMLErrors.WithDefault(config.DefaultDisableHTMLErrors),
272273
NoDNSLink: cfg.Gateway.NoDNSLink,
273274
PublicGateways: map[string]*gateway.PublicGateway{},

docs/changelogs/v0.40.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ This release was brought to you by the [Shipyard](https://ipshipyard.com/) team.
1111
- [Overview](#overview)
1212
- [🔦 Highlights](#-highlights)
1313
- [Routing V1 HTTP API now exposed by default](#routing-v1-http-api-now-exposed-by-default)
14-
- [Track total size when adding pins](#track-total-size-when-adding-pins]
14+
- [Track total size when adding pins](#track-total-size-when-adding-pins)
15+
- [IPIP-0524: Gateway codec conversion disabled by default](#ipip-0524-gateway-codec-conversion-disabled-by-default)
1516
- [📝 Changelog](#-changelog)
1617
- [👨‍👩‍👧‍👦 Contributors](#-contributors)
1718

@@ -32,6 +33,18 @@ Example output:
3233
Fetched/Processed 336 nodes (83 MB)
3334
```
3435

36+
#### IPIP-0524: Gateway codec conversion disabled by default
37+
38+
Codec conversion is now disabled by default per [IPIP-0524](https://github.com/ipfs/specs/pull/524).
39+
Requests for a format that differs from the block's codec will return `406 Not Acceptable`.
40+
41+
**Migration**: Clients should fetch raw blocks (`?format=raw` or `Accept: application/vnd.ipld.raw`)
42+
and convert client-side using libraries like [@helia/verified-fetch](https://www.npmjs.com/package/@helia/verified-fetch).
43+
44+
This change removes gateways from a gatekeeping role: new codecs can now be adopted by clients
45+
immediately without waiting for gateway operator updates. Set [`Gateway.AllowCodecConversion`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewayallowcodecconversion)
46+
to `true` to restore previous behavior.
47+
3548
### 📝 Changelog
3649

3750
### 👨‍👩‍👧‍👦 Contributors

docs/config.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ config file at runtime.
6363
- [`Gateway.NoFetch`](#gatewaynofetch)
6464
- [`Gateway.NoDNSLink`](#gatewaynodnslink)
6565
- [`Gateway.DeserializedResponses`](#gatewaydeserializedresponses)
66+
- [`Gateway.AllowCodecConversion`](#gatewayallowcodecconversion)
6667
- [`Gateway.DisableHTMLErrors`](#gatewaydisablehtmlerrors)
6768
- [`Gateway.ExposeRoutingAPI`](#gatewayexposeroutingapi)
6869
- [`Gateway.RetrievalTimeout`](#gatewayretrievaltimeout)
@@ -1104,6 +1105,28 @@ Default: `true`
11041105

11051106
Type: `flag`
11061107

1108+
### `Gateway.AllowCodecConversion`
1109+
1110+
An optional flag to enable automatic conversion between codecs when the
1111+
requested format differs from the block's native codec (e.g., converting
1112+
dag-pb or dag-cbor to dag-json).
1113+
1114+
When disabled (the default), the gateway returns `406 Not Acceptable` for
1115+
codec mismatches, following behavior specified in
1116+
[IPIP-0524](https://github.com/ipfs/specs/pull/524).
1117+
1118+
**Recommended approach**: Instead of relying on gateway-side conversion,
1119+
fetch the raw block using `?format=raw` (`application/vnd.ipld.raw`) and
1120+
perform conversion client-side. This approach:
1121+
1122+
- Allows clients to use any codec without waiting for gateway support
1123+
- Enables ecosystem innovation without gateway operator coordination
1124+
- Works with libraries like [@helia/verified-fetch](https://www.npmjs.com/package/@helia/verified-fetch) in JavaScript
1125+
1126+
Default: `false`
1127+
1128+
Type: `flag`
1129+
11071130
### `Gateway.DisableHTMLErrors`
11081131

11091132
An optional flag to disable the pretty HTML error pages of the gateway. Instead,

docs/examples/kubo-as-a-library/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ go 1.25
77
replace github.com/ipfs/kubo => ./../../..
88

99
require (
10-
github.com/ipfs/boxo v0.35.3-0.20251202220026-0842ad274a0c
10+
github.com/ipfs/boxo v0.35.3-0.20251203042105-52a05615b40f
1111
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
1212
github.com/libp2p/go-libp2p v0.45.0
1313
github.com/multiformats/go-multiaddr v0.16.1

docs/examples/kubo-as-a-library/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd
291291
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU=
292292
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
293293
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
294-
github.com/ipfs/boxo v0.35.3-0.20251202220026-0842ad274a0c h1:mczpALnNzNhmggehO5Ehr9+Q8+NiJyKJfT4EPwi01d0=
295-
github.com/ipfs/boxo v0.35.3-0.20251202220026-0842ad274a0c/go.mod h1:Abmp1if6bMQG87/0SQPIB9fkxJnZMLCt2nQw3yUZHH0=
294+
github.com/ipfs/boxo v0.35.3-0.20251203042105-52a05615b40f h1:QaTdH/7Bi3wPYtwRs9b7cKguT2h2al1ZLYE+ziFYqEg=
295+
github.com/ipfs/boxo v0.35.3-0.20251203042105-52a05615b40f/go.mod h1:Abmp1if6bMQG87/0SQPIB9fkxJnZMLCt2nQw3yUZHH0=
296296
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
297297
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
298298
github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ require (
2222
github.com/hashicorp/go-version v1.7.0
2323
github.com/ipfs-shipyard/nopfs v0.0.14
2424
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0
25-
github.com/ipfs/boxo v0.35.3-0.20251202220026-0842ad274a0c
25+
github.com/ipfs/boxo v0.35.3-0.20251203042105-52a05615b40f
2626
github.com/ipfs/go-block-format v0.2.3
2727
github.com/ipfs/go-cid v0.6.0
2828
github.com/ipfs/go-cidutil v0.1.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.25.0 h1:OqNqsGZPX8zh3eFMO8Lf8EHRRnSGBMqcd
358358
github.com/ipfs-shipyard/nopfs/ipfs v0.25.0/go.mod h1:BxhUdtBgOXg1B+gAPEplkg/GpyTZY+kCMSfsJvvydqU=
359359
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
360360
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
361-
github.com/ipfs/boxo v0.35.3-0.20251202220026-0842ad274a0c h1:mczpALnNzNhmggehO5Ehr9+Q8+NiJyKJfT4EPwi01d0=
362-
github.com/ipfs/boxo v0.35.3-0.20251202220026-0842ad274a0c/go.mod h1:Abmp1if6bMQG87/0SQPIB9fkxJnZMLCt2nQw3yUZHH0=
361+
github.com/ipfs/boxo v0.35.3-0.20251203042105-52a05615b40f h1:QaTdH/7Bi3wPYtwRs9b7cKguT2h2al1ZLYE+ziFYqEg=
362+
github.com/ipfs/boxo v0.35.3-0.20251203042105-52a05615b40f/go.mod h1:Abmp1if6bMQG87/0SQPIB9fkxJnZMLCt2nQw3yUZHH0=
363363
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
364364
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
365365
github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk=

test/dependencies/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ require (
136136
github.com/huin/goupnp v1.3.0 // indirect
137137
github.com/inconshreveable/mousetrap v1.1.0 // indirect
138138
github.com/ipfs/bbloom v0.0.4 // indirect
139-
github.com/ipfs/boxo v0.35.3-0.20251202220026-0842ad274a0c // indirect
139+
github.com/ipfs/boxo v0.35.3-0.20251203042105-52a05615b40f // indirect
140140
github.com/ipfs/go-bitfield v1.1.0 // indirect
141141
github.com/ipfs/go-block-format v0.2.3 // indirect
142142
github.com/ipfs/go-cid v0.6.0 // indirect

0 commit comments

Comments
 (0)