Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPIP-280: App Conventions for HTTP Gateway Detection #280

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/http-gateways/gateway-detection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: Detecting User-Preferred IPFS Gateway
description: >
Specification of the rules and standards for detecting and identifying
user-preferred IPFS gateways within applications, enabling seamless
integration and user control.
date: 2023-10-03
maturity: reliable
editors:
- name: Mark Gaiser
github: markg85
- name: Marcin Rataj
github: lidel
url: https://lidel.org/
affiliation:
name: Protocol Labs
url: https://protocol.ai/
tags: ['httpGateways', 'integratingHttpGateways']
order: 99
---


## Introduction

This document defines conventions for how applications can identify available
IPFS gateway, and how IPFS gateway implementations can signal own endpoint to
client applications.

## Specification

There are two ways of hinting user-prefered gateway URL:

- Setting the `IPFS_GATEWAY` environment variable
- Creating a `gateway` file at a well-known path

Applications SHOULD evaluate these hints in order and stop on the first match:

1. Check if a valid `IPFS_GATEWAY` environment variable is set
2. Check if a valid `gateway` file is present at one of well-known filesystem paths


### `IPFS_GATEWAY` Environment Variable

When `IPFS_GATEWAY` environment variable is set, the value MUST be interpreted
as URL of IPFS Gateway application to use.

This variable SHOULD override gateway selection done by all other means, including
internal application configuration.

### The `gateway` Configuration File

Client application SHOULD check if file is present at specific filesystem paths, in order:

1. If `IPFS_PATH` is set, try `$IPFS_PATH/gateway`
2. If `HOME` is set, try `$HOME/.ipfs/gateway`
3. If `$XDG_CONFIG_HOME` is set, try `$XDG_CONFIG_HOME/ipfs/gateway`
4. If `/etc` exists, try `/etc/ipfs/gateway`
5. Try OS-specific paths
- Windows
1. `%LOCALAPPDATA%/ipfs/gateway` (local user)
2. `%APPDATA%/ipfs/gateway` (roaming user)
3. `%PROGRAMDATA%/ipfs/gateway` (global)
- macOS
1. `$HOME/Library/Application Support/ipfs/gateway` (user)
2. `/Library/Application Support/ipfs/gateway` (global)
- Linux
1. `$HOME/.config/ipfs/gateway` (user)
2. `/etc/ipfs/gateway` (global)
Comment on lines +58 to +68
Copy link
Member

@lidel lidel Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markg85 I'm not feeling strongly about having OS-specific paths or ~/.config and /etc: keep or remove?
afaik nothing implements these atm, but does not hurt to have them is spec to future-proof things.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not feeling strong about those either.
They don't hurt or complicate things. The only reason i'd lean towards keeping it is because they clarify the windows part, mac/linux is effectively handled by points 1-4 as well.

So if it doesn't hurt, keep it. Else remove it.


When `gateway` file is present, the file contents MUST be interpreted as line
separated (`\n` or `\r\n`) `text/plain` file.

The first line of `gateway` file MUST be a valid `http://` or `https://` URL.

Implementations that only need one URL SHOULD use the first one and ignore the rest of the file.
Comment on lines +70 to +75
Copy link
Member

@lidel lidel Oct 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markg85 I wrote this bit naively, and now I realized that having more than one URL will cause issues in curl (code).

Any concerns if we simplify the spec and state that only one URL is allowed in the gateway file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh ouch!

For this spec. I'd keep it at a first line requirement but not limited to 1 line. Aka, it's fine as-is.

Curl needs some attention to catch the multiline scenario regardless of this spec. As just any other data after the first line is gonna break it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, my understanding is this problem was solved in curl/curl@859e88f#diff-1fa338b6a8d4b9a9ffd2243527ac4951c2576cb32dc28440f36f4f59e60643e2R785, the gateway file can now have more than one line, curl ignores everything after the first one.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

I'm leaving it up to your digression if you want to follow the curl 8.4.0 approach (meaning the spec needs to be reworded to 1 line and 1 only) or the curl 8.5.0 approach (first line must be the gateway, rest is ignored).

I would go for the 8.5.0 approach (aka, the spec as-written is ok). Given the other IPFS fixes in 8.5.0, that release is certainly the one to recommend for IPFS usage. Also, it's about to be released on Dec. 6th 2023.


### Security

Applications that integrate IPFS support via HTTP gateway:

MUST NOT hard-code non-localhost URL as a default fallback. Instead, SHOULD ask
user to define preferred IPFS gateway using one of methods defined in this
document.

