From 893c917ad1d19706a99f2586b2da4059f754dff3 Mon Sep 17 00:00:00 2001 From: Vito Giarrusso Date: Thu, 24 Aug 2017 10:14:56 +1000 Subject: [PATCH 1/6] Add support for network proxy agent (#2998) Added support for network proxy agent in http-proxy-middleware, configured via package.json or 'PROXY_AGENT' env var --- .../react-dev-utils/WebpackDevServerUtils.js | 17 +++++++++++++++++ packages/react-dev-utils/package.json | 1 + 2 files changed, 18 insertions(+) diff --git a/packages/react-dev-utils/WebpackDevServerUtils.js b/packages/react-dev-utils/WebpackDevServerUtils.js index 1cd060592f9..464cd559f4c 100644 --- a/packages/react-dev-utils/WebpackDevServerUtils.js +++ b/packages/react-dev-utils/WebpackDevServerUtils.js @@ -16,6 +16,7 @@ const chalk = require('chalk'); const detect = require('detect-port-alt'); const isRoot = require('is-root'); const inquirer = require('inquirer'); +const HttpsProxyAgent = require('https-proxy-agent'); const clearConsole = require('./clearConsole'); const formatWebpackMessages = require('./formatWebpackMessages'); const getProcessForPort = require('./getProcessForPort'); @@ -364,6 +365,21 @@ function prepareProxy(proxy, appPublicFolder) { } else { target = proxy[context].target; } + let proxyAgent; + if (proxy[context].hasOwnProperty('agent') || process.env.PROXY_AGENT) { + const agentVal = proxy[context].agent || process.env.PROXY_AGENT; + if (typeof agentVal !== 'string') { + console.log( + chalk.red('"agent" value in package.json must be a string') + ); + process.exit(1); + } + if (agentVal.toLowerCase() !== 'none') { + proxyAgent = process.env[agentVal] + ? new HttpsProxyAgent(process.env[agentVal]) + : new HttpsProxyAgent(agentVal); + } + } return Object.assign({}, proxy[context], { context: function(pathname) { return mayProxy(pathname) && pathname.match(context); @@ -377,6 +393,7 @@ function prepareProxy(proxy, appPublicFolder) { } }, target, + agent: proxyAgent ? proxyAgent : undefined, onError: onProxyError(target), }); }); diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index 0e4e135f89f..95447f0b021 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -45,6 +45,7 @@ "global-modules": "1.0.0", "gzip-size": "3.0.0", "html-entities": "1.2.1", + "https-proxy-agent": "^2.1.0", "inquirer": "3.2.1", "is-root": "1.0.0", "opn": "5.1.0", From 898f4f930a55426bc2032dc92ccc0461cb5c8f13 Mon Sep 17 00:00:00 2001 From: Vito Giarrusso Date: Thu, 24 Aug 2017 10:16:34 +1000 Subject: [PATCH 2/6] DOCS: document proxy agent setting (#2998) - Documented use of the agent property in the proxy config of package.json - Documented use of the PROXY_AGENT env var --- packages/react-scripts/template/README.md | 63 ++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index c55ccdf949f..c9005b28fba 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -46,6 +46,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - ["Invalid Host Header" Errors After Configuring Proxy](#invalid-host-header-errors-after-configuring-proxy) - [Configuring the Proxy Manually](#configuring-the-proxy-manually) - [Configuring a WebSocket Proxy](#configuring-a-websocket-proxy) + - [Configuring the Proxy behind a network proxy](#configuring-the-proxy-behind-a-network-proxy) - [Using HTTPS in Development](#using-https-in-development) - [Generating Dynamic `` Tags on the Server](#generating-dynamic-meta-tags-on-the-server) - [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files) @@ -1046,7 +1047,8 @@ You may also specify any configuration value [`http-proxy-middleware`](https://g } ``` -All requests matching this path will be proxies, no exceptions. This includes requests for `text/html`, which the standard `proxy` option does not proxy. +All requests matching this path will be proxies, no exceptions. This includes requests for `text/html`, which the standard `proxy` option does not proxy.` +eg:` If you need to specify multiple proxies, you may do so by specifying additional entries. You may also narrow down matches using `*` and/or `**`, to match the path exactly or any subpath. @@ -1114,6 +1116,65 @@ Either way, you can proxy WebSocket requests manually in `package.json`: } ``` +### Configuring the Proxy behind a network proxy + +If you are behind a network proxy (common in corporate environments), and require requests to the url specified in the `target` property of the `proxy` object to be forwarded through your network proxy, you may specify an `agent` property in your `package.json` under the `proxy` object. +The `agent` property must be a string value representing either the environment variable containing your network proxy configuration (case sensitive), or the proxy configuration itself, in the format: + +`://[:@]:` + +eg: `http://myproxy.com:8080` + +or: `http://my_name:my_password@myproxy.com:8080` + +You may also set the network proxy for all specified proxies via an environment variable named `PROXY_AGENT` either in your system environment variables or your `.env` or `.env.development` files. + +If the `PROXY_AGENT` environment variable exists, it will be used for all proxies which do not explicitly set an `agent` property manually. If you need to exclude a proxy from using the `PROXY_AGENT` value, simply set the `agent` property to "none". + +A more complete example of using the proxy agent is: + +```js +{ + // ... + "proxy": { + // Matches any request starting with /api + "/api": { + "target": "", + "ws": true + // Specify a network proxy agent for this context via environment variable + "agent": "http_proxy" + // ... + }, + // Matches any request starting with /foo + "/foo": { + "target": "", + "ssl": true, + "pathRewrite": { + "^/foo": "/foo/beta" + } + // Specify a network proxy agent for this context directly + "agent": "http://username:password@myproxy.local:8080" + // ... + }, + // Matches /bar/abc.html but not /bar/sub/def.html + // Does not need to be forwarded through the network proxy as it is local to the machine + "/bar/*.html": { + "target": "http://localhost:5000/bar_api", + // ... + }, + // Matches /baz/abc.html and /baz/sub/def.html + // Does not need to be forwarded through the network proxy as it is in the local domain, explicitly setting to none to override "PROXY_AGENT" environment variable + "/baz/**/*.html": { + "target": "http://apiserver.local", + "agent": "none" + // ... + } + } + // ... +} +``` + + ## Using HTTPS in Development >Note: this feature is available with `react-scripts@0.4.0` and higher. From d6e0aea52d9595313e9e67a2f06907e428df4f83 Mon Sep 17 00:00:00 2001 From: Vito Giarrusso Date: Thu, 24 Aug 2017 11:24:54 +1000 Subject: [PATCH 3/6] Fixed README formatting for continuity with existing formatting --- packages/react-scripts/template/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index c9005b28fba..9d3f845fb78 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -46,7 +46,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - ["Invalid Host Header" Errors After Configuring Proxy](#invalid-host-header-errors-after-configuring-proxy) - [Configuring the Proxy Manually](#configuring-the-proxy-manually) - [Configuring a WebSocket Proxy](#configuring-a-websocket-proxy) - - [Configuring the Proxy behind a network proxy](#configuring-the-proxy-behind-a-network-proxy) + - [Configuring the Proxy Behind a Network Proxy](#configuring-the-proxy-behind-a-network-proxy) - [Using HTTPS in Development](#using-https-in-development) - [Generating Dynamic `` Tags on the Server](#generating-dynamic-meta-tags-on-the-server) - [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files) @@ -1046,7 +1046,6 @@ You may also specify any configuration value [`http-proxy-middleware`](https://g // ... } ``` - All requests matching this path will be proxies, no exceptions. This includes requests for `text/html`, which the standard `proxy` option does not proxy.` eg:` From 8c2c7784e4cbdd7d53d41a691d114f011e729935 Mon Sep 17 00:00:00 2001 From: Vito Giarrusso Date: Thu, 24 Aug 2017 11:32:06 +1000 Subject: [PATCH 4/6] Update README.md Removed superfluous `e.g.` from line 1050-1051 (Accidental artifact from previous commit) --- packages/react-scripts/template/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 9d3f845fb78..48e36f0fce2 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -1046,8 +1046,7 @@ You may also specify any configuration value [`http-proxy-middleware`](https://g // ... } ``` -All requests matching this path will be proxies, no exceptions. This includes requests for `text/html`, which the standard `proxy` option does not proxy.` -eg:` +All requests matching this path will be proxies, no exceptions. This includes requests for `text/html`, which the standard `proxy` option does not proxy. If you need to specify multiple proxies, you may do so by specifying additional entries. You may also narrow down matches using `*` and/or `**`, to match the path exactly or any subpath. From 8293eddda5c65b365970d6330d3d976e81bad4dc Mon Sep 17 00:00:00 2001 From: Vito Giarrusso Date: Thu, 24 Aug 2017 11:35:22 +1000 Subject: [PATCH 5/6] Update README.md Fixed header capitilaztion on line [1117](https://github.com/thtliife/create-react-app/tree/proxy-agent-for-http-proxy-middleware/packages/react-scripts/template#configuring-the-proxy-behind-a-network-proxy) for continuity with existing formatting --- packages/react-scripts/template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 48e36f0fce2..e87a29a24e3 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -1114,7 +1114,7 @@ Either way, you can proxy WebSocket requests manually in `package.json`: } ``` -### Configuring the Proxy behind a network proxy +### Configuring the Proxy Behind a Network Proxy If you are behind a network proxy (common in corporate environments), and require requests to the url specified in the `target` property of the `proxy` object to be forwarded through your network proxy, you may specify an `agent` property in your `package.json` under the `proxy` object. The `agent` property must be a string value representing either the environment variable containing your network proxy configuration (case sensitive), or the proxy configuration itself, in the format: From b9682f03b6884e50e4224ff4e8afa58bc708a1a7 Mon Sep 17 00:00:00 2001 From: Vito Giarrusso Date: Thu, 24 Aug 2017 11:37:39 +1000 Subject: [PATCH 6/6] Update README.md Re-added accidentally removed whitespace at line 1049 --- packages/react-scripts/template/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index e87a29a24e3..935e605922f 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -1046,6 +1046,7 @@ You may also specify any configuration value [`http-proxy-middleware`](https://g // ... } ``` + All requests matching this path will be proxies, no exceptions. This includes requests for `text/html`, which the standard `proxy` option does not proxy. If you need to specify multiple proxies, you may do so by specifying additional entries.