1

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;
            }
        })
    );

Woodsman
  • 427
  • 4
  • 18

0 Answers0