Socket
Socket
Sign inDemoInstall

express-http-proxy

Package Overview
Dependencies
Maintainers
3
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-http-proxy - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

app/steps/handleProxyErrors.js

2

app/steps/decorateUserRes.js

@@ -13,3 +13,3 @@ 'use strict';

return function(rspData, res) {
return (isResGzipped(res)) ? zlib[method](rspData) : rspData;
return (isResGzipped(res) && rspData.length) ? zlib[method](rspData) : rspData;
};

@@ -16,0 +16,0 @@ }

@@ -13,6 +13,7 @@ 'use strict';

.then(function(shouldSkipToNext) {
return (shouldSkipToNext) ? Promise.reject() : Promise.resolve(container);
});
return (shouldSkipToNext) ? container.user.next() : Promise.resolve(container);
})
.catch(Promise.reject);
}
module.exports = maybeSkipToNextHandler;

@@ -7,3 +7,2 @@ 'use strict';

var req = Container.user.req;
var res = Container.user.res;
var bodyContent = Container.proxy.bodyContent;

@@ -16,2 +15,7 @@ var reqOpt = Container.proxy.reqBuilder;

var proxyReq = protocol.request(reqOpt, function(rsp) {
if (options.stream) {
Container.proxy.res = rsp;
return resolve(Container);
}
var chunks = [];

@@ -35,15 +39,3 @@ rsp.on('data', function(chunk) { chunks.push(chunk); });

// TODO: do reject here and handle this later on
proxyReq.on('error', function(err) {
// reject(error);
if (err.code === 'ECONNRESET') {
res.setHeader('X-Timout-Reason',
'express-http-proxy timed out your request after ' +
options.timeout + 'ms.');
res.writeHead(504, {'Content-Type': 'text/plain'});
res.end();
} else {
reject(err);
}
});
proxyReq.on('error', reject);

@@ -62,3 +54,14 @@ // this guy should go elsewhere, down the chain

if (bodyContent.length) {
proxyReq.write(bodyContent);
var body = bodyContent;
var contentType = proxyReq.getHeader('Content-Type');
if (contentType === 'x-www-form-urlencoded' || contentType === 'application/x-www-form-urlencoded') {
try {
var params = JSON.parse(body);
body = Object.keys(params).map(function(k) { return k + '=' + params[k]; }).join('&');
} catch (e) {
// bodyContent is not json-format
}
}
proxyReq.setHeader('Content-Length', Buffer.byteLength(body));
proxyReq.write(body);
}

@@ -65,0 +68,0 @@ proxyReq.end();

@@ -5,3 +5,7 @@ 'use strict';

if (!Container.user.res.headersSent) {
Container.user.res.send(Container.proxy.resData);
if (Container.options.stream) {
Container.proxy.res.pipe(Container.user.res);
} else {
Container.user.res.send(Container.proxy.resData);
}
}

@@ -8,0 +12,0 @@ return Promise.resolve(Container);

'use strict';
// ROADMAP: Major refactoring April 2017
// It would be easier to follow if we extract to simpler functions, and used
// a standard, step-wise set of filters with clearer edges and borders. It
// would be more useful if authors could use Promises for all over-rideable
// steps.
// * Breaks proxying into a series of discrete steps, many of which can be swapped out by authors.
// * Uses Promises to support async.
// * Uses a quasi-Global called Container to tidy up the argument passing between the major work-flow steps.
// complete: Break workflow into composable steps without changing them much
// complete: extract workflow methods from main file
// complete: cleanup options interface
// complete: change hook names to be different than the workflow steps.
// *: cleanup host is processed twice
// *: cleanup workflow methods so they all present as over-rideable thennables
// *: Update/add tests to unit test workflow steps independently
// complete: update docs and release

@@ -28,2 +18,3 @@ var ScopeContainer = require('./lib/scopeContainer');

var decorateUserResHeaders = require('./app/steps/decorateUserResHeaders');
var handleProxyErrors = require('./app/steps/handleProxyErrors');
var maybeSkipToNextHandler = require('./app/steps/maybeSkipToNextHandler');

@@ -59,4 +50,10 @@ var prepareProxyReq = require('./app/steps/prepareProxyReq');

.then(sendUserRes)
.catch(next);
.catch(function(err) {
var resolver = (container.options.proxyErrorHandler) ?
container.options.proxyErrorHandler :
handleProxyErrors;
resolver(err, res, next);
});
};
};

@@ -41,2 +41,3 @@ 'use strict';

userResHeaderDecorator: options.userResHeaderDecorator,
proxyErrorHandler: options.proxyErrorHandler,
filter: options.filter || defaultFilter,

@@ -57,2 +58,7 @@ // For backwards compatability, we default to legacy behavior for newly added settings.

// automatically opt into stream mode if no response modifiers are specified
resolved.stream = !resolved.skipToNextHandlerFilter &&
!resolved.userResDecorator &&
!resolved.userResHeaderDecorator;
debug(resolved);

@@ -59,0 +65,0 @@ return resolved;

{
"name": "express-http-proxy",
"version": "1.1.0",
"version": "1.2.0",
"description": "http proxy middleware for express",

@@ -5,0 +5,0 @@ "engines": {

@@ -5,4 +5,2 @@ # express-http-proxy [![NPM version](https://badge.fury.io/js/express-http-proxy.svg)](http://badge.fury.io/js/express-http-proxy) [![Build Status](https://travis-ci.org/villadora/express-http-proxy.svg?branch=master)](https://travis-ci.org/villadora/express-http-proxy) [![Dependency Status](https://gemnasium.com/villadora/express-http-proxy.svg)](https://gemnasium.com/villadora/express-http-proxy)

## NOTE: version 1.0.0 released: breaking changes, transition guide at bottom of doc.
## Install

@@ -29,5 +27,14 @@

### Streaming
Proxy requests and user responses are piped/streamed/chunked by default.
If you define a response modifier (userResDecorator, userResHeaderDecorator),
or need to inspect the response before continuing (maybeSkipToNext), streaming
is disabled, and the request and response are buffered.
This can cause performance issues with large payloads.
### Promises
Many function hooks support Promises.
Many function hooks support Promises.
If any Promise is rejected, ```next(x)``` is called in the hosting application, where ```x``` is whatever you pass to ```Promise.reject```;

@@ -51,2 +58,22 @@

### Host
The first positional argument is for the proxy host; in many cases you will use a static string here, eg.
```
app.use('/', proxy('http://google.com'))
```
However, this argument can also be a function, and that function can be
memoized or computed on each request, based on the setting of
```memoizeHost```.
```
function selectProxyHost() {
return (new Date() % 2) ? 'http://google.com' : 'http://altavista.com';
}
app.use('/', proxy(selectProxyHost);
```
### Options

@@ -56,2 +83,7 @@

Note: In ```express-http-proxy```, the ```path``` is considered the portion of
the url after the host, and including all query params. E.g. for the URL
```http://smoogle.com/search/path?q=123```; the path is
```/search/path?q=123```.
Provide a proxyReqPathResolver function if you'd like to

@@ -76,3 +108,4 @@ operate on the path before issuing the proxy request. Use a Promise for async

setTimeout(function () { // simulate async
var resolvedPathValue = "http://google.com";
// in this case I expect a request to /proxy => localhost:12345/a/different/path
var resolvedPathValue = "/a/different/path";
resolve(resolvedPathValue);

@@ -213,3 +246,3 @@ }, 200);

#### skipToNextHandlerFilter(supports Promise form)
(experimental: this interface may change in upcoming versions)
(experimental: this interface may change in upcoming versions)

@@ -226,4 +259,36 @@ Allows you to inspect the proxy response, and decide if you want to continue processing (via express-http-proxy) or call ```next()``` to return control to express.

### proxyErrorHandler
By default, ```express-http-proxy``` will pass any errors except ECONNRESET to
next, so that your application can handle or react to them, or just drop
through to your default error handling. ECONNRESET errors are immediately
returned to the user for historical reasons.
If you would like to modify this behavior, you can provide your own ```proxyErrorHandler```.
```js
// Example of skipping all error handling.
app.use(proxy('localhost:12346', {
proxyErrorHandler: function(err, res, next) {
next(err);
}
}));
// Example of rolling your own
app.use(proxy('localhost:12346', {
proxyErrorHandler: function(err, res, next) {
switch (err && err.code) {
case 'ECONNRESET': { return res.status(405).send('504 became 405'); }
case 'ECONNREFUSED': { return res.status(200).send('gotcher back'); }
default: { next(err); }
}
}}));
```
#### proxyReqOptDecorator (supports Promise form)

@@ -317,4 +382,6 @@

This defaults to true in order to preserve legacy behavior.
##### Note: this setting is required for binary uploads. A future version of this library may handle this for you.
This defaults to true in order to preserve legacy behavior.
When false, no action will be taken on the body and accordingly ```req.body``` will no longer be set.

@@ -366,7 +433,6 @@

#### timeout
By default, node does not express a timeout on connections.
Use timeout option to impose a specific timeout.
By default, node does not express a timeout on connections.
Use timeout option to impose a specific timeout.
Timed-out requests will respond with 504 status code and a X-Timeout-Reason header.

@@ -466,4 +532,16 @@

### Q: How to ignore self-signed certificates ?
You can set the `rejectUnauthorized` value in proxy request options prior to sending. See ```proxyReqOptDecorator``` for more details.
```js
app.use('/', proxy('internalhost.example.com', {
proxyReqOptDecorator: function(proxyReqOpts, originalReq) {
proxyReqOpts.rejectUnauthorized = false
return proxyReqOpts;
}
})
```
## Release Notes

@@ -473,3 +551,4 @@

| --- | --- |
| 1.0.8 | Add step to allow response headers to be modified.
| 1.2.0 | Auto-stream when no decorations are made to req/res. Improved docs, fixes issues in maybeSkipToNexthandler, allow authors to manage error handling. |
| 1.1.0 | Add step to allow response headers to be modified.
| 1.0.7 | Update dependencies. Improve docs on promise rejection. Fix promise rejection on body limit. Improve debug output. |

@@ -476,0 +555,0 @@ | 1.0.6 | Fixes preserveHostHdr not working, skip userResDecorator on 304, add maybeSkipToNext, test improvements and cleanup. |

@@ -53,3 +53,3 @@ 'use strict';

.end(function(err) {
fs.unlink(filename);
fs.unlinkSync(filename);
// This test is both broken and I think unnecessary.

@@ -85,3 +85,3 @@ // Its broken because http.bin no longer supports /post, but this test assertion is based on the old

.end(function(err) {
fs.unlink(filename);
fs.unlinkSync(filename);
// This test is both broken and I think unnecessary.

@@ -110,3 +110,3 @@ // Its broken because http.bin no longer supports /post, but this test assertion is based on the old

.end(function(err) {
fs.unlink(filename);
fs.unlinkSync(filename);
assert(err === null);

@@ -113,0 +113,0 @@ // This test is both broken and I think unnecessary.

@@ -16,4 +16,7 @@ 'use strict';

// TODO: This seems like a bug factory. We will have intermittent port conflicts, yeah?
var firstPort = Math.floor(Math.random() * 10000);
var secondPort = Math.floor(Math.random() * 10000);
function randomNumberInPortRange() {
return Math.floor(Math.random() * 48000) + 1024;
}
var firstPort = randomNumberInPortRange();
var secondPort = randomNumberInPortRange();

@@ -20,0 +23,0 @@ var hostFn = function(req) {

@@ -33,7 +33,5 @@ var express = require('express');

.get('/')
.expect(408)
.expect('X-Timout-Reason', 'express-http-proxy timed out your request after 100 ms.')
.end(function() {
done();
});
.expect(504)
.expect('X-Timeout-Reason', 'express-http-proxy reset the request.')
.end(done);
}

@@ -40,0 +38,0 @@

var assert = require('assert');
var express = require('express');
var bodyParser = require('body-parser');
var request = require('supertest');

@@ -14,2 +15,4 @@ var proxy = require('../');

app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(proxy('httpbin.org'));

@@ -41,2 +44,13 @@ });

it('test proxy post by x-www-form-urlencoded', function(done) {
request(app)
.post('/post')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send('mypost=hello')
.end(function(err, res) {
assert.equal(JSON.stringify(res.body.form), '{"mypost":"hello"}');
done(err);
});
});
it('test proxy put', function(done) {

@@ -43,0 +57,0 @@ request(app)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc