Skip to content
Open
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Other options:
- `via`: by default no [via header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.45) is added. If you pass `true` for this option the local hostname will be used for the via header. You can also pass a string for this option in which case that will be used for the via header.
- `cookieRewrite`: this option can be used to support cookies via the proxy by rewriting the cookie domain to that of the proxy server. By default cookie domains are not rewritten. The `cookieRewrite` option works as the `via` option - if you pass `true` the local hostname will be used, and if you pass a string that will be used as the rewritten cookie domain.
- `preserveHost`: When enabled, this option will pass the Host: line from the incoming request to the proxied host. Default: `false`.
- `transformReq`: transform function called on requests enables dynamic rewriting of headers sent to the server.
- `transformResp`: transform function called on responses enables dynamic rewriting of headers coming back from the server.

### Usage with route:

Expand Down
18 changes: 18 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module.exports = function proxyMiddleware(options) {
opts.headers = options.headers ? merge(req.headers, options.headers) : req.headers;

applyViaHeader(req.headers, opts, opts.headers);
transformReq(req.headers, opts, opts.headers);

if (!options.preserveHost) {
// Forwarding the host breaks dotcloud
Expand All @@ -64,6 +65,7 @@ module.exports = function proxyMiddleware(options) {
}
applyViaHeader(myRes.headers, opts, myRes.headers);
rewriteCookieHosts(myRes.headers, opts, myRes.headers, req);
transformResp(myRes.headers, opts, myRes.headers);
resp.writeHead(myRes.statusCode, myRes.headers);
myRes.on('error', function (err) {
next(err);
Expand Down Expand Up @@ -118,6 +120,22 @@ function rewriteCookieHosts(existingHeaders, opts, applyTo, req) {
applyTo['set-cookie'] = rewrittenCookies;
}

function transformReq (existingHeaders, opts, applyTo) {
if (typeof opts.transformReq !== 'function') {
return;
}

opts.transformReq(existingHeaders, opts, applyTo);
}

function transformResp (existingHeaders, opts, applyTo) {
if (typeof opts.transformResp !== 'function') {
return;
}

opts.transformResp(existingHeaders, opts, applyTo);
}

function slashJoin(p1, p2) {
var trailing_slash = false;

Expand Down
59 changes: 59 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,65 @@ describe("proxy", function() {
})
});

it("calls the transformReq function and transforms the request headers", function(done) {
var destServer = createServerWithLibName('http', function(req, resp) {
assert.strictEqual(req.headers.host, 'localhost:8086');
assert.strictEqual(req.headers['x-custom-header'], 'hello localhost:8087');
resp.statusCode = 200;
resp.write(req.url);
resp.end();
});

var proxyOptions = url.parse('http://localhost:8086/');
proxyOptions.transformReq = function (existingHeaders, opts, applyTo) {
applyTo['x-custom-header'] = 'hello ' + existingHeaders.host;
};

var app = connect();
app.use(proxy(proxyOptions));

destServer.listen(8086, 'localhost', function() {
app.listen(8087);

var options = url.parse('http://localhost:8087/foo/test/');
http.get(options, function () {
// ok...
done();
}).on('error', function () {
assert.fail('Request proxy failed');
});
});
});

it("calls the transformResp function and transforms the response headers", function(done) {
var destServer = createServerWithLibName('http', function(req, resp) {
resp.statusCode = 200;
resp.setHeader('x-custom-header', 'hello');
resp.write(req.url);
resp.end();
});

var proxyOptions = url.parse('http://localhost:8088/');
proxyOptions.transformResp = function (existingHeaders, opts, applyTo) {
applyTo['x-custom-reply'] = 'hi there ' + existingHeaders['x-custom-header'];
};

var app = connect();
app.use(proxy(proxyOptions));

destServer.listen(8088, 'localhost', function() {
app.listen(8089);

var options = url.parse('http://localhost:8089/foo/test/');
http.get(options, function (resp) {
assert.strictEqual(resp.headers['x-custom-reply'], 'hi there hello');
done();
}).on('error', function () {
assert.fail('Request proxy failed');
});
});
});

});

function createServerWithLibName(libName, requestListener) {
Expand Down