CORS issues for cluster in docker

Hi,
im currently setting up a local docker test cluster (4 nodes all on the same machine). I’ve followed this docker-compose.yml and setup things like the replication factor etc., which all work.
The issue i’m having is adding files to the cluster directly, over the proxy api and not via ipfs-cluster-ctl cli, that works as it should. From what I understand the cluster proxy api (port 9095) mimics the ipfs api, meaning I should be able to add files with the js-ipfs-http-client, just like when running a normal ipfs node. However, when I add a file, I get an CORS error (No ‘Access-Control-Allow-Origin’ header is present on the requested resource) and no response that contains the files address, the request is still successful though. The funny thing is, the file is actually added to the cluster, with all the pins etc. working as expected.

ENV’s from docker compose:

environment:
  CLUSTER_SECRET: 890e6fe6498009xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  IPFS_API: /dns4/ipfs0/tcp/5001
  CLUSTER_REPLICATIONFACTORMIN: 2
  CLUSTER_REPLICATIONFACTORMAX: 2
  CLUSTER_PEERNAME: cluster0
  CLUSTER_LEAVEONSHUTDOWN: 'TRUE'
  CLUSTER_RESTAPI_CORSALLOWEDMETHODS: GET, POST
  CLUSTER_RESTAPI_CORSALLOWEDORIGINS: http://localhost:3000

Request error message:
Access to fetch at ‘http://127.0.0.1:9095/api/v0/add?stream-channels=true’ from origin ‘http://localhost:3000’ 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.

Request:

Would be grateful for any help or ideas what could be causing this.

Hi,

since you are accessing the Proxy endpoint, you need to configure IPFS with the CORS headers you need. I think you need to add localhost:3000 to the IPFS configuration. The CLUSTER_RESTAPI_CORSALLOWEDORIGINS apply to the Cluster REST API, but not to the proxy.

Cluster will do its best to mimic the IPFS API responses so that it looks like you are talking directly to the IPFS daemon. This means that if CORS is not configured in IPFS, then Cluster won’t add anything.

Hope that helps!

Im actually doing that. When I use js-ipfs-http-client with port 5001, it works without any issues.
The thing that is really throwing me off, is the fact that I get the cors error, but the data is still added to cluster but no hash is returned.
I’ll do some digging to figure out what is causing this, when I add data to the cluster with js-ipfs-http-client but run it from my terminal, there is no error, so im guessing its some kind of browser policy that is causing this. I’ll update this when I find a solution.

Hmm what is the origin header that arrives to the IPFS daemon when you make the request through Cluster? I’m suspecting is not the same as when you do the request directly… does it work with the allowed origins set to ‘*’ ?

Might help if you post both requests as well (include the OPTION one).
Iirc the Access-Control-Allow-Origin header must be present on both respones. I suspect it is only included in the OPTION response.

I’m unable to catch/inspect the request made from the proxy api to the ipfs daemon. You have any tips on how to catch it/locate the logs in docker? Does this have to do with the ipfsproxy.extract_headers_extra setting?
The ipfs daemon and the ipfs cluster are both configured to accept all origins.

ngrep to localhost:5001 should show any traffic sent to the IPFS API from the cluster proxy endpoint.

You are using cluster 0.8.0 or above right?? We definitely hardcode more headers than the ones your response is showing.

I just tested and it works for me:

[20:04:41] ~ $ curl -v -X POST 'localhost:9095/api/v0/add' -F file=@ipfs-test.txt -H 'Origin: localhost:9095'
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying ::1...
* TCP_NODELAY set
* connect to ::1 port 9095 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 9095 (#0)
> POST /api/v0/add HTTP/1.1
> Host: localhost:9095
> User-Agent: curl/7.60.0
> Accept: */*
> Origin: localhost:9095
> Content-Length: 207
> Content-Type: multipart/form-data; boundary=------------------------8fff3c7783835b37
> 
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: X-Stream-Output, X-Chunked-Output, X-Content-Length
< Cache-Control: no-cache
< Connection: close
< Content-Type: application/json
< Server: ipfs-cluster/ipfsproxy/0.9.0+git041f5e1e937d1b4376f12825f25a823bc58d5767
< Trailer: X-Stream-Error
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< X-Chunked-Output: 1
< Date: Thu, 28 Feb 2019 20:04:46 GMT
< Transfer-Encoding: chunked
< 

You need to make sure that the IPFS config for CORS is correct. It needs to be in the API section, not the HTTPGateway one. And it needs to allow POST:

  "API": {
    "HTTPHeaders": {
      "Access-Control-Allow-Headers": [
        "X-Requested-With",
        "Range"
      ],
      "Access-Control-Allow-Methods": [
        "POST", "GET"
      ],
      "Access-Control-Allow-Origin": [
        "*"
      ]
    }
  },

Adding data via terminal, like you did above works just like it should, just that I dont see the Access-Control-Allow-Origin header. I mean the only thing this could still be causing is that the settings aren’t set via docker ENV’s properly I would think at this point.

Is this correct?

CLUSTER_RESTAPI_CORSALLOWEDMETHODS: GET,POST,PUT
CLUSTER_RESTAPI_CORSALLOWEDORIGINS: "*"

This is the service.json that is generated in my container, as I understand, the settings that are set via Docker ENV’s aren’t shown here. https://pastebin.com/HFS1t4NH

Regarding the requests from proxy to daemon, I monitored all requests on port 5001 with wireshark, not able to see the ones sent from the proxy though. Will try with ngrep after lunch.

Also, im always pulling the latest cluster image from docker.

I already mentioned that RESTAPI_* configuration variables have nothing to do with the proxy endpoint and do not affect it. This is very probably an issue with the ipfs daemon being misconfigured (.ipfs/config), not Cluster.