@@ -69,18 +69,29 @@ const defaults: CorsOptions = {
6969 * @returns {Middleware<T, B> } - A middleware function for handling CORS headers.
7070 */
7171export function cors < T extends Record < string , unknown > = Record < string , unknown > , B extends Record < string , unknown > = Record < string , unknown > > (
72- options : CorsOptions = { }
72+ options : CorsOptions = { } ,
7373) : Middleware < T , B > {
7474 const opts = { ...defaults , ...options } ;
7575
7676 return async ( ctx : Context < T , B > , next ) => {
77- const origin = ctx . req . headers . get ( "Origin" ) || "" ;
77+ const requestOrigin = ctx . req . headers . get ( "Origin" ) ;
7878
79- // Check if origin is allowed
80- const isAllowed = await checkOrigin ( origin , opts . origin ) ;
79+ // Non-CORS request
80+ if ( ! requestOrigin ) {
81+ return next ( ) ;
82+ }
83+
84+ const isAllowed = await checkOrigin ( requestOrigin , opts . origin ) ;
8185
8286 if ( isAllowed ) {
83- ctx . header ( "Access-Control-Allow-Origin" , origin || "*" ) ;
87+ const isWildcard = opts . origin === "*" && ! opts . credentials ;
88+
89+ if ( isWildcard ) {
90+ ctx . header ( "Access-Control-Allow-Origin" , "*" ) ;
91+ } else {
92+ ctx . header ( "Access-Control-Allow-Origin" , requestOrigin ) ;
93+ appendVary ( ctx , "Origin" ) ;
94+ }
8495
8596 if ( opts . credentials ) {
8697 ctx . header ( "Access-Control-Allow-Credentials" , "true" ) ;
@@ -91,7 +102,7 @@ export function cors<T extends Record<string, unknown> = Record<string, unknown>
91102 }
92103 }
93104
94- // Handle preflight
105+ // Preflight request
95106 if ( ctx . req . method === "OPTIONS" ) {
96107 if ( opts . allowMethods ?. length ) {
97108 ctx . header ( "Access-Control-Allow-Methods" , opts . allowMethods . join ( ", " ) ) ;
@@ -101,12 +112,12 @@ export function cors<T extends Record<string, unknown> = Record<string, unknown>
101112 ctx . header ( "Access-Control-Allow-Headers" , opts . allowHeaders . join ( ", " ) ) ;
102113 }
103114
104- if ( opts . maxAge ) {
105- ctx . header ( "Access-Control-Max-Age" , opts . maxAge . toString ( ) ) ;
115+ if ( opts . maxAge !== undefined ) {
116+ ctx . header ( "Access-Control-Max-Age" , String ( opts . maxAge ) ) ;
106117 }
107118
108119 if ( ! opts . preflightContinue ) {
109- return ctx . text ( "" , opts . optionsSuccessStatus || 204 ) ;
120+ return ctx . text ( "" , opts . optionsSuccessStatus ?? 204 ) ;
110121 }
111122 }
112123
@@ -125,6 +136,20 @@ async function checkOrigin(origin: string, allowed?: string | string[] | ((origi
125136 if ( ! allowed || allowed === "*" ) return true ;
126137 if ( typeof allowed === "string" ) return origin === allowed ;
127138 if ( Array . isArray ( allowed ) ) return allowed . includes ( origin ) ;
128- if ( typeof allowed === "function" ) return allowed ( origin ) ;
139+ if ( typeof allowed === "function" ) return await allowed ( origin ) ;
129140 return false ;
130141}
142+
143+ function appendVary ( ctx : Context < any , any > , value : string ) {
144+ const existing = ctx . res ?. headers . get ( "Vary" ) ;
145+ if ( ! existing ) {
146+ ctx . header ( "Vary" , value ) ;
147+ } else if (
148+ ! existing
149+ . split ( "," )
150+ . map ( ( v ) => v . trim ( ) )
151+ . includes ( value )
152+ ) {
153+ ctx . header ( "Vary" , `${ existing } , ${ value } ` ) ;
154+ }
155+ }
0 commit comments