Reputation: 16
I'm trying to setup a service that already handles CORS requests and would like to keep it that way instead of handling the CORS request on the Edge Proxy.
Leaving the cors
field blank didn't help at all.
Is there anyway to achieve this with Ambassador?
Upvotes: 0
Views: 1831
Reputation: 156
Ambassador will not handle CORS in anyway unless you set the cors
parameter in a Mapping
or Module
config.
Even if that is set, the way Envoy handles CORS seems to be the behavior you are searching for.
Taking a look at the linked comment in this issue https://github.com/envoyproxy/envoy/issues/300#issuecomment-296796675, we can see how Envoy chose to implement it's CORS filter. Specifically:
Assign values to the CORS headers in the repsponse: For each of the headers specified in Table 1 above:
a. let value be the option for the header config
b. if value is not defined, continue to the next header
c. else, write the response header for the specified config option
This means that Envoy will first take the value of the headers set by the upstream service and only write them with the configured values if they are not set in the response.
You can test this by creating a route to the httpbin.org (which handles CORS) and setting cors
parameter in the Mapping
.
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: cors-httpbin
spec:
prefix: /httpbin/
service: httpbin.org
cors:
origins:
- http://foo.example
methods:
- POST
- OPTIONS
The Mapping
above should configure Envoy to set the access-control-allow-origins
and access-control-allow-methods
headers to http://foo.example.com
and POST
respectively. However, after sending a test request to this endpoint, we can see that we are instead getting very different CORS headers back in the response:
curl https://aes.example.com/httpbin/headers -v -H "Origin: http://bar.example.com" -H "Access-Control-Request-Method: GET" -X OPTIONS
* Trying 34.74.58.157:443...
* Connected to aes.example.com (10.11.12.100) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: aes.example.com
* Server certificate: Let's Encrypt Authority X3
* Server certificate: DST Root CA X3
> OPTIONS /httpbin/headers HTTP/1.1
> Host: aes.example.com
> User-Agent: curl/7.69.0
> Accept: */*
> Origin: http://bar.example.com
> Access-Control-Request-Method: GET
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< date: Thu, 19 Mar 2020 13:25:48 GMT
< content-type: text/html; charset=utf-8
< content-length: 0
< server: envoy
< allow: HEAD, OPTIONS, GET
< access-control-allow-origin: http://bar.example.com
< access-control-allow-credentials: true
< access-control-allow-methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
< access-control-max-age: 3600
< x-envoy-upstream-service-time: 33
<
* Connection #0 to host aes.example.com left intact
This is because the httpbin.org upstream is setting these headers in the response and so Envoy is defaulting to using them instead of forcing the CORS configuration we gave it. In this way, Envoy really acts as a default for CORS settings and allows upstreams to set more or less restrictive configurations as they see fit.
This behavior can be confusing and caused me a lot of headaches trying to figure it out. I hope I helped clear it up for you.
Upvotes: 1