import * as express from 'express' ; import proxy from 'http-proxy-middleware' ; import { URL , URLSearchParams } from 'url' ; export function _extractUrlFromReferer ( proxyPrefix , referer = '' ) { const index = referer . indexOf ( proxyPrefix ) ; return index > - 1 ? referer . substr ( index + proxyPrefix . length ) : '' ; } export function _trimProxyPrefix ( proxyPrefix , path ) { return path . indexOf ( proxyPrefix ) === 0 ? ( path = path . substr ( proxyPrefix . length ) ) : path ; } export function _routePathWithReferer ( proxyPrefix , path , referer = '' ) { const proxiedUrlInReferer = _extractUrlFromReferer ( proxyPrefix , referer ) ; let decodedPath = decodeURIComponent ( proxiedUrlInReferer || _trimProxyPrefix ( proxyPrefix , path ) ) ; if ( ! decodedPath . startsWith ( 'http://' ) && ! decodedPath . startsWith ( 'https://' ) ) { decodedPath = 'http://' + decodedPath ; } return new URL ( decodedPath ) . origin ; } export function _rewritePath ( proxyPrefix , path , query ) { const querystring = new URLSearchParams ( query ) . toString ( ) ; const decodedPath = decodeURIComponent ( path ) ; return _trimProxyPrefix ( proxyPrefix , decodedPath ) + ( querystring && '?' + querystring ) ; } export default ( app , apisPrefix ) => { const proxyPrefix = apisPrefix + '/_proxy/' ; app . use ( ( req , _ , next ) => { if ( req . headers . referer ) { const refererUrl = _extractUrlFromReferer ( proxyPrefix , req . headers . referer as string ) ; if ( refererUrl && req . url . indexOf ( proxyPrefix ) !== 0 ) { let proxiedUrl = decodeURIComponent ( _extractUrlFromReferer ( proxyPrefix , req . headers . referer as string ) ) ; if ( ! proxiedUrl . startsWith ( 'http://' ) && ! proxiedUrl . startsWith ( 'https://' ) ) { proxiedUrl = 'http://' + proxiedUrl ; } const proxiedOrigin = new URL ( proxiedUrl ) . origin ; req . url = proxyPrefix + encodeURIComponent ( proxiedOrigin + req . url ) ; } } next ( ) ; } ) ; app . all ( proxyPrefix + '*' , proxy ( { changeOrigin : true , logLevel : 'debug' , target : 'http://127.0.0.1' , router : ( req ) => { return _routePathWithReferer ( proxyPrefix , req . path , req . headers . referer as string ) ; } , pathRewrite : ( _ , req ) => { return _rewritePath ( proxyPrefix , req . path , req . query ) ; } , } ) ) ; } ;