Socket
Socket
Sign inDemoInstall

http-proxy-middleware

Package Overview
Dependencies
43
Maintainers
1
Versions
81
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.0 to 0.5.0

37

index.js

@@ -9,3 +9,2 @@ var httpProxy = require('http-proxy');

var proxyOptions = opts || {};
var pathRewriter;

@@ -29,15 +28,22 @@ // Legacy option.proxyHost

pathRewriter = PathRewriter.create(proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
var pathRewriter = PathRewriter.create(proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
// handle option.pathRewrite
if (pathRewriter) {
proxy.on('proxyReq', function (proxyReq, req, res, options) {
var proxyReqPathRewrite = function (proxyReq, req, res, options) {
proxyReq.path = pathRewriter(proxyReq.path);
});
};
proxy.on('proxyReq', proxyReqPathRewrite);
}
// Custom listener for the `proxyRes` event on `proxy`.
if (isFunction(proxyOptions.onProxyRes)) {
proxy.on('proxyRes', proxyOptions.onProxyRes);
}
// Custom listener for the `error` event on `proxy`.
var onProxyError = getProxyErrorHandler();
// handle error and close connection properly
proxy.on('error', function (err, req, res) {
handlers.proxyError(err, req, res, proxyOptions);
});
proxy.on('error', onProxyError);
proxy.on('error', proxyErrorLogger);

@@ -83,4 +89,21 @@ // Listen for the `close` event on `proxy`.

function getProxyErrorHandler () {
if (isFunction(proxyOptions.onError)) {
return proxyOptions.onError; // custom error listener
}
return handlers.proxyError; // otherwise fall back to default
}
function proxyErrorLogger (err, req, res) {
var targetUri = proxyOptions.target.host + req.url;
console.log('[HPM] Proxy error:', err.code, targetUri);
}
function isFunction (v) {
return (v && typeof v === 'function');
}
};
module.exports = httpProxyMiddleware;

9

lib/handlers.js

@@ -5,9 +5,6 @@ module.exports = {

function proxyError (err, req, res, proxyOptions) {
var targetUri = proxyOptions.target.host + req.url;
function proxyError (err, req, res) {
var host = (req.headers && req.headers.host) || '';
res.writeHead(500);
res.end('Error occured while trying to proxy to: '+ proxyOptions.target.host + req.url);
console.log('[HPM] Proxy error:', err.code, targetUri);
res.end('Error occured while trying to proxy to: '+ host + req.url);
};
{
"name": "http-proxy-middleware",
"version": "0.4.0",
"description": "The one-liner proxy middleware for connect, express and browser-sync",
"version": "0.5.0",
"description": "The one-liner node.js proxy middleware for connect, express and browser-sync",
"main": "index.js",

@@ -6,0 +6,0 @@ "scripts": {

@@ -7,3 +7,3 @@ # http-proxy-middleware

The one-liner proxy middleware for [connect](https://github.com/senchalabs/connect), [express](https://github.com/strongloop/express) and [browser-sync](https://github.com/BrowserSync/browser-sync)
The one-liner node.js proxy middleware for [connect](https://github.com/senchalabs/connect), [express](https://github.com/strongloop/express) and [browser-sync](https://github.com/BrowserSync/browser-sync)

@@ -32,3 +32,3 @@ ### Install

* **options.target**: target host to proxy to.
Check out available [proxy options](#options).
Check out available [proxy middleware options](#options).

@@ -48,3 +48,7 @@

target: 'http://www.example.org', // target host
changeOrigin: true // needed for virtual hosted sites
changeOrigin: true, // needed for virtual hosted sites
ws: true, // proxy websockets
pathRewrite: {
'^/old/api' : '/new/api' // rewrite paths
}
};

@@ -61,6 +65,27 @@

See [more examples](#more-examples).
See [working examples](#more-examples).
**Tip:** For [name-based virtual hosted sites](http://en.wikipedia.org/wiki/Virtual_hosting#Name-based), you'll need to use the option `changeOrigin` and set it to `true`.
### Context matching
http-proxy-middleware offers several ways to decide which requests should be proxied.
Request URL's [ _path-absolute_ and _query_](https://tools.ietf.org/html/rfc3986#section-3) will be used for context matching .
* path matching
* `'/'` - matches any path, all requests will be proxied.
* `'/api'` - matches paths starting with `/api`
* multiple path matching
* `['/api','/ajax','/someotherpath']`
* wildcard path matching
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
* `**` matches any path, all requests will be proxied.
* `**/*.html` matches any path which ends with `.html`
* `/*.html` matches paths directly under path-absolute
* `/api/**/*.html` matches requests ending with `.html` in the path of `/api`
* `['/api/**', '/ajax/**']` combine multiple patterns
* `['/api/**', '!**/bad.json']` exclusion
### Compatible servers:

@@ -74,6 +99,3 @@ http-proxy-middleware is compatible with the following servers:

### Options
* (DEPRECATED) **option.proxyHost**: Use `option.changeOrigin = true` instead.
* **option.pathRewrite**: object, rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
```javascript

@@ -86,2 +108,21 @@ {

* **option.onError**: function, subscribe to http-proxy's error event for custom error handling.
```javascript
function onError (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.');
}
```
* **option.onProxyRes**: function, subscribe to http-proxy's proxyRes event.
```javascript
function (proxyRes, req, res) {
proxyRes.headers['x-added'] = 'foobar'; // add new header to response
delete proxyRes.headers['x-removed']; // remove header from response
}
```
* (DEPRECATED) **option.proxyHost**: Use `option.changeOrigin = true` instead.
The following options are provided by the underlying [http-proxy](https://www.npmjs.com/package/http-proxy).

@@ -95,3 +136,3 @@ * **option.target**: url string to be parsed with the url module

* **option.hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
* **option.ssl: object to be passed to https.createServer()
* **option.ssl**: object to be passed to https.createServer()
* **option.ws: true/false**: if you want to proxy websockets

@@ -110,24 +151,2 @@

### Context matching
Request URL's [ _path-absolute_ and _query_](https://tools.ietf.org/html/rfc3986#section-3) will be used for context matching .
* URL: `http://example.com:8042/over/there?name=ferret#nose`
* context: `/over/there?name=ferret`
http-proxy-middleware offers several ways to decide which requests should be proxied:
* path matching
* `'/'` - matches any path, all requests will be proxied.
* `'/api'` - matches paths starting with `/api`
* multiple path matching
* `['/api','/ajax','/someotherpath']`
* wildcard path matching
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
* `**` matches any path, all requests will be proxied.
* `**/*.html` matches any path which ends with `.html`
* `/*.html` matches paths directly under path-absolute
* `/api/**/*.html` matches requests ending with `.html` in the path of `/api`
* `['/api/**', '/ajax/**']` combine multiple patterns
* `['/api/**', '!**/bad.json']` exclusion
### More Examples

@@ -150,6 +169,6 @@

Or just explore the proxy examples' sources:
* `examples/connect` - [connect proxy middleware example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect)
* `examples/express` - [express proxy middleware example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express)
* `examples/browser-sync` - [browser-sync proxy middleware example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync)
* `examples/websocket` - [websocket proxy example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket) with express
* `examples/connect` - [connect proxy middleware example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect/index.js)
* `examples/express` - [express proxy middleware example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express/index.js)
* `examples/browser-sync` - [browser-sync proxy middleware example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync/index.js)
* `examples/websocket` - [websocket proxy example](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket/index.js) with express

@@ -169,2 +188,3 @@ ### Tests

### Changlog
* [v0.5.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.5.0) - support subscribing to http-proxy error- and proxyRes-event
* [v0.4.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.4.0) - support websocket

@@ -171,0 +191,0 @@ * [v0.3.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.3.0) - support wildcard / glob

@@ -9,2 +9,7 @@ var expect = require('chai').expect;

it('should match all paths', function () {
result = contextMatcher.match('', 'http://localhost/api/foo/bar');
expect(result).to.be.true;
});
it('should match all paths starting with forward-slash', function () {
result = contextMatcher.match('/', 'http://localhost/api/foo/bar');

@@ -11,0 +16,0 @@ expect(result).to.be.true;

@@ -11,2 +11,5 @@ var expect = require('chai').expect;

var mockReq = {
headers : {
host : 'localhost:3000'
},
url : '/api'

@@ -43,5 +46,5 @@ };

it('should end the response and return error message', function () {
expect(errorMessage).to.equal('Error occured while trying to proxy to: localhost.dev/api');
expect(errorMessage).to.equal('Error occured while trying to proxy to: localhost:3000/api');
});
});

@@ -255,3 +255,3 @@ var expect = require('chai').expect;

describe('additional request headers', function () {
describe('option.headers - additional request headers', function () {
var proxyServer, targetServer;

@@ -286,3 +286,3 @@ var targetHeaders;

describe('legacy proxyHost parameter', function () {
describe('legacy option.proxyHost', function () {
var proxyServer, targetServer;

@@ -318,16 +318,96 @@ var targetHeaders;

describe('Error handling', function () {
describe('option.onError - Error handling', function () {
var proxyServer, targetServer;
var response;
var response, responseBody;
describe('default', function () {
beforeEach(function (done) {
var mw_proxy = proxyMiddleware('/api', {target:'http://localhost:666'}); // unreachable host on port:666
var mw_target = function (req, res, next) {next()};
proxyServer = createServer(3000, mw_proxy);
targetServer = createServer(8000, mw_target);
http.get('http://localhost:3000/api/', function (res) {
response = res;
done();
});
});
afterEach(function () {
proxyServer.close();
targetServer.close();
});
it('should handle errors when host is not reachable', function () {
expect(response.statusCode).to.equal(500);
});
});
describe('custom', function () {
beforeEach(function (done) {
var customOnError = function (err, req, res) {
res.writeHead(418); // different error code
res.end("I'm a teapot"); // no response body
};
var mw_proxy = proxyMiddleware('/api', {target:'http://localhost:666', onError: customOnError}); // unreachable host on port:666
var mw_target = function (req, res, next) {next()};
proxyServer = createServer(3000, mw_proxy);
targetServer = createServer(8000, mw_target);
http.get('http://localhost:3000/api/', function (res) {
response = res;
res.on('data', function (chunk) {
responseBody = chunk.toString();
done();
});
});
});
afterEach(function () {
proxyServer.close();
targetServer.close();
});
it('should respond with custom http status code', function () {
expect(response.statusCode).to.equal(418);
});
it('should respond with custom status message', function () {
expect(responseBody).to.equal("I'm a teapot");
});
});
});
describe('option.onProxyRes', function () {
var proxyServer, targetServer;
var response, responseBody;
beforeEach(function (done) {
var mw_proxy = proxyMiddleware('/api', {target:'http://localhost:666'}); // unreachable host on port:666
var mw_target = function (req, res, next) {next()};
var fnOnProxyRes = function (proxyRes, req, res) {
proxyRes.headers['x-added'] = 'foobar'; // add custom header to response
delete proxyRes.headers['x-removed'];
};
var mw_proxy = proxyMiddleware('/api', {
target:'http://localhost:8000',
onProxyRes: fnOnProxyRes
});
var mw_target = function (req, res, next) {
res.setHeader('x-removed', 'remove-header');
res.write(req.url); // respond with req.url
res.end();
};
proxyServer = createServer(3000, mw_proxy);
targetServer = createServer(8000, mw_target);
http.get('http://localhost:3000/api/', function (res) {
http.get('http://localhost:3000/api/foo/bar', function (res) {
response = res;
done();
res.on('data', function (chunk) {
responseBody = chunk.toString();
done();
});
});

@@ -341,9 +421,12 @@ });

it('should add `x-added` as custom header to response"', function () {
expect(response.headers['x-added']).to.equal('foobar');
});
it('should handle errors when host is not reachable', function () {
expect(response.statusCode).to.equal(500);
it('should remove `x-removed` field from response header"', function () {
expect(response.headers['x-removed']).to.equal(undefined);
});
});
describe('Rewrite path', function () {
describe('option.pathRewrite', function () {
var proxyServer, targetServer;

@@ -350,0 +433,0 @@ var responseBody;

@@ -8,3 +8,3 @@ var expect = require('chai').expect;

describe('websocket proxy', function () {
describe('option.ws - WebSocket proxy', function () {
var proxyServer, ws, wss;

@@ -11,0 +11,0 @@ var targetHeaders;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc