diff --git a/README.md b/README.md index 5e96d683..75be5cc4 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```; @@ -205,7 +205,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. @@ -360,8 +360,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 @@ -443,6 +443,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 e4f82b9c..4d8439a8 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": [