Skip to content

Commit

Permalink
ipip-425: Signaling Features on HTTP Gateways
Browse files Browse the repository at this point in the history
Initial version to kick-off discussion
  • Loading branch information
lidel committed Jul 6, 2023
1 parent fb214ae commit 0eacf6a
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/http-gateways/path-gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,46 @@ Optional, present in certain response types:
non-executable binary response types are not used in `<script>` and `<style>`
HTML tags.

### `Ipfs-Gateway-Features` (response header)

Optional, this header SHOULD be only returned in response to HTTP `OPTIONS` request.

The value is a list of key-value pairs, as specified by the 5.6.1. Lists section of :cite[rfc9110].

Each feature is indicated by a key and optional value. When more than one value is supported, `|` is used as a separator.
For example:

```
Ipfs-Gateway-Features: foo, bar=1, buzz=a|b|c
```

A Gateway SHOULD use this header to communicate support for specific Gateway feeatures, enabling clients to make better decisions on how to retrieve data.

A Gateway MAY define and return their own features.

A Client MUST send HTTP OPTIONS request to inspect this header before performaning any more expensive feature-detection.

#### Canonical Ipfs-Features values

- `trustless-gateway` for :cite[trustless-gateway]
- `path-proof` indicates support for returning parent blocks up to the terminus element
- `car-version=1|2` indicates CAR support
- `dag-scope=block|entity|all` from :cite[ipip-0402]
- `entity-bytes` from :cite[ipip-0402], implies support for `dag-scope=entity` as well
- `car-block-order=dfs` from :cite[ipip-0412]
- `car-block-dupes=y|n` from :cite[ipip-0412]
- `path-gateway` for deserialized responses defined by :cite[path-gateway]
- `subdomain-gateway=example.com` for :cite[subdomain-gateway] support based on `Host` header
- `dnslink-gateway` for :cite[dnslink-gateway] support based on `Host` header
- `ipns` indicating :cite[ipns-record] support on `/ipns/` content paths
- `dnslink` indicating [DNSLink](https://dnslink.dev) support on `/ipns/` content paths

<!-- TODO do we want these too?
- `multibase` list of prefixes, indicates which multibase encoding are supported in CIDs
- `multihash` indicates which hash functions are supported in CIDs
- `multicodec` indicates which codecs are supported in CIDs
-->

### `Server-Timing` (response header)

Optional. Implementations MAY use this header to communicate one or more
Expand Down
92 changes: 92 additions & 0 deletions src/ipips/ipip-0425.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
title: "IPIP-0425: Signaling Features on HTTP Gateways"
date: 2023-07-06
ipip: proposal
editors:
- name: Marcin Rataj
github: lidel
url: https://lidel.org/
relatedIssues:
- https://github.com/ipfs/specs/pull/402#pullrequestreview-1396116569
- https://github.com/ipfs/specs/pull/412#pullrequestreview-1427137365
order: 425
tags: ['ipips']
---

## Summary

Add ability to query HTTP Gateway for an explicit list of supported features.

## Motivation

A Gateway always ships with an opinionated set of supported hash functions and
IPLD codecs, and the differences between implementations will grow over time.

For example, some legacy gateways may not support newly added features like
`dag-scope` and `entity-bytes` from :cite[ipip-0402] or the ability to get some
block ordering guarantees introduced in :cite[ipip-0412]. Future IPIPs may add
more features and response formats.

We need a light mechanism for clients to detect which gateway supports partial CARs

## Detailed design

This IPIP introduces a set of HTTP headers returned in response to `OPTIONS` request:

The `Ipfs-Gateway-Features` header is used for signalling support for specific Gateway features to the client.

The lack of the header, or missing key-value pair within the header means support status is unknown.

Initial list of key-value pairs is documented in `Ipfs-Gateway-Features` section of :cite[path-gateway]

## Design rationale

There is a good prior art for this in web browsers where HTTP `OPTIONS` method
is used in [CORS Preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request)
that checks if the CORS protocol is understood and a server is aware using
specific methods and headers.

The `OPTIONS` request if often sent by web browser anyway, so we would not be
introducing much overhead.

### User benefit

Reduced cost for both client and gateway. Sending `OPTIONS` request will be
very inexpensive, especially when compared with current status quo where a
client has to send at least one request to probe a specific feature like
support forp Blake3 hash function or `dag-scope` or `entity-bytes`.

This translates to decreased latency and ability to choose the best retrieval
strategy faster.

### Compatibility

This IPIP is fully backward-compatible with browsers and existing IPFS
ecosystem. Gateways already return CORS headers with `OPTIONS` responses, we
will simply return additional headers with the same responses.

:::issue

For JavaScript running on web pages to be able to read `Ipfs-Gateway-Features`
header it MUST be safelisted via `Access-Control-Expose-Headers`.

:::

### Security

This IPIP does not introduce any new security concerns. Probing gateway for
supported features and hash functions is already possible via regular `GET`
requests.

### Alternatives

- Exposing the list of suported features via `GET /.well-known/ipfs/gateway/features-TBD` would also work, but:
- introduces surface for path-related deployment bugs, where Nginx is only exposing `/ipfs` namespace – in such case signaling endpoint would not be exposed to the public internet

## Test fixtures

TODO

### Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

0 comments on commit 0eacf6a

Please sign in to comment.