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

Add ability to omit Vary: Origin header #317

Open
gl-jkeys opened this issue Mar 21, 2024 · 5 comments · May be fixed by #318
Open

Add ability to omit Vary: Origin header #317

gl-jkeys opened this issue Mar 21, 2024 · 5 comments · May be fixed by #318

Comments

@gl-jkeys
Copy link

Hello! Thank you to the authors and maintainers for this important package.

We have an issue where we would like the ability to conditionally omit Vary: Origin as a header. In our use case, we have specific routes for which the responses does not vary based on the requesting origin, e.g. a route for vending static image content.

Without this functionality, we are unable to use Cloudflare Polish1, which only accepts Vary: Accept-Encoding2, short of effectively rewriting all the cors code minus the Vary: Origin header.

Would this repository be able to add this functionality, or accept a patch to allow conditionally removing this header based on the requested routes?

Thank you again!

Footnotes

  1. https://developers.cloudflare.com/images/polish/

  2. https://developers.cloudflare.com/images/polish/cf-polished-statuses/

@gl-jkeys gl-jkeys linked a pull request Mar 23, 2024 that will close this issue
@gl-jkeys
Copy link
Author

cc @UlisesGascon @troygoode @dougwilson

I have opened a PR that will close this issue. I tentatively set the package version to 2.9.0, because I believe this feature warrants a new minor version but does not warrant a new major version.

Apologies for the ping if you are no longer maintaining this package!

@gl-jkeys
Copy link
Author

For anyone who encounters this:

It might be tedious, depending on how many routes you need to apply this to, but here's a function you can use to remove the Origin: Vary header after the cors middleware has been applied to your route.

export function removeVaryOriginHeader(res: Response) {
  const varyHeader = res.getHeader('Vary')
  if (typeof varyHeader === 'string' && varyHeader === 'Origin') {
    res.removeHeader('Vary')
  } else if (Array.isArray(varyHeader) && varyHeader.includes('Origin')) {
    const updatedVaryHeader = varyHeader.filter((header) => header !== 'Origin')
    res.setHeader('Vary', updatedVaryHeader)
  }
}

@UlisesGascon
Copy link
Member

UlisesGascon commented Apr 1, 2024

I opened a discussion on Slack (https://openjs-foundation.slack.com/archives/C02QB1731FH/p1711971438045899), I want to collect more feedback on this.

Feel free to join us in slack. invitation link

@jonchurch
Copy link
Member

jonchurch commented Nov 27, 2024

Edit: What are you setting for origin? Just a string? Doesn't matter rn for the actual behavior in the library, but if you are serving to different origins then removing vary would break things when the browser gets an Access-Control-Allow-Origin for a different origin than the request.

Hmm when we have a fixed origin like either * or mydomain.com the response headers won't actually vary based on origin. If we are using a fixed origin, then we get a fixed Access-Control-Allow-Origin header.

If I set origin: "https://example.com" then I will always get back Access-Control-Allow-Origin: https://example.com

Right now the code will set Vary: Origin for anything except *

cors/lib/index.js

Lines 41 to 66 in 53312a5

if (!options.origin || options.origin === '*') {
// allow any origin
headers.push([{
key: 'Access-Control-Allow-Origin',
value: '*'
}]);
} else if (isString(options.origin)) {
// fixed origin
headers.push([{
key: 'Access-Control-Allow-Origin',
value: options.origin
}]);
headers.push([{
key: 'Vary',
value: 'Origin'
}]);
} else {
isAllowed = isOriginAllowed(requestOrigin, options.origin);
// reflect origin
headers.push([{
key: 'Access-Control-Allow-Origin',
value: isAllowed ? requestOrigin : false
}]);
headers.push([{
key: 'Vary',
value: 'Origin'

That came in w/ #30

Im not sure that was correct though. The MDN link w/ the commit message says:

If the server specifies a single origin (that may dynamically change based on the requesting origin as part of an allowlist) rather than the * wildcard, then the server should also include Origin in the Vary response header to indicate to clients that server responses will differ based on the value of the Origin request header.

When not using an allowlist, we shouldn't need Vary: Origin. If you are using an allowlist, then it would be required due to the response headers changing based on origin.

@jonchurch
Copy link
Member

Updates from the Fetch Spec, we shouldn't be setting Vary: origin for static or * origin option

https://fetch.spec.whatwg.org/#cors-protocol-and-http-caches

If CORS protocol requirements are more complicated than setting Access-Control-Allow-Origin to * or a static origin, Vary is to be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants