1import { parse } from 'url'; 2 3import { disableResponseCache, ExpoMiddleware } from './ExpoMiddleware'; 4import { 5 assertMissingRuntimePlatform, 6 assertRuntimePlatform, 7 parsePlatformHeader, 8 resolvePlatformFromUserAgentHeader, 9 RuntimePlatform, 10} from './resolvePlatform'; 11import { ServerRequest, ServerResponse } from './server.types'; 12import * as Log from '../../../log'; 13 14const debug = require('debug')( 15 'expo:start:server:middleware:runtimeRedirect' 16) as typeof console.log; 17 18/** Runtime to target: expo = Expo Go, custom = Dev Client. */ 19type RuntimeTarget = 'expo' | 'custom'; 20 21export type DeepLinkHandler = (props: { 22 runtime: RuntimeTarget; 23 platform: RuntimePlatform; 24}) => void | Promise<void>; 25 26export class RuntimeRedirectMiddleware extends ExpoMiddleware { 27 constructor( 28 protected projectRoot: string, 29 protected options: { 30 onDeepLink: DeepLinkHandler; 31 getLocation: (props: { runtime: RuntimeTarget }) => string | null | undefined; 32 } 33 ) { 34 super(projectRoot, ['/_expo/link']); 35 } 36 37 async handleRequestAsync(req: ServerRequest, res: ServerResponse): Promise<void> { 38 const { query } = parse(req.url!, true); 39 const isDevClient = query['choice'] === 'expo-dev-client'; 40 const platform = parsePlatformHeader(req) ?? resolvePlatformFromUserAgentHeader(req); 41 assertMissingRuntimePlatform(platform); 42 assertRuntimePlatform(platform); 43 const runtime = isDevClient ? 'custom' : 'expo'; 44 45 debug(`props:`, { platform, runtime }); 46 47 this.options.onDeepLink({ runtime, platform }); 48 49 const redirect = this.options.getLocation({ runtime }); 50 if (!redirect) { 51 Log.warn( 52 `[redirect middleware]: Unable to determine redirect location for runtime '${runtime}' and platform '${platform}'` 53 ); 54 res.statusCode = 404; 55 res.end(); 56 return; 57 } 58 debug('Redirect ->', redirect); 59 res.setHeader('Location', redirect); 60 61 // Disable caching 62 disableResponseCache(res); 63 64 // 'Temporary Redirect' 65 res.statusCode = 307; 66 res.end(); 67 } 68} 69