@@ -3,6 +3,8 @@ const TOKEN_COOKIE_NAME = 'oc_preview_token';
33const TOKEN_QUERY_PARAM = 'oc_preview_token' ;
44const CLIENT_TOKEN_QUERY_PARAM = 'oc_client_token' ;
55const URL_AUTH_TOKEN_QUERY_PARAM = 'oc_url_token' ;
6+ const PREVIEW_PASSTHROUGH_REQUEST_HEADERS = [ 'x-inertia' , 'x-inertia-version' ] ;
7+ const PREVIEW_PASSTHROUGH_RESPONSE_HEADERS = [ 'x-inertia' , 'x-inertia-location' ] ;
68
79const LOOPBACK_HOSTS = new Set ( [
810 'localhost' ,
@@ -25,6 +27,34 @@ const parsePreviewResourcePath = (url) => {
2527 }
2628} ;
2729
30+ const readHeader = ( headers , name ) => {
31+ if ( ! headers || typeof headers !== 'object' ) return undefined ;
32+ const direct = headers [ name ] ;
33+ if ( direct !== undefined ) return direct ;
34+ const lowerName = name . toLowerCase ( ) ;
35+ const key = Object . keys ( headers ) . find ( ( entry ) => entry . toLowerCase ( ) === lowerName ) ;
36+ return key ? headers [ key ] : undefined ;
37+ } ;
38+
39+ export const applyPreviewPassthroughRequestHeaders = ( req , proxyReq ) => {
40+ for ( const headerName of PREVIEW_PASSTHROUGH_REQUEST_HEADERS ) {
41+ const value = readHeader ( req ?. headers , headerName ) ;
42+ if ( value !== undefined ) {
43+ proxyReq . setHeader ( headerName , value ) ;
44+ }
45+ }
46+ } ;
47+
48+ export const applyPreviewPassthroughResponseHeaders = ( proxyRes , res ) => {
49+ if ( ! res || res . headersSent || typeof res . setHeader !== 'function' ) return ;
50+ for ( const headerName of PREVIEW_PASSTHROUGH_RESPONSE_HEADERS ) {
51+ const value = readHeader ( proxyRes ?. headers , headerName ) ;
52+ if ( value !== undefined ) {
53+ res . setHeader ( headerName , value ) ;
54+ }
55+ }
56+ } ;
57+
2858const previewResourceNoiseRuleSets = [
2959 {
3060 name : 'vite' ,
@@ -1412,14 +1442,16 @@ export const createPreviewProxyRuntime = ({
14121442 return `${ strippedPath } ${ withoutUrlAuthToken } ` ;
14131443 } ,
14141444 on : {
1415- proxyReq : ( proxyReq ) => {
1445+ proxyReq : ( proxyReq , req ) => {
1446+ applyPreviewPassthroughRequestHeaders ( req , proxyReq ) ;
14161447 // Keep local dev servers from receiving OpenChamber credentials.
14171448 proxyReq . removeHeader ( 'cookie' ) ;
14181449 proxyReq . removeHeader ( 'authorization' ) ;
14191450 proxyReq . removeHeader ( 'x-openchamber-ui-session' ) ;
14201451 proxyReq . setHeader ( 'accept-encoding' , 'identity' ) ;
14211452 } ,
1422- proxyRes : responseInterceptor ( async ( responseBuffer , proxyRes , req ) => {
1453+ proxyRes : responseInterceptor ( async ( responseBuffer , proxyRes , req , res ) => {
1454+ applyPreviewPassthroughResponseHeaders ( proxyRes , res ) ;
14231455 // Per-response nonce lets the injected bridge run under the dev
14241456 // server's CSP without dropping its script restrictions wholesale.
14251457 const bridgeNonce = crypto . randomBytes ( 16 ) . toString ( 'base64' ) ;
0 commit comments