SHOULD either warn user when non-localhost gateway is used for deserialized
responses (warning about the risk of MITM), or (preferred) limit HTTP use
outside of localhost to verifiable response types defined in
:cite[trustless-gateway].

### Privacy and User Control

Applications SHOULD never default to public gateways. Instead, suggest to the
user how to run a local node.

### Compatibility and Testing

Implementers should test against implementations mentioned in :cite[ipip-0280]
as the baseline for making decisions around maximizing interoperability.

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
2 changes: 2 additions & 0 deletions src/http-gateways/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ <h3>Web</h3>
<a href="https://en.wikipedia.org/wiki/Same-origin_policy">origin-based security model</a>.
</p>
{% include 'list.html', posts: collections.webHttpGateways %}
<h3>Integration</h3>
{% include 'list.html', posts: collections.integratingHttpGateways %}
</main>

{% include 'footer.html' %}
4 changes: 4 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ <h3><a href="/http-gateways/">HTTP Gateways</a></h3>
Web semantics (for website hosting and web browsers):
</p>
{% include 'list.html', posts: collections.webHttpGateways %}
<p>
Other integrations:
</p>
{% include 'list.html', posts: collections.integratingHttpGateways %}
</section>
<section>
<h3><a href="/ipns/">InterPlanetary Naming System</a></h3>
Expand Down
104 changes: 104 additions & 0 deletions src/ipips/ipip-0280.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: "IPIP-0280: Conventions for HTTP Gateway Detection"
date: 2023-10-03
ipip: proposal
editors:
- name: Mark Gaiser
github: markg85
- name: Marcin Rataj
github: lidel
url: https://lidel.org/
affiliation:
name: Protocol Labs
url: https://protocol.ai/
relatedIssues:
- https://github.com/ipfs/kubo/issues/8847
- https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/f889837e00d3b2388a24c0a9d075ad62f47da825
- https://github.com/curl/curl/pull/8805
order: 280
tags: ['ipips']
---

## Summary

This IPIP aims to create conventions for how applications can identify available IPFS gateway,
and how IPFS gateway implementations can signal own endpoint.

## Motivation

Applications wanting to leverage IPFS Gateways are, without a common
convention, left to invent their own ways of finding a gateway, including naive
approaches such as localhost port scanning.

This IPIP introduces specification that defines how an application wanting to
implement IPFS support can find a local or user-preferred gateways.

## Detailed design

We introduce two ways of hinting user-prefered gateway URL to cover
the majority of runtimes and use cases:

- `IPFS_GATEWAY` environment variable
- `gateway` file and filesystem paths to look for it

See: :cite[gateway-detection] for details.

## Design rationale

### User benefit

End users can define their prefered gateway once, and benefit from
opportunistic support in applications they use.

Application developers save time as they only need to implement support for
vendor-agnostic convention to be able to read user preferred gateway.

### Compatibility

#### Kubo

Kubo ([>0.15.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.15.md#-ipfs_pathgateway-file))
creates a hint file in `$IPFS_PATH/gateway` (default being `$HOME/.ipfs/gateway`, see [kubo#8847](https://github.com/ipfs/kubo/issues/8847)).

The file contains a single line being the local HTTP gateway URL. For example: `http://localhost:8080`.

Every time `ipfs daemon` starts, it updates the the content of `$IPFS_PATH/gateway` or creates the file if it doesn't exist.

#### IPFS Chromium

ipfs-chromium uses `IPFS_GATEWAY` environment variable
([ipfs-chrompium#29](https://github.com/little-bear-labs/ipfs-chromium/issues/29)).

It can be a single URL, or a whitespace-separated URLs to be used as the initial gateway pool.

Ref. <https://blog.ipfs.tech/2023-05-multigateway-chromium-client/>

#### FFMPEG

FFMPEG's libavformat supports both `$HOME/.ipfs/gateway` file and `IPFS_GATEWAY` environment variable
([ffmpeg.git/commit/f889837](https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/f889837e00d3b2388a24c0a9d075ad62f47da825)).


Ref. <https://blog.ipfs.tech/2022-08-01-ipfs-and-ffmpeg/>

#### Curl

Curl (>8.4.0, [curl#8805](https://github.com/curl/curl/pull/8805)) supports
will try the `IPFS_GATEWAY` environment variable first, and then look for
`$IPFS_PATH/gateway` or `$HOME/.ipfs/gateway`, if present.

It expects a single URL.

Ref. <https://curl.se/docs/ipfs.html>

### Security

See "Security" section of :cite[gateway-detection].

### Alternatives

N/A. This IPIP covers both environment variable and configuration file.

### Copyright

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