From 62d0af3279c77a822bde75c40a86bdccdcdd3e1a Mon Sep 17 00:00:00 2001 From: Brian Murrell Date: Wed, 27 Sep 2017 00:43:44 -0700 Subject: [PATCH] respect http_proxy and no_proxy for corporate firewall env --- README.md | 16 ++++++++++------ app/steps/sendProxyRequest.js | 17 +++++++++++++++++ package.json | 3 +++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4b44d783..425ca8df 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Express middleware to proxy request to another host and pass response back to original caller. -## NOTE: version 1.0.0 released: breaking changes, transition guide at bottom of doc. +## NOTE: version 1.0.0 released: breaking changes, transition guide at bottom of doc. ## Install @@ -27,7 +27,7 @@ app.use('/proxy', proxy('www.google.com')); ### 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```; @@ -193,7 +193,7 @@ REMOVED: See ```proxyReqOptDecorator``` and ```proxyReqBodyDecorator```. #### skipToNextHandlerFilter(supports Promise form) -(experimental: this interface may change in upcoming versions) +(experimental: this interface may change in upcoming versions) 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. @@ -295,7 +295,7 @@ The ```parseReqBody``` option allows you to control parsing the request body. For example, disabling body parsing is useful for large uploads where it would be inefficient to hold the data in memory. -This defaults to true in order to preserve legacy behavior. +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. @@ -346,8 +346,8 @@ app.use('/post', proxy('httpbin.org', { #### 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. ```js @@ -429,6 +429,10 @@ The library will automatically use https if the provided path has 'https://' or You can use ```proxyReqOptDecorator``` to ammend any auth or challenge headers required to succeed https. +### Q: Does it work behind a corporate firewall? + +The library will respect `http_proxy` or `HTTP_PROXY` and `no_proxy` environment variables if set and route outside requests through configured corporate firewall proxy. + ### Q: How can I support non-standard certificate chains? You can use the ability to decorate the proxy request prior to sending. See ```proxyReqOptDecorator``` for more details. diff --git a/app/steps/sendProxyRequest.js b/app/steps/sendProxyRequest.js index 5bf08e00..5b4c5eb2 100644 --- a/app/steps/sendProxyRequest.js +++ b/app/steps/sendProxyRequest.js @@ -8,6 +8,23 @@ function sendProxyRequest(Container) { var bodyContent = Container.proxy.bodyContent; var reqOpt = Container.proxy.reqBuilder; var options = Container.options; + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers + var corporateProxyServer = process.env.http_proxy || process.env.HTTP_PROXY || + process.env.https_proxy || process.env.HTTPS_PROXY; + var noProxyVal = process.env.no_proxy; + // jscs:enable requireCamelCaseOrUpperCaseIdentifiers + var noProxy = []; + if (noProxyVal) { + noProxy = noProxyVal.split(','); + } + + function isHostOutside() { + return !noProxy.includes(reqOpt.host); + } + if (corporateProxyServer && isHostOutside()) { + var HttpsProxyAgent = require('https-proxy-agent'); + reqOpt.agent = new HttpsProxyAgent(corporateProxyServer); + } return new Promise(function(resolve, reject) { var protocol = Container.proxy.requestModule; diff --git a/package.json b/package.json index ee2fd082..9110c8f0 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "main": "index.js", "scripts": { "test": "npm -s run mocha && npm run -s lint && npm run -s jscs", + "pretest:corp-firewall": "if [ -z \"$http_proxy\" ]; then echo 'ERROR: you must set http_proxy first'; exit 1; else exit 0; fi", + "test:corp-firewall": "NODE_TLS_REJECT_UNAUTHORIZED=0 no_proxy='127.0.0.1,localhost' npm test", "test:debug": "mocha debug -R spec test --recursive", "mocha": "mocha -R spec test --recursive", "lint": "jshint index.js test/*.js test/**/*js lib/*js app/**/*js ", @@ -42,6 +44,7 @@ "dependencies": { "debug": "^3.0.1", "es6-promise": "^4.1.1", + "https-proxy-agent": "^2.1.0", "raw-body": "^2.3.0" }, "contributors": [