diff --git a/.travis.yml b/.travis.yml index 956c0fcbe..564cffd83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ sudo: false language: node_js node_js: + - "4" - "6" - "8" script: diff --git a/README.md b/README.md index 736caac73..7bb26c9a1 100644 --- a/README.md +++ b/README.md @@ -377,7 +377,6 @@ proxyServer.listen(8015); * **timeout**: timeout (in millis) for incoming requests * **followRedirects**: true/false, Default: false - specify whether you want to follow redirects * **selfHandleRequest** true/false, if set to true, none of the webOutgoing passes are called and its your responsibility ro appropriately return the response by listening and acting on the `proxyRes` event -* **modifyResponse**: do not pipe proxyRes to res, so you can respond to client with your own response. It still goes through all out going web passes unlike selfHandleRequest * **buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option: ``` @@ -487,13 +486,16 @@ proxy.close(); ### Miscellaneous +If you want to handle your own response after receiving the proxyRes, you can do +so with `selfHandleResponse` + ### Modify response ``` var option = { - target: target, - modifyResponse : true + target: target, + selfHandleResponse : true }; proxy.on('proxyRes', function (proxyRes, req, res) { var body = new Buffer(''); diff --git a/lib/http-proxy/passes/web-incoming.js b/lib/http-proxy/passes/web-incoming.js index eeff92ce8..995a0db4d 100644 --- a/lib/http-proxy/passes/web-incoming.js +++ b/lib/http-proxy/passes/web-incoming.js @@ -182,7 +182,7 @@ module.exports = { if (server) server.emit('end', req, res, proxyRes); }); // We pipe to the response unless its expected to be handled by the user - if (!options.selfHandleResponse && !options.modifyResponse) proxyRes.pipe(res); + if (!options.selfHandleResponse) proxyRes.pipe(res); } else { if (server) server.emit('end', req, res, proxyRes); } diff --git a/package-lock.json b/package-lock.json index 1824f1ad3..104c174f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,6 +103,12 @@ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, + "buffer-from": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "dev": true + }, "bufferutil": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.2.1.tgz", @@ -153,12 +159,30 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "1.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" + } + }, "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", "dev": true }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -359,6 +383,12 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "json3": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", @@ -3254,6 +3284,27 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -3341,6 +3392,15 @@ "options": "0.0.6" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, "supports-color": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", @@ -3356,6 +3416,12 @@ "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", "dev": true }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -3382,6 +3448,12 @@ } } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 2f01cf795..2ca6b6083 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "devDependencies": { "async": "^2.0.0", + "concat-stream": "^1.6.2", "expect.js": "~0.3.1", "mocha": "^3.5.3", "nyc": "^11.7.1", diff --git a/test/lib-http-proxy-passes-web-incoming-test.js b/test/lib-http-proxy-passes-web-incoming-test.js index cffe1af1e..37f74204b 100644 --- a/test/lib-http-proxy-passes-web-incoming-test.js +++ b/test/lib-http-proxy-passes-web-incoming-test.js @@ -1,6 +1,8 @@ var webPasses = require('../lib/http-proxy/passes/web-incoming'), httpProxy = require('../lib/http-proxy'), expect = require('expect.js'), + concat = require('concat-stream'), + async = require('async'), url = require('url'), http = require('http'); @@ -316,6 +318,44 @@ describe('#createProxyServer.web() using own http server', function () { http.request('http://127.0.0.1:8086', function() {}).end(); }); + it('should proxy the request and provide and respond to manual user response when using modifyResponse', function(done) { + var proxy = httpProxy.createProxyServer({ + target: 'http://127.0.0.1:8080', + selfHandleResponse: true + }); + + function requestHandler(req, res) { + proxy.once('proxyRes', function (proxyRes, pReq, pRes) { + proxyRes.pipe(concat(function (body) { + expect(body.toString('utf8')).eql('Response'); + pRes.end(Buffer.from('my-custom-response')); + })) + }); + + proxy.web(req, res); + } + + var proxyServer = http.createServer(requestHandler); + + var source = http.createServer(function(req, res) { + res.end('Response'); + }); + + async.parallel([ + next => proxyServer.listen(8086, next), + next => source.listen(8080, next) + ], function (err) { + http.get('http://127.0.0.1:8086', function(res) { + res.pipe(concat(function(body) { + expect(body.toString('utf8')).eql('my-custom-response'); + source.close(); + proxyServer.close(); + done(); + })); + }).once('error', done); + }) + }); + it('should proxy the request and handle changeOrigin option', function (done) { var proxy = httpProxy.createProxyServer({ target: 'http://127.0.0.1:8080',