proxy_agent: Use proxy-from-env for robustness
Now we support pretty much every variable under the sun along with $NO_PROXY all correctly and with minimal code on our end.
This commit is contained in:
@ -1,13 +1,15 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import * as http from "http"
|
||||
import * as url from "url"
|
||||
import * as proxyagent from "proxy-agent"
|
||||
import * as proxyAgent from "proxy-agent"
|
||||
import * as proxyFromEnv from "proxy-from-env"
|
||||
|
||||
/**
|
||||
* This file has nothing to do with the code-server proxy.
|
||||
* It is for $HTTP_PROXY and $HTTPS_PROXY support.
|
||||
* It is to support $HTTP_PROXY, $HTTPS_PROXY and $NO_PROXY.
|
||||
*
|
||||
* - https://github.com/cdr/code-server/issues/124
|
||||
* - https://www.npmjs.com/package/proxy-agent
|
||||
* - https://www.npmjs.com/package/proxy-from-env
|
||||
*
|
||||
* This file exists in two locations:
|
||||
* - src/node/proxy_agent.ts
|
||||
@ -17,7 +19,7 @@ import * as proxyagent from "proxy-agent"
|
||||
|
||||
/**
|
||||
* monkeyPatch patches the node http,https modules to route all requests through the
|
||||
* agents we get from the proxy-agent package.
|
||||
* agent we get from the proxy-agent package.
|
||||
*
|
||||
* This approach only works if there is no code specifying an explicit agent when making
|
||||
* a request.
|
||||
@ -28,29 +30,22 @@ import * as proxyagent from "proxy-agent"
|
||||
*
|
||||
* Even if they do, it's probably the same proxy so we should be fine! And those knobs
|
||||
* are deprecated anyway.
|
||||
*
|
||||
* We use $HTTP_PROXY for all HTTP resources via a normal HTTP proxy.
|
||||
* We use $HTTPS_PROXY for all HTTPS resources via HTTP connect.
|
||||
* See https://stackoverflow.com/a/10442767/4283659
|
||||
*/
|
||||
export function monkeyPatch(inVSCode: boolean): void {
|
||||
const http = require("http")
|
||||
const https = require("https")
|
||||
if (shouldEnableProxy()) {
|
||||
const http = require("http")
|
||||
const https = require("https")
|
||||
|
||||
const httpProxyURL = process.env.HTTP_PROXY || process.env.http_proxy
|
||||
if (httpProxyURL) {
|
||||
logger.debug(`using $HTTP_PROXY ${httpProxyURL}`)
|
||||
http.globalAgent = newProxyAgent(inVSCode, httpProxyURL)
|
||||
}
|
||||
|
||||
const httpsProxyURL = process.env.HTTPS_PROXY || process.env.https_proxy
|
||||
if (httpsProxyURL) {
|
||||
logger.debug(`using $HTTPS_PROXY ${httpsProxyURL}`)
|
||||
https.globalAgent = newProxyAgent(inVSCode, httpsProxyURL)
|
||||
// If we do not pass in a proxy URL, proxy-agent will get the URL from the environment.
|
||||
// See https://www.npmjs.com/package/proxy-from-env.
|
||||
// Also see shouldEnableProxy.
|
||||
const pa = newProxyAgent(inVSCode)
|
||||
http.globalAgent = pa
|
||||
https.globalAgent = pa
|
||||
}
|
||||
}
|
||||
|
||||
function newProxyAgent(inVSCode: boolean, for: "http" | "https", proxyURL: string): http.Agent {
|
||||
function newProxyAgent(inVSCode: boolean): http.Agent {
|
||||
// The reasoning for this split is that VS Code's build process does not have
|
||||
// esModuleInterop enabled but the code-server one does. As a result depending on where
|
||||
// we execute, we either have a default attribute or we don't.
|
||||
@ -59,8 +54,28 @@ function newProxyAgent(inVSCode: boolean, for: "http" | "https", proxyURL: strin
|
||||
// a huge number of errors. And we can't use require as otherwise the modules won't be
|
||||
// included in the final product.
|
||||
if (inVSCode) {
|
||||
return new (proxyagent as any)(opts)
|
||||
return new (proxyAgent as any)()
|
||||
} else {
|
||||
return new (proxyagent as any).default(opts)
|
||||
return new (proxyAgent as any).default()
|
||||
}
|
||||
}
|
||||
|
||||
// If they have $NO_PROXY set to example.com then this check won't work!
|
||||
// But that's drastically unlikely.
|
||||
function shouldEnableProxy(): boolean {
|
||||
let shouldEnable = false
|
||||
|
||||
const httpProxy = proxyFromEnv.getProxyForUrl(`http://example.com`)
|
||||
if (httpProxy) {
|
||||
shouldEnable = true
|
||||
logger.debug(`using $HTTP_PROXY ${httpProxy}`)
|
||||
}
|
||||
|
||||
const httpsProxy = proxyFromEnv.getProxyForUrl(`https://example.com`)
|
||||
if (httpsProxy) {
|
||||
shouldEnable = true
|
||||
logger.debug(`using $HTTPS_PROXY ${httpsProxy}`)
|
||||
}
|
||||
|
||||
return shouldEnable
|
||||
}
|
||||
|
Reference in New Issue
Block a user