express-http-proxy
Advanced tools
Comparing version 0.6.0 to 0.7.0
84
index.js
@@ -6,4 +6,4 @@ var assert = require('assert'); | ||
var https = require('https'); | ||
var is = require('type-is'); | ||
var getRawBody = require('raw-body'); | ||
var isError = require('lodash.iserror'); | ||
@@ -20,3 +20,3 @@ require('buffer'); | ||
var ishttps = /^https/.test(host); | ||
var ishttps = /^https/.test(host) || !!options.https; | ||
@@ -28,3 +28,3 @@ if (typeof host == 'string') { | ||
} | ||
var h = host.split(':'); | ||
@@ -38,8 +38,9 @@ if (h[1] === '443') { | ||
port = String.prototype.replace.call(port, '/', ''); | ||
} | ||
} else { | ||
port = ishttps ? 443 : 80; | ||
} | ||
port = options.port || port; | ||
/** | ||
/** | ||
* intercept(targetResponse, data, res, req, function(err, json)); | ||
@@ -53,2 +54,3 @@ */ | ||
var preserveHostHdr = options.preserveHostHdr; | ||
var preserveReqSession = options.preserveReqSession; | ||
@@ -70,12 +72,22 @@ return function handleProxy(req, res, next) { | ||
var parsedHost = parseHost((typeof host == 'function') ? host(req) : host.toString()); | ||
if (isError(parsedHost)) | ||
next(parsedHost); | ||
// var hasRequestBody = 'content-type' in req.headers || 'transfer-encoding' in req.headers; | ||
getRawBody(req, { | ||
length: req.headers['content-length'], | ||
limit: limit | ||
}, function(err, bodyContent) { | ||
if (err) return next(err); | ||
// Support for body-parser or other modules which already consume the req and store the result in req.body | ||
if (req.body) { | ||
runProxy(null, req.body); | ||
} else { | ||
getRawBody(req, { | ||
length: req.headers['content-length'], | ||
limit: limit, | ||
encoding: 'utf-8' | ||
}, runProxy); | ||
} | ||
function runProxy(err, bodyContent) { | ||
var reqOpt = { | ||
hostname: (typeof host == 'function') ? host(req) : host.toString(), | ||
port: port, | ||
hostname: parsedHost.host, | ||
port: options.port || parsedHost.port, | ||
headers: hds, | ||
@@ -88,5 +100,8 @@ method: req.method, | ||
if (preserveReqSession) { | ||
reqOpt.session = req.session; | ||
} | ||
if (decorateRequest) | ||
reqOpt = decorateRequest(reqOpt) || reqOpt; | ||
reqOpt = decorateRequest(reqOpt, req) || reqOpt; | ||
@@ -96,2 +111,4 @@ bodyContent = reqOpt.bodyContent; | ||
delete reqOpt.params; | ||
if (err && !bodyContent) return next(err); | ||
@@ -104,3 +121,3 @@ if (typeof bodyContent == 'string') | ||
var chunks = []; | ||
var realRequest = (ishttps ? https : http).request(reqOpt, function(rsp) { | ||
var realRequest = parsedHost.module.request(reqOpt, function(rsp) { | ||
var rspData = null; | ||
@@ -124,3 +141,3 @@ rsp.on('data', function(chunk) { | ||
var encode = 'utf8'; | ||
var encode = 'utf8'; | ||
if (rsp.headers && rsp.headers['content-type']) { | ||
@@ -133,3 +150,3 @@ var contentType = rsp.headers['content-type']; | ||
if (/charset=/.test(attr)) { | ||
// encode = attr.split('=')[1]; | ||
// encode = attr.split('=')[1]; | ||
break; | ||
@@ -141,9 +158,9 @@ } | ||
if (typeof rspd == 'string') | ||
if (typeof rspd == 'string') | ||
rspd = new Buffer(rspd, encode); | ||
if (!Buffer.isBuffer(rspd)) { | ||
next(new Error("intercept should return string or buffer as data")); | ||
} | ||
if (!res.headersSent) | ||
@@ -172,2 +189,4 @@ res.set('content-length', rspd.length); | ||
for (var p in rsp.headers) { | ||
if (p == 'transfer-encoding') | ||
continue; | ||
res.set(p, rsp.headers[p]); | ||
@@ -188,3 +207,3 @@ } | ||
realRequest.end(); | ||
}); | ||
} | ||
}; | ||
@@ -204,1 +223,24 @@ }; | ||
} | ||
function parseHost(host) { | ||
if (!host) { | ||
return new Error("Empty host parameter"); | ||
} | ||
if (!/http(s)?:\/\//.test(host)) { | ||
host = "http://" + host; | ||
} | ||
var parsed = url.parse(host); | ||
if (! parsed.hostname) { | ||
return new Error("Unable to parse hostname, possibly missing protocol://?"); | ||
} | ||
var ishttps = parsed.protocol === 'https:'; | ||
return { | ||
host: parsed.hostname, | ||
port: parsed.port || (ishttps ? 443 : 80), | ||
module: ishttps ? https : http | ||
}; | ||
} |
{ | ||
"name": "express-http-proxy", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"description": "http proxy middleware for express", | ||
@@ -36,3 +36,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"type-is": "^1.2.0", | ||
"lodash.iserror": "^3.1.0", | ||
"raw-body": "^1.1.6" | ||
@@ -39,0 +39,0 @@ }, |
# 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*: As work content changed, I have no spare time to maintaining this node module, It's appreciated if anyone want to take or keep maintaining, just contact me via jky239@gmail.com with Title contains: "Wanted: npm package xxxx". Thx. | ||
Express proxy middleware to forward request to another host and pass response back | ||
@@ -13,3 +16,3 @@ | ||
## Usage | ||
If you want to set up proxy for URL starting with `/proxy` | ||
```js | ||
@@ -66,2 +69,13 @@ var proxy = require('express-http-proxy'); | ||
You can copy the host HTTP header to the proxied express server using the `preserveHostHdr` option. | ||
``` | ||
app.use('/proxy', proxy('www.google.com', { | ||
forwardPath: function(req, res) { | ||
return require('url').parse(req.url).path; | ||
}, | ||
preserveHostHdr: true | ||
})); | ||
``` | ||
## Release Notes | ||
@@ -68,0 +82,0 @@ |
199
test/test.js
@@ -37,2 +37,12 @@ var assert = require('assert'); | ||
}); | ||
it('https with function for URL', function(done) { | ||
var https = express(); | ||
https.use( proxy(function() { return 'httpbin.org'; }, {https: true}) ); | ||
request(https) | ||
.get('/user-agent') | ||
.end(function(err, res) { | ||
if (err) return done(err); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -115,7 +125,7 @@ | ||
it('test intercept on html response',function(done) { | ||
it('test intercept on html response', function(done) { | ||
var app = express(); | ||
app.use(proxy('httpbin.org', { | ||
intercept: function(rsp, data, req, res, cb) { | ||
data = data.toString().replace('Oh','<strong>Hey</strong>'); | ||
data = data.toString().replace('Oh', '<strong>Hey</strong>'); | ||
assert(data !== ""); | ||
@@ -137,3 +147,3 @@ cb(null, data); | ||
var app = express(); | ||
app.use(proxy('https://api.github.com', { | ||
app.use(proxy('https://api.github.com', { | ||
intercept: function(rsp, data, req, res, cb) { | ||
@@ -156,3 +166,42 @@ var Iconv = require('iconv').Iconv; | ||
describe('test proxy middleware compatibility', function() { | ||
it('should use req.body if defined', function(done) { | ||
var app = express(); | ||
// Simulate another middleware that puts req stream into the body | ||
app.use(function(req, res, next) { | ||
var received = []; | ||
req.on('data', function onData(chunk) { | ||
if (!chunk) return; | ||
received.push(chunk); | ||
}); | ||
req.on('end', function onEnd(err) { | ||
received = Buffer.concat(received).toString('utf8'); | ||
req.body = JSON.parse(received); | ||
req.body.foo = 1; | ||
next(); | ||
}); | ||
}); | ||
app.use(proxy('example.com', { | ||
intercept: function(rsp, data, req, res, cb) { | ||
assert(req.body); | ||
assert.equal(req.body.foo, 1); | ||
assert.equal(req.body.mypost, 'hello'); | ||
cb(null, data); | ||
} | ||
})); | ||
request(app) | ||
.post('/post') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
describe('test proxy cookie', function() { | ||
@@ -179,72 +228,67 @@ it('set cookie', function(done) { | ||
it('test proxy get', function(done) { | ||
request(app) | ||
.get('/get') | ||
.end(function(err, res) { | ||
if (err) return done(err); | ||
assert(/node-superagent/.test(res.body.headers['User-Agent'])); | ||
assert.equal(res.body.url, 'http://httpbin.org/get'); | ||
done(err); | ||
}); | ||
}); | ||
describe('test http verbs', function() { | ||
it('test proxy get', function(done) { | ||
request(app) | ||
.get('/get') | ||
.end(function(err, res) { | ||
if (err) return done(err); | ||
assert(/node-superagent/.test(res.body.headers['User-Agent'])); | ||
assert.equal(res.body.url, 'http://httpbin.org/get'); | ||
done(err); | ||
}); | ||
}); | ||
it('test proxy post', function(done) { | ||
request(app) | ||
.post('/post') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
}); | ||
it('test proxy post', function(done) { | ||
request(app) | ||
.post('/post') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
}); | ||
it('test proxy put', function(done) { | ||
request(app) | ||
.put('/put') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
}); | ||
it('test proxy patch', function(done) { | ||
request(app) | ||
.patch('/patch') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
}); | ||
it('test proxy put', function(done) { | ||
request(app) | ||
.put('/put') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
it('test proxy delete', function(done) { | ||
request(app) | ||
.del('/delete') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
it('test proxy patch', function(done) { | ||
request(app) | ||
.patch('/patch') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
}); | ||
it('test proxy delete', function(done) { | ||
request(app) | ||
.del('/delete') | ||
.send({ | ||
mypost: 'hello' | ||
}) | ||
.end(function(err, res) { | ||
assert.equal(res.body.data, '{"mypost":"hello"}'); | ||
done(err); | ||
}); | ||
}); | ||
describe('test url parsing', function() { | ||
it('can parse a url with a port', function(done) { | ||
var app = express(); | ||
app.use(proxy('http://localhost:9786')); | ||
app.use(proxy('http://httpbin.org:80')); | ||
request(app) | ||
@@ -261,3 +305,3 @@ .get('/') | ||
var app = express(); | ||
app.use(proxy('http://localhost:9786/')); | ||
app.use(proxy('http://httpbin.org:80/')); | ||
request(app) | ||
@@ -273,2 +317,27 @@ .get('/') | ||
describe('test preserveReqSession', function() { | ||
it('preserveReqSession', function(done) { | ||
var app = express(); | ||
app.use(function (req, res, next) { | ||
req.session = 'hola'; | ||
next(); | ||
}); | ||
app.use(proxy('httpbin.org', { | ||
preserveReqSession: true, | ||
decorateRequest: function(req) { | ||
assert(req.session, 'hola'); | ||
} | ||
})); | ||
request(app) | ||
.get('/user-agent') | ||
.end(function(err, res) { | ||
if (err) return done(err); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20380
491
89
+ Addedlodash.iserror@^3.1.0
+ Addedlodash.iserror@3.1.1(transitive)
- Removedtype-is@^1.2.0
- Removedmedia-typer@0.3.0(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedtype-is@1.6.18(transitive)