diff --git a/CHANGELOG.md b/CHANGELOG.md index 7190373ed..420aeb792 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ The following emojis are used to highlight certain changes: ### Fixed +- `routing/http/client`: optional address and protocol filter parameters from [IPIP-484](https://github.com/ipfs/specs/pull/484) use human-readable `,` instead of `%2C`. [#688](https://github.com/ipfs/boxo/pull/688) + ### Security ## [v0.24.0] diff --git a/routing/http/filters/filters.go b/routing/http/filters/filters.go index ae7aad18f..122f625de 100644 --- a/routing/http/filters/filters.go +++ b/routing/http/filters/filters.go @@ -39,7 +39,13 @@ func AddFiltersToURL(baseURL string, protocolFilter, addrFilter []string) string query.Set("filter-addrs", strings.Join(addrFilter, ",")) } - parsedURL.RawQuery = query.Encode() + // The comma is in the "sub-delims" set of characters that don't need to be + // encoded in most parts of a URL, including query parameters. Golang + // standard library percent-escapes it for consistency, but we prefer + // human-readable /routing/v1 URLs, and real comma is restored here to + // ensure human and machine requests hit the same HTTP cache keys. + parsedURL.RawQuery = strings.ReplaceAll(query.Encode(), "%2C", ",") + return parsedURL.String() } diff --git a/routing/http/filters/filters_test.go b/routing/http/filters/filters_test.go index ac6219bd7..d86316045 100644 --- a/routing/http/filters/filters_test.go +++ b/routing/http/filters/filters_test.go @@ -30,21 +30,21 @@ func TestAddFiltersToURL(t *testing.T) { baseURL: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", protocolFilter: []string{"transport-bitswap", "transport-ipfs-gateway-http"}, addrFilter: nil, - expected: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi?filter-protocols=transport-bitswap%2Ctransport-ipfs-gateway-http", + expected: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi?filter-protocols=transport-bitswap,transport-ipfs-gateway-http", }, { name: "Only addr filter", baseURL: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", protocolFilter: nil, addrFilter: []string{"ip4", "ip6"}, - expected: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi?filter-addrs=ip4%2Cip6", + expected: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi?filter-addrs=ip4,ip6", }, { name: "Both filters", baseURL: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi", protocolFilter: []string{"transport-bitswap", "transport-graphsync-filecoinv1"}, addrFilter: []string{"ip4", "ip6"}, - expected: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi?filter-addrs=ip4%2Cip6&filter-protocols=transport-bitswap%2Ctransport-graphsync-filecoinv1", + expected: "https://example.com/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi?filter-addrs=ip4,ip6&filter-protocols=transport-bitswap,transport-graphsync-filecoinv1", }, { name: "URL with existing query parameters",