11import { Context } from 'hono' ;
22import { Env } from '../utils' ;
33
4+ function matchOrigin ( origin : string , allowed : string [ ] ) : boolean {
5+ for ( const rule of allowed ) {
6+ if ( rule === '*' ) return true ;
7+ if ( rule . includes ( '*' ) ) {
8+ const pattern = '^' + rule
9+ . replace ( / [ . + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' )
10+ . replace ( / \\ \* / g, '.*' ) + '$' ;
11+ const re = new RegExp ( pattern ) ;
12+ if ( re . test ( origin ) ) return true ;
13+ } else if ( rule === origin ) {
14+ return true ;
15+ }
16+ }
17+ return false ;
18+ }
19+
420export async function corsMiddleware ( c : Context < { Bindings : Env } > , next : ( ) => Promise < void > ) {
5- const origin = c . req . header ( 'Origin' ) ;
21+ const origin = c . req . header ( 'Origin' ) || '' ;
622 const allowedOriginsEnv = c . env . ALLOWED_ORIGINS || '*' ;
723
8- // 許可されたオリジンのリストを取得
924 const allowedOrigins = allowedOriginsEnv === '*'
1025 ? [ '*' ]
11- : allowedOriginsEnv . split ( ',' ) . map ( ( o : string ) => o . trim ( ) ) ;
26+ : allowedOriginsEnv . split ( ',' ) . map ( ( o : string ) => o . trim ( ) ) . filter ( Boolean ) ;
1227
13- // オリジンが許可されているかチェック
1428 let allowedOrigin = '*' ;
1529 if ( origin && allowedOrigins [ 0 ] !== '*' ) {
16- if ( allowedOrigins . includes ( origin ) ) {
30+ if ( matchOrigin ( origin , allowedOrigins ) ) {
1731 allowedOrigin = origin ;
1832 } else {
19- // オリジンが許可されていない場合はCORSヘッダーを返さない
33+ // Not allowed origin: log details for troubleshooting
34+ try {
35+ const url = new URL ( c . req . url ) ;
36+ console . warn ( '[CORS] Blocked request' , {
37+ method : c . req . method ,
38+ path : url . pathname ,
39+ origin,
40+ allowedOrigins,
41+ } ) ;
42+ } catch ( _ ) {
43+ console . warn ( '[CORS] Blocked request' , {
44+ method : c . req . method ,
45+ origin,
46+ allowedOrigins,
47+ } ) ;
48+ }
2049 if ( c . req . method === 'OPTIONS' ) {
2150 return c . text ( 'Forbidden' , 403 ) ;
2251 }
@@ -25,9 +54,12 @@ export async function corsMiddleware(c: Context<{ Bindings: Env }>, next: () =>
2554 }
2655 }
2756
57+ const reqAllowedHeaders = c . req . header ( 'Access-Control-Request-Headers' ) ;
58+
2859 c . header ( 'Access-Control-Allow-Origin' , allowedOrigin ) ;
60+ c . header ( 'Vary' , 'Origin, Access-Control-Request-Headers' ) ;
2961 c . header ( 'Access-Control-Allow-Methods' , 'GET, POST, PUT, DELETE, PATCH, OPTIONS' ) ;
30- c . header ( 'Access-Control-Allow-Headers' , 'Content-Type, Authorization' ) ;
62+ c . header ( 'Access-Control-Allow-Headers' , reqAllowedHeaders || 'Content-Type, Authorization' ) ;
3163 c . header ( 'Access-Control-Max-Age' , '86400' ) ;
3264
3365 if ( c . req . method === 'OPTIONS' ) {
0 commit comments