Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Also forward error requests to the proxy #2425

Merged
merged 1 commit into from
Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ class Server {
this.websocketProxies.push(proxyMiddleware);
}

this.app.use((req, res, next) => {
const handle = (req, res, next) => {
if (typeof proxyConfigOrCallback === 'function') {
const newProxyConfig = proxyConfigOrCallback();

Expand Down Expand Up @@ -319,7 +319,11 @@ class Server {
} else {
next();
}
});
};

this.app.use(handle);
// Also forward error requests to the proxy so it can handle them.
this.app.use((error, req, res, next) => handle(req, res, next));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is create two instances of proxy that was reduce performance

Copy link
Contributor Author

@OliverJAsh OliverJAsh Feb 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proxy middleware is created once, outside of handle:

      proxyMiddleware = getProxyMiddleware(proxyConfig);

… and the result is used in handle on each request, be it a non-error or error request. So I don't think this change will hurt performance in any way.

If you really think this will hurt performance, are you able to provide an example to demonstrate that's the case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each request now run handle (

const handle = (req, res, next) => {
) twice so we potentially send require to middleware twice
return proxyMiddleware(req, res, next);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe that's true. handle will only run once:

  • If the request has not errored, handle will be called via app.use(handle).
  • If the request has errored, handle will be called via app.use((error, req, res, next) => handle(req, res, next)).

You can see this for yourself if you add some logging to handle.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

});
}

Expand Down
17 changes: 17 additions & 0 deletions test/server/proxy-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,19 @@ describe('proxy option', () => {
// Parse application/json
proxy.use(bodyParser.json());

// This forces Express to try to decode URLs, which is needed for the test
// associated with the middleware below.
proxy.all('*', (_req, res, next) => {
next();
});
// We must define all 4 params in order for this to be detected as an
// error handling middleware.
// eslint-disable-next-line no-unused-vars
proxy.use((error, proxyReq, res, next) => {
res.status(500);
res.send('error from proxy');
});

proxy.get('/get', (proxyReq, res) => {
res.send('GET method from proxy');
});
Expand Down Expand Up @@ -372,6 +385,10 @@ describe('proxy option', () => {
});
});

it('errors', (done) => {
req.get('/%').expect(500, 'error from proxy', done);
});

it('GET method', (done) => {
req.get('/get').expect(200, 'GET method from proxy', done);
});
Expand Down