code-server-2/src/node/proxy_agent.ts

67 lines
2.5 KiB
TypeScript
Raw Normal View History

import { logger } from "@coder/logger"
import * as http from "http"
import * as url from "url"
2020-12-04 07:08:55 +00:00
import * as proxyagent from "proxy-agent"
/**
* This file has nothing to do with the code-server proxy.
* It is for $HTTP_PROXY and $HTTPS_PROXY support.
* - https://github.com/cdr/code-server/issues/124
* - https://www.npmjs.com/package/proxy-agent
*
* 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.
*/
/**
* monkeyPatch patches the node http,https modules to route all requests through the
* agents we get from the proxy-agent package.
2020-12-18 10:30:40 +00:00
*
* This approach only works if there is no code specifying an explicit agent when making
* a request.
2020-12-18 10:30:40 +00: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 10:30:40 +00:00
*
* Even if they do, it's probably the same proxy so we should be fine! And those knobs
* are deprecated anyway.
2020-12-18 10:30:40 +00:00
*
* 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")
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)
}
}
function newProxyAgent(inVSCode: boolean, for: "http" | "https", proxyURL: string): 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.
//
// I can't enable esModuleInterop in VS Code's build process as it breaks and spits out
// 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)
} else {
return new (proxyagent as any).default(opts)
}
}