Skip to content

Commit 3b179bc

Browse files
authored
fix(Express sub Router): 404 on non-proxy routes (#98)
1 parent 306fdd4 commit 3b179bc

File tree

3 files changed

+87
-5
lines changed

3 files changed

+87
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## [v0.18.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.18.0)
4+
- fix(Express sub Router): 404 on non-proxy routes ([#94](https://github.com/chimurai/http-proxy-middleware/issues/94))
5+
36
## [v0.17.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.0)
47
- fix(context matching): Use [RFC 3986 path](https://tools.ietf.org/html/rfc3986#section-3.3) in context matching. (excludes query parameters)
58

lib/index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ function HttpProxyMiddleware(context, opts) {
3535
return middleware;
3636

3737
function middleware(req, res, next) {
38-
// https://github.com/chimurai/http-proxy-middleware/issues/17
39-
req.url = req.originalUrl;
40-
41-
if (contextMatcher.match(config.context, req.url, req)) {
38+
if (shouldProxy(config.context, req)) {
4239
var activeProxyOptions = prepareProxyRequest(req);
4340
proxy.web(req, res, activeProxyOptions);
4441
} else {
@@ -55,20 +52,35 @@ function HttpProxyMiddleware(context, opts) {
5552
}
5653

5754
function handleUpgrade(req, socket, head) {
58-
if (contextMatcher.match(config.context, req.url, req)) {
55+
if (shouldProxy(config.context, req)) {
5956
var activeProxyOptions = prepareProxyRequest(req);
6057
proxy.ws(req, socket, head, activeProxyOptions);
6158
logger.info('[HPM] Upgrading to WebSocket');
6259
}
6360
}
6461

62+
/**
63+
* Determine whether request should be proxied.
64+
*
65+
* @private
66+
* @return {Boolean}
67+
*/
68+
function shouldProxy(context, req) {
69+
var path = (req.originalUrl || req.url);
70+
return contextMatcher.match(context, path, req);
71+
}
72+
6573
/**
6674
* Apply option.router and option.pathRewrite
6775
* Order matters:
6876
Router uses original path for routing;
6977
NOT the modified path, after it has been rewritten by pathRewrite
7078
*/
7179
function prepareProxyRequest(req) {
80+
// https://github.com/chimurai/http-proxy-middleware/issues/17
81+
// https://github.com/chimurai/http-proxy-middleware/issues/94
82+
req.url = (req.originalUrl || req.url);
83+
7284
// store uri before it gets rewritten for logging
7385
var originalPath = req.url;
7486
var newProxyOptions = _.cloneDeep(proxyOptions);

test/e2e/express-router.spec.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
var express = require('express');
2+
var expect = require('chai').expect;
3+
var http = require('http');
4+
var proxy = require('../../index');
5+
6+
describe('Usage in Express', function() {
7+
8+
var app;
9+
var server;
10+
11+
beforeEach(function() {
12+
app = express();
13+
});
14+
15+
afterEach(function() {
16+
server && server.close();
17+
});
18+
19+
// https://github.com/chimurai/http-proxy-middleware/issues/94
20+
describe('Express Sub Route', function() {
21+
22+
beforeEach(function() {
23+
24+
// sub route config
25+
var sub = new express.Router();
26+
27+
function filter(pathname, req) {
28+
var urlFilter = new RegExp('^/sub/api');
29+
var match = urlFilter.test(pathname);
30+
return match;
31+
}
32+
33+
/**
34+
* Mount proxy without 'path' in sub route
35+
*/
36+
var proxyConfig = {target: 'http://jsonplaceholder.typicode.com', changeOrigin: true, logLevel: 'silent'};
37+
sub.use(proxy(filter, proxyConfig));
38+
39+
sub.get('/hello', jsonMiddleware({'content': 'foobar'}));
40+
41+
// configure sub route on /sub junction
42+
app.use('/sub', sub);
43+
44+
// start server
45+
server = app.listen(3000);
46+
});
47+
48+
it('should still return a response when route does not match proxyConfig', function(done) {
49+
var responseBody;
50+
http.get('http://localhost:3000/sub/hello', function(res) {
51+
res.on('data', function(chunk) {
52+
responseBody = chunk.toString();
53+
expect(responseBody).to.equal('{"content":"foobar"}');
54+
done();
55+
});
56+
});
57+
});
58+
59+
});
60+
61+
function jsonMiddleware(data) {
62+
return function(req, res) {
63+
res.json(data);
64+
};
65+
}
66+
67+
});

0 commit comments

Comments
 (0)