ipshipyard / waterworks-community

Discussion and documentation concerning the operation of the IPFS HTTP Gateway at https://ipfs.io/ipfs.
MIT License
0 stars 0 forks source link

missing CORS header on trustless-gateway.link #4

Closed lidel closed 4 months ago

lidel commented 5 months ago

trustless-gateway.link can't be used in browser due to missing CORS header.

Repro steps

@sgtpooki created demo at https://codepen.io/SgtPooki/pen/JjxYpZX

Can be reproduced by looking at Network tab in devtools.

Problem

I think the exact problem is that response is missing access-control-allow-origin: *:

$ curl -i "https://trustless-gateway.link/ipfs/QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6" -H "Accept: application/vnd.ipld.raw"
HTTP/2 200
server: openresty
date: Tue, 16 Jan 2024 16:38:28 GMT
content-type: application/vnd.ipld.raw
content-length: 24862
accept-ranges: bytes
access-control-allow-methods: GET
access-control-allow-methods: HEAD
access-control-allow-methods: OPTIONS
cache-control: public, max-age=29030400, immutable
content-disposition: attachment; filename="QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6.bin"; filename*=UTF-8''QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6.bin
etag: "QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6.raw"
vary: Accept-Encoding
x-content-type-options: nosniff
x-ipfs-path: /ipfs/QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6
x-ipfs-roots: QmawceGscqN4o8Y8Fv26UUmB454kn2bnkXV5tEQYc4jBd6
x-ipfs-pop: ipfs-bank4-fr2
timing-allow-origin: *
x-ipfs-datasize: 24862
x-ipfs-lb-pop: gateway-bank2-fr2
x-bfid: 9a831c6b4e1115eac081897c46ace271
strict-transport-security: max-age=31536000; includeSubDomains; preload
x-proxy-cache: MISS

cc @sgtpooki @ns4plabs @2color

lidel commented 5 months ago

@ns4plabs for now, let's add the missing header at nginx level

@hacdias i wonder if we should make liberal CORS the default in boxo/gateway, so we don't have to set them up every time on public gateways?

These are more often desired (subdomain and path gateways) rather than not.

SgtPooki commented 5 months ago

Access to fetch at 'https://trustless-gateway.link/ipfs/QmW9pMY7fvbxVA2CaihgxJRzmSv15Re2TABte4HoZdfypo?format=raw' from origin 'https://cdpn.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

SgtPooki commented 5 months ago

@hacdias i wonder if we should make liberal CORS the default in boxo/gateway, so we don't have to set them up every time on public gateways?

@lidel, also, do we have recommended config for trustless gateways in the IPIP or elsewhere? i.e. CORS should allow any origin?

lidel commented 5 months ago

specs are tracked in https://github.com/ipfs/specs/issues/423

until we have them, as a rule of thumb, always assume public gateways must have liberal CORS so other websites can fetch content from them

hacdias commented 5 months ago

@lidel we already have a function that applies the liberal CORS: https://github.com/ipfs/boxo/blob/main/gateway/gateway.go#L431. If your suggestion is to apply it by default, I would also suggest stopping to export it.

It seems fine to me to change the default, as long as we make it clear.

lidel commented 5 months ago

I assumed we forgot to enable CORS in Rainbow, and it had to be added in Nginx, but I've checked latest Kubo and ghcr.io/ipfs/rainbow:main-latest and both have Access-Control-Allow-Origin: *, so we don't need to change anything in boxo, this seems to be an infra thing.

@ns4plabs any idea why Access-Control-Allow-Origin: * gets dropped on trustless-gateway.link and not ipfs.io?

achingbrain commented 5 months ago

I'm not sure this is working in Kubo 0.25.0, unless I've misconfigured it.

I have enabled CORS on the API with:

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["GET", "POST"]'

And turned on the routing API on the gateway and enabled CORS with:

ipfs config --json Gateway.ExposeRoutingAPI 'true'
ipfs config --json Gateway.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
ipfs config --json Gateway.HTTPHeaders.Access-Control-Allow-Methods '["GET", "POST"]'

I can make a fetch request to the API from any origin with:

await fetch('http://127.0.0.1:5101/api/v0/id', { method: 'POST' })
Response { type: 'cors', url: 'http://127.0.0.1:5101/api/v0/id' ...

But I get errors from the routing API:

await fetch('http://127.0.0.1:8180/routing/v1/ipns/bafzaajaiaejcbsm3udfhqd6ailaazwtte7543vgezji6ultv43jkdxhd4elgc5wr', { headers: { Accept: 'application/vnd.ipfs.ipns-record' }})
Access to fetch at 'http://127.0.0.1:8180/routing/v1/ipns/bafzaajaiaejcbsm3udfhqd6ailaazwtte7543vgezji6ultv43jkdxhd4elgc5wr' from origin 'http://127.0.0.1:5101' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
hacdias commented 5 months ago

@achingbrain that is indeed a bug. The config gateway headers are applied solely to the gateway handler, and to nothing else on that HTTP listener.

@lidel I see two options:

  1. Add a headers option to the routing server handler. More things to pass around in more places.
  2. Remove the HTTPHeaders option from boxo/gateway. The implementer is then responsible for setting up some middleware (< 10 lines) that sets the headers they want. In Kubo this is trivial with the corehttp.Option system, and would then apply to everything in the gw port.
lidel commented 5 months ago

Yep, it is a bug, since /routing/v1 is exposed on gateway port, it should have the same implicit config and user-provided Gateway.HTTPHeaders applied as /ipfs handler.

@hacdias +1 to refactoring things and moving implicit/explicit header setup into a dedicated reusable middleware handler (example, we would write our own version). I think we should have it in boxo/gateway and have it in examples, so people don't need to write their own for basic stuff like implicit CORS.

In Kubo, the middleware would add all implicit headers and CORS from boxo/gateway + add any user provided configuration from Gateway.HTTPHeaders and we could put it in front of both /routing/v1 and /ipfs handlers sgtm.

This way it is in one place and we don't need to pass anything into the routing handler.

ns4plabs commented 5 months ago

We rolled out https://github.com/protocol/bifrost-infra/pull/2826 and now the Rainbow headers are passed through

SgtPooki commented 4 months ago

I believe we can probably close this now. confirmed that requests are working properly at https://codepen.io/SgtPooki/pen/JjxYpZX

2color commented 4 months ago

Confirming this is working too. Can be closed @lidel (I don't have permissions)