1import { parsePlatformHeader } from './resolvePlatform'; 2import { ServerNext, ServerRequest, ServerResponse } from './server.types'; 3 4const debug = require('debug')('expo:start:server:metro:historyFallback') as typeof console.log; 5 6const WS_DEVICE_URL = '/inspector/device'; 7const WS_DEBUGGER_URL = '/inspector/debug'; 8const PAGES_LIST_JSON_URL = '/json'; 9const PAGES_LIST_JSON_URL_2 = '/json/list'; 10const PAGES_LIST_JSON_VERSION_URL = '/json/version'; 11 12export function isInspectorProxyRequest(req: ServerRequest) { 13 const ua = req.headers['user-agent']; 14 const url = req.url; 15 16 // This check is very fragile but it enables websites to use any of the 17 // endpoints below without triggering the inspector proxy. 18 if (!url || (ua && !ua.includes('node-fetch'))) { 19 // This optimizes for the inspector working over the endpoint being available on web. 20 // Web is less fragile. 21 return false; 22 } 23 24 return [ 25 WS_DEVICE_URL, 26 WS_DEBUGGER_URL, 27 PAGES_LIST_JSON_URL, 28 PAGES_LIST_JSON_URL_2, 29 PAGES_LIST_JSON_VERSION_URL, 30 ].includes(url); 31} 32 33/** 34 * Create a web-only middleware which redirects to the index middleware without losing the path component. 35 * This is useful for things like React Navigation which need to render the index.html and then direct the user in-memory. 36 */ 37export class HistoryFallbackMiddleware { 38 constructor( 39 private indexMiddleware: ( 40 req: ServerRequest, 41 res: ServerResponse, 42 next: ServerNext 43 ) => Promise<void> 44 ) {} 45 getHandler() { 46 return (req: ServerRequest, res: ServerResponse, next: any) => { 47 const platform = parsePlatformHeader(req); 48 49 if (!platform || platform === 'web') { 50 if (isInspectorProxyRequest(req)) { 51 debug('Inspector proxy request:', req.url, 'UA:', req.headers['user-agent']); 52 return next(); 53 } 54 // Redirect unknown to the manifest handler while preserving the path. 55 // This implements the HTML5 history fallback API. 56 return this.indexMiddleware(req, res, next); 57 } 58 59 return next(); 60 }; 61 } 62} 63