Skip to content

Commit d295878

Browse files
authoredDec 21, 2022
fix(cors): add content-length: 0 header if 204 is returned by OPTIONS request (#2239)
* fix(cors): add content-length: 0 header if 204 is returned by OPTIONS request * add changeset
1 parent c152105 commit d295878

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed
 

‎.changeset/slimy-kings-confess.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'graphql-yoga': patch
3+
---
4+
5+
Add content-length: 0 header if 204 is returned by OPTIONS request

‎packages/graphql-yoga/src/plugins/useCORS.ts

+6
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ export function useCORS<TServerContext extends Record<string, any>>(
146146
if (request.method.toUpperCase() === 'OPTIONS') {
147147
const response = new fetchAPI.Response(null, {
148148
status: 204,
149+
// Safari (and potentially other browsers) need content-length 0,
150+
// for 204 or they just hang waiting for a body
151+
// see: https://github.com/expressjs/cors/blob/master/lib/index.js#L176
152+
headers: {
153+
'Content-Length': '0',
154+
},
149155
})
150156
endResponse(response)
151157
}

‎packages/graphql-yoga/src/plugins/useCors.spec.ts

+32
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,39 @@
11
import { Request } from '@whatwg-node/fetch'
2+
import { createSchema } from '../schema.js'
3+
import { createYoga } from '../server.js'
4+
import { YogaInitialContext } from '../types.js'
25
import { getCORSHeadersByRequestAndOptions, CORSOptions } from './useCORS.js'
36

47
describe('CORS', () => {
8+
describe('OPTIONS call', () => {
9+
it('should respond with correct status & headers', async () => {
10+
const schemaFactory = async (ctx: YogaInitialContext) => {
11+
return createSchema({
12+
typeDefs: /* GraphQL */ `
13+
type Query {
14+
foo: String
15+
}
16+
`,
17+
resolvers: {
18+
Query: {
19+
foo: () => 'bar',
20+
},
21+
},
22+
})
23+
}
24+
const yoga = createYoga({
25+
schema: schemaFactory,
26+
})
27+
let result = await yoga.fetch('http://yoga/graphql', {
28+
method: 'OPTIONS',
29+
headers: {
30+
'Content-Type': 'application/json',
31+
},
32+
})
33+
expect(result.status).toEqual(204)
34+
expect(result.headers.get('Content-Length')).toEqual('0')
35+
})
36+
})
537
describe('No origins specified', () => {
638
const corsOptionsWithNoOrigins = {}
739
it('should return the wildcard if no origin is sent with header', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.