CORS Issue: Custom Header Being Blocked by IC Boundary Node

I’m running a canister that serves XRPC endpoints. I’m trying to allow cross-origin requests that include a custom header atproto-accept-labelers.

My canister sets these CORS headers:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: *

However, the OPTIONS preflight response from the boundary node shows more restrictive headers:

access-control-allow-headers: user-agent,dnt,if-none-match,if-modified-since,cache-control,content-type,range,cookie,x-requested-with,x-ic-canister-id

This is causing browsers to block requests with the custom header. Is there a way to override this?

For more context, I am trying to get https://bsky.app to send a request to my canister but it needs to include the atproto-accept-labelers when its connecting to my server
Any help would be great

3 Likes

Oh yes…if you need custom headers you may need to run a custom boundary board like we did with propyl.io.

:slightly_frowning_face:

1 Like

Maybe in theory when the boundary nodes are decentralized, each boundary node could have different settings?
This is kind of a big deal this doesn’t work for my project

Im not a big CORS guy, any thoughts on why the headers are limited but other CORS settings are *?

2 Likes

I’m not sure. I had issues with partial media files back in the day. I think this has been resolved. I know you can mess with headers in asset canisters using the json5 file.

See discussion: Boundary node http response headers - #72 by faraz.shaikh

This is what we used but it was last updated 3 years ago:

This may be the new one:

Maybe some clues as to what happens here: Code search results · GitHub

3 Likes

tagging @rbirkner
Saw you were in the other boundary node threads

Seems like it

2 Likes

Hey @Gekctek

Your observations are 100% correct. The HTTP gateway within the boundary nodes overrides whatever CORS headers you set in your canister. In particular, OPTIONS requests are directly handled by the HTTP gateway and never make it to the canister. Changing that would mean significantly increased latency for all OPTIONS requests.

I can check what the possibilities are and will report back!

3 Likes

That would be wonderful, thank you

@rbirkner Any update/additional thoughts?

Sorry for taking so long to get back to you: I replied in the other thread, but it also relates to this.

Why does POSTMAN seem to work fine when hitting the ICP http boundary nodes, but browser calls fail?

Hey @Gekctek

We have an update for you and the good news is, we will get there, but it will take some time:

Currently, the HTTP gateways directly reply to any OPTIONS request with the default headers. We have now updated the behavior such that OPTIONS requests are passed on to the canister. If the canister provides a valid response, the HTTP gateway returns it to the client. Otherwise, the HTTP gateway injects its default response and remembers for 1 day that the canister is not providing proper responses (this is to reduce the latency and load).

However, we have not yet activated this behavior as none of the canisters that we tested with actually support OPTIONS requests. The asset canister treats every requests as a GET (independent of the actual request method). NNS and II dapp are the same. The only dapp that somewhat handles OPTIONS is juno.build, which returns a 405 Method not supported error. We have brought it up internally and hopefully, we can get support for that soon (at least in the asset canister).

What kind of canister do you intend to use? Do you have your own canister or do you rely on the asset canister?

UPDATE: Just in case you are interested: this is the corresponding PR on the HTTP gateway

2 Likes

What kind of requests are you making? Can you provide us with an example please.

I am currently building an http framework in motoko so I’ll be doing all the CORS response headed myself

It started as me wanting to integrate into another system that has a custom header, but now it’s more general of needing to handle the OPTIONS preflight in my framework

Out of curiosity: Do you handle certification in your HTTP framework?

I’m working on integration with some cert libraries
https://mops.one/ic-assets

1 Like

How will i know when this has been deployed to production http gateways
I see its merged in and whatnot but im not sure how often gateways get updated