It would be great to know what I did wrong specifically, but short of that I'd love to know how to print out whatever the real path-rewrite actually is. I tried setting DEBUG=express-http-proxy, but didn't get anything helpful. It seems the proxy-forwarding has a strong declarative syntax, but I haven't found a was to print out what the final result is.
My Node/Express/Middleware server is trying to forward any and all requests starting with /spreadsheet-upload/* to an angular server provided the caller begins with /spreadsheet-upload. For example, if someone points a browser to https://localhost/spreadsheet-upload/page-1, the angular server should serve page-1. Basically strip off the /spreadsheet-upload portion and then send it to a server with host name config.spreadsheet_client_host.
I'm getting a 200 return code, but I'm getting a blank page and there's this error in the browser's console:
Angular is running in the development mode. Call enableProdMode() to enable the production mode. vendor.js:41938:17
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'spreadsheet-upload'
./node_modules/@angular/router/fesm5/router.js/ApplyRedirects.prototype.noMatchError@https://localhost:8080/vendor.js:68322:16
./node_modules/@angular/router/fesm5/router.js/ApplyRedirects.prototype.apply/<@https://localhost:8080/vendor.js:68303:29
./node_modules/rxjs/_esm5/internal/operators/catchError.js/CatchSubscriber.prototype.error@https://localhost:8080/vendor.js:82540:31
./node_modules/rxjs/_esm5/internal/Subscriber.js/Subscriber.prototype._error@https://localhost:8080/vendor.js:77522:26
./node_modules/rxjs/_esm5/internal/Subscriber.js/Subscriber.prototype.error@https://localhost:8080/vendor.js:77496:18
./node_modules/rxjs/_esm5/internal/Subscriber.js/Subscriber.prototype._error@https://localhost:8080/vendor.js:77522:26
./node_modules/rxjs/_esm5/internal/Subscriber.js/Subscriber.prototype.error@https://localhost:8080/vendor.js:77496:18
./node_modules/rxjs/_esm5/internal/Subscriber.js/Subscr…
resolvePromise https://localhost:8080/polyfills.js:3170
resolvePromise https://localhost:8080/polyfills.js:3127
scheduleResolveOrReject https://localhost:8080/polyfills.js:3231
invokeTask https://localhost:8080/polyfills.js:2762
onInvokeTask https://localhost:8080/vendor.js:42628
invokeTask https://localhost:8080/polyfills.js:2761
runTask https://localhost:8080/polyfills.js:2534
drainMicroTaskQueue https://localhost:8080/polyfills.js:2940
The forwarding snippet is:
app.use(['/spreadsheet-upload', '/spreadsheet-upload/*'], ensureAuthenticated,
function (req, res, next) {
logger.debug('Route for spreadsheet-upload originalUrl=' + req.originalUrl + ': Forwarding to ' + config.spreadsheet_client_host);
next();
},
createProxyMiddleware({
target: config.spreadsheet_client_host,
changeOrigin: true,
limit: "4mb",
memoizeHost: false,
preserveHostHdr: true,
https: false,
secure: false,
proxyErrorHandler: function (err, res, next) {
util.inspect(err);
next();
},
logLevel: 'debug',
onProxyReq: function (proxyReq, req, rsp) {
Object.keys(req.headers).forEach(function (key) {
proxyReq.setHeader(key, req.headers[key]);
});
var accessToken = generateToken(req.user);
/**
* Set bearer token based on code from Sprint-API's lua code
*/
proxyReq.setHeader('Authorization', 'Bearer ' + accessToken);
},
onProxyRes: function onProxyRes(proxyRes, req, res) {
Object.keys(proxyRes.headers).forEach(function (key) {
res.append(key, proxyRes.headers[key]);
});
},
pathRewrite: {
'^\/spreadsheet-upload\/': '/'
}
})
);
I used to have
router: {
'.*:8080': config.spreadsheet_client_host
}
in the createProxyMiddleware, but read on stackoverflow that it's not supported.
This snippet actually works:
app.use('/sprint-cost-recovery*', ensureAuthenticated,
function (req, res, next) {
logger.debug('Route: ' + req.originalUrl + ': Forwarding to ' + config.sprint_cost_recovery_client_host);
next();
},
forward_proxy(config.sprint_cost_recovery_client_host, {
limit: '2mb',
memoizeHost: false,
preserveHostHdr: true,
https: false,
secure: false,
proxyErrorHandler: function (err, res, next) {
util.inspect(err);
next();
},
proxyReqPathResolver: req => {
logger.debug('Route: /sprint-cost-recovery: proxyReqPathResolver() function reached');
util.inspect(req.originalUrl);
util.inspect(req.hostname);
util.inspect(req.https_port);
const result = url.parse(req.originalUrl).path;
logger.debug('Route: /sprint-cost-recovery: proxyReqPathResolver(): result=' + result);
return result;
}
})
);