1
1
import { logger } from "@coder/logger"
2
2
import * as http from "http"
3
- import * as proxyagent from "proxy-agent"
3
+ import * as proxyAgent from "proxy-agent"
4
+ import * as proxyFromEnv from "proxy-from-env"
4
5
5
6
/**
6
- * This file does not have anything to do with the code-server proxy.
7
- * It's for $HTTP_PROXY support!
7
+ * This file has nothing to do with the code-server proxy.
8
+ * It is to support $HTTP_PROXY, $HTTPS_PROXY and $NO_PROXY.
9
+ *
8
10
* - https://github.com/cdr/code-server/issues/124
9
11
* - https://www.npmjs.com/package/proxy-agent
12
+ * - https://www.npmjs.com/package/proxy-from-env
10
13
*
11
14
* This file exists in two locations:
12
15
* - src/node/proxy_agent.ts
@@ -15,48 +18,64 @@ import * as proxyagent from "proxy-agent"
15
18
*/
16
19
17
20
/**
18
- * monkeyPatch patches the node HTTP/HTTPS library to route all requests through our
19
- * custom agent from the proxyAgent package.
21
+ * monkeyPatch patches the node http,https modules to route all requests through the
22
+ * agent we get from the proxy-agent package.
23
+ *
24
+ * This approach only works if there is no code specifying an explicit agent when making
25
+ * a request.
26
+ *
27
+ * None of our code ever passes in a explicit agent to the http,https modules.
28
+ * VS Code's does sometimes but only when a user sets the http.proxy configuration.
29
+ * See https://code.visualstudio.com/docs/setup/network#_legacy-proxy-server-support
30
+ *
31
+ * Even if they do, it's probably the same proxy so we should be fine! And those knobs
32
+ * are deprecated anyway.
20
33
*/
21
- export function monkeyPatch ( vscode : boolean ) : void {
22
- // We do not support HTTPS_PROXY here to avoid confusion. proxy-agent will automatically
23
- // use the correct protocol to connect to the proxy depending on the requested URL.
24
- //
25
- // We could implement support ourselves to allow people to configure the proxy used for
26
- // HTTPS vs HTTP but there doesn't seem to be much value in that.
27
- //
28
- // At least of right now, it'd just be plain confusing to support HTTPS_PROXY when proxy-agent
29
- // will still use HTTP to hit it for HTTP requests.
30
- const proxyURL = process . env . HTTP_PROXY || process . env . http_proxy
31
- if ( ! proxyURL ) {
32
- return
33
- }
34
+ export function monkeyPatch ( inVSCode : boolean ) : void {
35
+ if ( shouldEnableProxy ( ) ) {
36
+ const http = require ( "http" )
37
+ const https = require ( "https" )
34
38
35
- logger . debug ( `using $HTTP_PROXY ${ process . env . HTTP_PROXY } ` )
39
+ // If we do not pass in a proxy URL, proxy-agent will get the URL from the environment.
40
+ // See https://www.npmjs.com/package/proxy-from-env.
41
+ // Also see shouldEnableProxy.
42
+ const pa = newProxyAgent ( inVSCode )
43
+ http . globalAgent = pa
44
+ https . globalAgent = pa
45
+ }
46
+ }
36
47
37
- let pa : http . Agent
48
+ function newProxyAgent ( inVSCode : boolean ) : http . Agent {
38
49
// The reasoning for this split is that VS Code's build process does not have
39
50
// esModuleInterop enabled but the code-server one does. As a result depending on where
40
51
// we execute, we either have a default attribute or we don't.
41
52
//
42
53
// I can't enable esModuleInterop in VS Code's build process as it breaks and spits out
43
- // a huge number of errors.
44
- if ( vscode ) {
45
- pa = new ( proxyagent as any ) ( process . env . HTTP_PROXY )
54
+ // a huge number of errors. And we can't use require as otherwise the modules won't be
55
+ // included in the final product.
56
+ if ( inVSCode ) {
57
+ return new ( proxyAgent as any ) ( )
46
58
} else {
47
- pa = new ( proxyagent as any ) . default ( process . env . HTTP_PROXY )
59
+ return new ( proxyAgent as any ) . default ( )
60
+ }
61
+ }
62
+
63
+ // If they have $NO_PROXY set to example.com then this check won't work!
64
+ // But that's drastically unlikely.
65
+ function shouldEnableProxy ( ) : boolean {
66
+ let shouldEnable = false
67
+
68
+ const httpProxy = proxyFromEnv . getProxyForUrl ( `http://example.com` )
69
+ if ( httpProxy ) {
70
+ shouldEnable = true
71
+ logger . debug ( `using $HTTP_PROXY ${ httpProxy } ` )
72
+ }
73
+
74
+ const httpsProxy = proxyFromEnv . getProxyForUrl ( `https://example.com` )
75
+ if ( httpsProxy ) {
76
+ shouldEnable = true
77
+ logger . debug ( `using $HTTPS_PROXY ${ httpsProxy } ` )
48
78
}
49
79
50
- /**
51
- * None of our code ever passes in a explicit agent to the http modules but VS Code's
52
- * does sometimes but only when a user sets the http.proxy configuration.
53
- * See https://code.visualstudio.com/docs/setup/network#_legacy-proxy-server-support
54
- *
55
- * Even if they do, it's probably the same proxy so we should be fine! And those are
56
- * deprecated anyway.
57
- */
58
- const http = require ( "http" )
59
- const https = require ( "https" )
60
- http . globalAgent = pa
61
- https . globalAgent = pa
80
+ return shouldEnable
62
81
}
0 commit comments