2020-12-04 13:53:27 +08:00
|
|
|
import { logger } from "@coder/logger"
|
|
|
|
import * as http from "http"
|
2020-12-18 23:38:00 +08:00
|
|
|
import * as proxyAgent from "proxy-agent"
|
|
|
|
import * as proxyFromEnv from "proxy-from-env"
|
2020-12-04 13:53:27 +08:00
|
|
|
|
|
|
|
/**
|
2020-12-18 22:09:07 +08:00
|
|
|
* This file has nothing to do with the code-server proxy.
|
2020-12-18 23:38:00 +08:00
|
|
|
* It is to support $HTTP_PROXY, $HTTPS_PROXY and $NO_PROXY.
|
|
|
|
*
|
2020-12-04 13:53:27 +08:00
|
|
|
* - https://github.com/cdr/code-server/issues/124
|
|
|
|
* - https://www.npmjs.com/package/proxy-agent
|
2020-12-18 23:38:00 +08:00
|
|
|
* - https://www.npmjs.com/package/proxy-from-env
|
2020-12-04 13:53:27 +08:00
|
|
|
*
|
|
|
|
* This file exists in two locations:
|
|
|
|
* - src/node/proxy_agent.ts
|
|
|
|
* - lib/vscode/src/vs/base/node/proxy_agent.ts
|
|
|
|
* The second is a symlink to the first.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2020-12-18 22:09:07 +08:00
|
|
|
* monkeyPatch patches the node http,https modules to route all requests through the
|
2020-12-18 23:38:00 +08:00
|
|
|
* agent we get from the proxy-agent package.
|
2020-12-18 18:30:40 +08:00
|
|
|
*
|
2020-12-18 22:09:07 +08:00
|
|
|
* This approach only works if there is no code specifying an explicit agent when making
|
|
|
|
* a request.
|
2020-12-18 18:30:40 +08:00
|
|
|
*
|
2020-12-18 22:09:07 +08:00
|
|
|
* None of our code ever passes in a explicit agent to the http,https modules.
|
|
|
|
* VS Code's does sometimes but only when a user sets the http.proxy configuration.
|
|
|
|
* See https://code.visualstudio.com/docs/setup/network#_legacy-proxy-server-support
|
2020-12-18 18:30:40 +08:00
|
|
|
*
|
2020-12-18 22:09:07 +08:00
|
|
|
* Even if they do, it's probably the same proxy so we should be fine! And those knobs
|
|
|
|
* are deprecated anyway.
|
2020-12-04 13:53:27 +08:00
|
|
|
*/
|
2020-12-18 22:09:07 +08:00
|
|
|
export function monkeyPatch(inVSCode: boolean): void {
|
2020-12-18 23:38:00 +08:00
|
|
|
if (shouldEnableProxy()) {
|
|
|
|
const http = require("http")
|
|
|
|
const https = require("https")
|
2020-12-04 13:53:27 +08:00
|
|
|
|
2020-12-18 23:38:00 +08:00
|
|
|
// 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
|
2020-12-18 22:09:07 +08:00
|
|
|
}
|
|
|
|
}
|
2020-12-04 13:53:27 +08:00
|
|
|
|
2020-12-18 23:38:00 +08:00
|
|
|
function newProxyAgent(inVSCode: boolean): http.Agent {
|
2020-12-04 13:53:27 +08:00
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
// I can't enable esModuleInterop in VS Code's build process as it breaks and spits out
|
2020-12-18 22:09:07 +08:00
|
|
|
// 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) {
|
2020-12-18 23:38:00 +08:00
|
|
|
return new (proxyAgent as any)()
|
2020-12-04 13:53:27 +08:00
|
|
|
} else {
|
2020-12-18 23:38:00 +08:00
|
|
|
return new (proxyAgent as any).default()
|
2020-12-04 13:53:27 +08:00
|
|
|
}
|
|
|
|
}
|
2020-12-18 23:38:00 +08:00
|
|
|
|
|
|
|
// If they have $NO_PROXY set to example.com then this check won't work!
|
|
|
|
// But that's drastically unlikely.
|
2021-07-24 05:38:25 +08:00
|
|
|
export function shouldEnableProxy(): boolean {
|
2020-12-18 23:38:00 +08:00
|
|
|
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
|
|
|
|
}
|