@@ -603,6 +603,7 @@ const routeActionRegistry = new Map<string, RouterAction>()
603603/** HTTP methods that mutate state and therefore need CSRF protection. */
604604const CSRF_PROTECTED_METHODS = new Set ( [ 'POST' , 'PUT' , 'PATCH' , 'DELETE' ] )
605605const CSRF_SEEDED_BY_HANDLE_REQUEST = Symbol . for ( 'stacks.router.csrfSeededByHandleRequest' )
606+ const FRAMEWORK_SECURITY_HEADERS_MISSING = Symbol ( 'stacks.router.frameworkSecurityHeadersMissing' )
606607
607608interface ResolvedMiddleware {
608609 name : string
@@ -2015,7 +2016,9 @@ function createMiddlewareHandler(routeKey: string, handler: StacksHandler): Rout
20152016 }
20162017 h . set ( 'Server-Timing' , timing )
20172018 }
2018- applySecurityHeaders ( h )
2019+ const frameworkHeadersAreMissing = ( response as unknown as Record < symbol , unknown > ) [ FRAMEWORK_SECURITY_HEADERS_MISSING ] === true
2020+ && ! requested
2021+ applySecurityHeaders ( h , frameworkHeadersAreMissing )
20192022 }
20202023
20212024 if ( response && typeof ( response ) . headers ?. set === 'function' ) {
@@ -2936,8 +2939,11 @@ function formatResult(result: unknown, req: EnhancedRequest): Response {
29362939/** Serialize JSON once and make its size available to compression. */
29372940function formatJsonResult ( result : unknown , req : EnhancedRequest , linkHeader ?: string | null ) : Response {
29382941 const encoding = req . headers . get ( 'accept-encoding' )
2939- if ( ! encoding || encoding === 'identity' )
2940- return linkHeader ? Response . json ( result , { headers : { Link : linkHeader } } ) : Response . json ( result )
2942+ if ( ! encoding || encoding === 'identity' ) {
2943+ const response = linkHeader ? Response . json ( result , { headers : { Link : linkHeader } } ) : Response . json ( result )
2944+ ; ( response as unknown as Record < symbol , unknown > ) [ FRAMEWORK_SECURITY_HEADERS_MISSING ] = true
2945+ return response
2946+ }
29412947
29422948 // Give compression the byte length without making it consume and rebuild
29432949 // the response stream just to check its threshold. Count UTF-8 bytes, not
@@ -2949,7 +2955,9 @@ function formatJsonResult(result: unknown, req: EnhancedRequest, linkHeader?: st
29492955 }
29502956 if ( linkHeader )
29512957 headers . Link = linkHeader
2952- return new Response ( body , { headers } )
2958+ const response = new Response ( body , { headers } )
2959+ ; ( response as unknown as Record < symbol , unknown > ) [ FRAMEWORK_SECURITY_HEADERS_MISSING ] = true
2960+ return response
29532961}
29542962
29552963/**
0 commit comments