@theia/ai-core 1.70.0-next.12 → 1.70.0-next.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/index.d.ts +1 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +1 -0
- package/lib/common/index.js.map +1 -1
- package/lib/common/proxy-util.d.ts +9 -0
- package/lib/common/proxy-util.d.ts.map +1 -0
- package/lib/common/proxy-util.js +84 -0
- package/lib/common/proxy-util.js.map +1 -0
- package/lib/common/proxy-util.spec.d.ts +2 -0
- package/lib/common/proxy-util.spec.d.ts.map +1 -0
- package/lib/common/proxy-util.spec.js +89 -0
- package/lib/common/proxy-util.spec.js.map +1 -0
- package/lib/node/index.d.ts +2 -0
- package/lib/node/index.d.ts.map +1 -0
- package/lib/node/index.js +20 -0
- package/lib/node/index.js.map +1 -0
- package/lib/node/proxy-util.d.ts +23 -0
- package/lib/node/proxy-util.d.ts.map +1 -0
- package/lib/node/proxy-util.js +83 -0
- package/lib/node/proxy-util.js.map +1 -0
- package/lib/node/proxy-util.spec.d.ts +2 -0
- package/lib/node/proxy-util.spec.d.ts.map +1 -0
- package/lib/node/proxy-util.spec.js +122 -0
- package/lib/node/proxy-util.spec.js.map +1 -0
- package/package.json +11 -10
- package/src/common/index.ts +1 -0
- package/src/common/proxy-util.spec.ts +106 -0
- package/src/common/proxy-util.ts +86 -0
- package/src/node/index.ts +17 -0
- package/src/node/proxy-util.spec.ts +143 -0
- package/src/node/proxy-util.ts +85 -0
package/lib/common/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from './language-model';
|
|
|
9
9
|
export * from './language-model-alias';
|
|
10
10
|
export * from './prompt-service';
|
|
11
11
|
export * from './prompt-service-util';
|
|
12
|
+
export * from './proxy-util';
|
|
12
13
|
export * from './prompt-text';
|
|
13
14
|
export * from './protocol';
|
|
14
15
|
export * from './today-variable-contribution';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAeA,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAeA,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAE7B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC;AACnD,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
|
package/lib/common/index.js
CHANGED
|
@@ -27,6 +27,7 @@ tslib_1.__exportStar(require("./language-model"), exports);
|
|
|
27
27
|
tslib_1.__exportStar(require("./language-model-alias"), exports);
|
|
28
28
|
tslib_1.__exportStar(require("./prompt-service"), exports);
|
|
29
29
|
tslib_1.__exportStar(require("./prompt-service-util"), exports);
|
|
30
|
+
tslib_1.__exportStar(require("./proxy-util"), exports);
|
|
30
31
|
tslib_1.__exportStar(require("./prompt-text"), exports);
|
|
31
32
|
tslib_1.__exportStar(require("./protocol"), exports);
|
|
32
33
|
tslib_1.__exportStar(require("./today-variable-contribution"), exports);
|
package/lib/common/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":";;;AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,0DAAgC;AAChC,kDAAwB;AACxB,yEAA+C;AAC/C,gEAAsC;AACtC,qEAA2C;AAC3C,oEAA0C;AAC1C,gEAAsC;AACtC,2DAAiC;AACjC,iEAAuC;AACvC,2DAAiC;AACjC,gEAAsC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":";;;AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,0DAAgC;AAChC,kDAAwB;AACxB,yEAA+C;AAC/C,gEAAsC;AACtC,qEAA2C;AAC3C,oEAA0C;AAC1C,gEAAsC;AACtC,2DAAiC;AACjC,iEAAuC;AACvC,2DAAiC;AACjC,gEAAsC;AACtC,uDAA6B;AAE7B,wDAA8B;AAC9B,qDAA2B;AAC3B,wEAA8C;AAC9C,6DAAmC;AACnC,6DAAmC;AACnC,mEAAyC;AACzC,gEAAsC;AACtC,iEAAuC;AACvC,6EAAmD;AACnD,+DAAqC;AACrC,kDAAwB;AACxB,6DAAmC;AACnC,2DAAiC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether the given target URL should bypass the proxy based on `no_proxy` rules.
|
|
3
|
+
*
|
|
4
|
+
* @param targetUrl - The URL to check against the no_proxy rules.
|
|
5
|
+
* @param noProxyValue - A comma-separated list of no_proxy rules.
|
|
6
|
+
* @returns `true` if the target URL should bypass the proxy, `false` otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export declare function shouldBypassProxy(targetUrl: string | undefined, noProxyValue: string | undefined): boolean;
|
|
9
|
+
//# sourceMappingURL=proxy-util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.d.ts","sourceRoot":"","sources":["../../src/common/proxy-util.ts"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CA6D1G"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.shouldBypassProxy = shouldBypassProxy;
|
|
19
|
+
/**
|
|
20
|
+
* Checks whether the given target URL should bypass the proxy based on `no_proxy` rules.
|
|
21
|
+
*
|
|
22
|
+
* @param targetUrl - The URL to check against the no_proxy rules.
|
|
23
|
+
* @param noProxyValue - A comma-separated list of no_proxy rules.
|
|
24
|
+
* @returns `true` if the target URL should bypass the proxy, `false` otherwise.
|
|
25
|
+
*/
|
|
26
|
+
function shouldBypassProxy(targetUrl, noProxyValue) {
|
|
27
|
+
if (!targetUrl || !noProxyValue) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = new URL(targetUrl);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
38
|
+
const port = parsed.port;
|
|
39
|
+
const rules = noProxyValue.split(',');
|
|
40
|
+
for (const rawRule of rules) {
|
|
41
|
+
const rule = rawRule.trim().toLowerCase();
|
|
42
|
+
if (!rule) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (rule === '*') {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
let ruleHost;
|
|
49
|
+
let rulePort;
|
|
50
|
+
const portSeparatorIndex = rule.lastIndexOf(':');
|
|
51
|
+
// Check if there's a port in the rule (only if the part after ':' is numeric)
|
|
52
|
+
if (portSeparatorIndex !== -1) {
|
|
53
|
+
const possiblePort = rule.substring(portSeparatorIndex + 1);
|
|
54
|
+
if (/^\d+$/.test(possiblePort)) {
|
|
55
|
+
ruleHost = rule.substring(0, portSeparatorIndex);
|
|
56
|
+
rulePort = possiblePort;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
ruleHost = rule;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
ruleHost = rule;
|
|
64
|
+
}
|
|
65
|
+
// If the rule specifies a port, the target must match it
|
|
66
|
+
if (rulePort !== undefined && port !== rulePort) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (ruleHost.startsWith('.')) {
|
|
70
|
+
// Domain suffix match: .example.com matches *.example.com
|
|
71
|
+
if (hostname.endsWith(ruleHost) || hostname === ruleHost.substring(1)) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Exact match or suffix match (without leading dot)
|
|
77
|
+
if (hostname === ruleHost || hostname.endsWith('.' + ruleHost)) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=proxy-util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.js","sourceRoot":"","sources":["../../src/common/proxy-util.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAShF,8CA6DC;AApED;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,SAA6B,EAAE,YAAgC;IAC7F,IAAI,CAAC,SAAS,IAAI,CAAC,YAAY,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACD,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAEzB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,SAAS;QACb,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,QAAgB,CAAC;QACrB,IAAI,QAA4B,CAAC;QACjC,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACjD,8EAA8E;QAC9E,IAAI,kBAAkB,KAAK,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC;YAC5D,IAAI,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7B,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;gBACjD,QAAQ,GAAG,YAAY,CAAC;YAC5B,CAAC;iBAAM,CAAC;gBACJ,QAAQ,GAAG,IAAI,CAAC;YACpB,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,QAAQ,GAAG,IAAI,CAAC;QACpB,CAAC;QAED,yDAAyD;QACzD,IAAI,QAAQ,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9C,SAAS;QACb,CAAC;QAED,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,0DAA0D;YAC1D,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpE,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,oDAAoD;YACpD,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.spec.d.ts","sourceRoot":"","sources":["../../src/common/proxy-util.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const chai_1 = require("chai");
|
|
19
|
+
const proxy_util_1 = require("./proxy-util");
|
|
20
|
+
describe('proxy-util', () => {
|
|
21
|
+
describe('shouldBypassProxy', () => {
|
|
22
|
+
it('should return false when targetUrl is undefined', () => {
|
|
23
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)(undefined, 'localhost')).to.be.false;
|
|
24
|
+
});
|
|
25
|
+
it('should return false when noProxyValue is undefined', () => {
|
|
26
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://example.com', undefined)).to.be.false;
|
|
27
|
+
});
|
|
28
|
+
it('should return false when noProxyValue is empty', () => {
|
|
29
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://example.com', '')).to.be.false;
|
|
30
|
+
});
|
|
31
|
+
it('should return false when targetUrl cannot be parsed', () => {
|
|
32
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('not-a-url', 'localhost')).to.be.false;
|
|
33
|
+
});
|
|
34
|
+
it('should match exact hostname (case-insensitive)', () => {
|
|
35
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://myhost.local/v1', 'myhost.local')).to.be.true;
|
|
36
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://MyHost.Local/v1', 'myhost.local')).to.be.true;
|
|
37
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://myhost.local/v1', 'MyHost.Local')).to.be.true;
|
|
38
|
+
});
|
|
39
|
+
it('should not match partial hostname', () => {
|
|
40
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://notmyhost.local', 'myhost.local')).to.be.false;
|
|
41
|
+
});
|
|
42
|
+
it('should match domain suffix with leading dot', () => {
|
|
43
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://api.example.com/v1', '.example.com')).to.be.true;
|
|
44
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://deep.sub.example.com', '.example.com')).to.be.true;
|
|
45
|
+
});
|
|
46
|
+
it('should match exact domain for leading dot rule', () => {
|
|
47
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://example.com/v1', '.example.com')).to.be.true;
|
|
48
|
+
});
|
|
49
|
+
it('should match suffix without leading dot', () => {
|
|
50
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://sub.example.com/v1', 'example.com')).to.be.true;
|
|
51
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://example.com/v1', 'example.com')).to.be.true;
|
|
52
|
+
});
|
|
53
|
+
it('should match wildcard', () => {
|
|
54
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://anything.com', '*')).to.be.true;
|
|
55
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('https://secure.host.org/path', '*')).to.be.true;
|
|
56
|
+
});
|
|
57
|
+
it('should match IP addresses', () => {
|
|
58
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://192.168.1.100:8080/v1', '192.168.1.100')).to.be.true;
|
|
59
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://192.168.1.100/v1', '192.168.1.100')).to.be.true;
|
|
60
|
+
});
|
|
61
|
+
it('should not match different IP addresses', () => {
|
|
62
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://192.168.1.101/v1', '192.168.1.100')).to.be.false;
|
|
63
|
+
});
|
|
64
|
+
it('should match port-specific rules', () => {
|
|
65
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://myhost:8080/v1', 'myhost:8080')).to.be.true;
|
|
66
|
+
});
|
|
67
|
+
it('should not match when port differs', () => {
|
|
68
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://myhost:9090/v1', 'myhost:8080')).to.be.false;
|
|
69
|
+
});
|
|
70
|
+
it('should not match port-specific rule when target has no port', () => {
|
|
71
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://myhost/v1', 'myhost:8080')).to.be.false;
|
|
72
|
+
});
|
|
73
|
+
it('should trim whitespace around entries', () => {
|
|
74
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://example.com', ' example.com ')).to.be.true;
|
|
75
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://foo.com', ' foo.com , bar.com ')).to.be.true;
|
|
76
|
+
});
|
|
77
|
+
it('should handle multiple comma-separated rules', () => {
|
|
78
|
+
const noProxy = 'localhost,127.0.0.1,.internal.net';
|
|
79
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://localhost/api', noProxy)).to.be.true;
|
|
80
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://127.0.0.1:3000', noProxy)).to.be.true;
|
|
81
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://service.internal.net', noProxy)).to.be.true;
|
|
82
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://external.com', noProxy)).to.be.false;
|
|
83
|
+
});
|
|
84
|
+
it('should skip empty rules from consecutive commas', () => {
|
|
85
|
+
(0, chai_1.expect)((0, proxy_util_1.shouldBypassProxy)('http://example.com', 'example.com,,localhost')).to.be.true;
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=proxy-util.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.spec.js","sourceRoot":"","sources":["../../src/common/proxy-util.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const tslib_1 = require("tslib");
|
|
19
|
+
tslib_1.__exportStar(require("./proxy-util"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAEhF,uDAA6B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a custom fetch function that routes requests through the given HTTP proxy.
|
|
3
|
+
* Returns `undefined` if no proxy URL is provided.
|
|
4
|
+
*
|
|
5
|
+
* @param proxyUrl - The proxy URL to use, or `undefined` for no proxy.
|
|
6
|
+
* @returns A custom fetch function using the proxy, or `undefined`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createProxyFetch(proxyUrl: string | undefined): typeof fetch | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Resolves the proxy URL to use for a given target URL.
|
|
11
|
+
*
|
|
12
|
+
* Resolution order:
|
|
13
|
+
* 1. If `settingsProxy` is provided (e.g., from Theia `http.proxy` preference), use it.
|
|
14
|
+
* 2. Otherwise check environment variables based on the target URL scheme.
|
|
15
|
+
* 3. If a proxy is resolved, check `no_proxy`/`NO_PROXY` — if bypass, return `undefined`.
|
|
16
|
+
* 4. Return the resolved proxy URL or `undefined` if none found.
|
|
17
|
+
*
|
|
18
|
+
* @param targetUrl - The URL for which to resolve a proxy.
|
|
19
|
+
* @param settingsProxy - An optional proxy URL from application settings.
|
|
20
|
+
* @returns The proxy URL to use, or `undefined` if no proxy should be used.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getProxyUrl(targetUrl: string | undefined, settingsProxy?: string): string | undefined;
|
|
23
|
+
//# sourceMappingURL=proxy-util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.d.ts","sourceRoot":"","sources":["../../src/node/proxy-util.ts"],"names":[],"mappings":"AAmBA;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KAAK,GAAG,SAAS,CAQvF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmCrG"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.createProxyFetch = createProxyFetch;
|
|
19
|
+
exports.getProxyUrl = getProxyUrl;
|
|
20
|
+
const undici = require("undici");
|
|
21
|
+
const proxy_util_1 = require("../common/proxy-util");
|
|
22
|
+
/**
|
|
23
|
+
* Creates a custom fetch function that routes requests through the given HTTP proxy.
|
|
24
|
+
* Returns `undefined` if no proxy URL is provided.
|
|
25
|
+
*
|
|
26
|
+
* @param proxyUrl - The proxy URL to use, or `undefined` for no proxy.
|
|
27
|
+
* @returns A custom fetch function using the proxy, or `undefined`.
|
|
28
|
+
*/
|
|
29
|
+
function createProxyFetch(proxyUrl) {
|
|
30
|
+
if (!proxyUrl) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const proxyAgent = new undici.ProxyAgent(proxyUrl);
|
|
34
|
+
return ((input, init) => fetch(input, { ...init, dispatcher: proxyAgent }));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolves the proxy URL to use for a given target URL.
|
|
38
|
+
*
|
|
39
|
+
* Resolution order:
|
|
40
|
+
* 1. If `settingsProxy` is provided (e.g., from Theia `http.proxy` preference), use it.
|
|
41
|
+
* 2. Otherwise check environment variables based on the target URL scheme.
|
|
42
|
+
* 3. If a proxy is resolved, check `no_proxy`/`NO_PROXY` — if bypass, return `undefined`.
|
|
43
|
+
* 4. Return the resolved proxy URL or `undefined` if none found.
|
|
44
|
+
*
|
|
45
|
+
* @param targetUrl - The URL for which to resolve a proxy.
|
|
46
|
+
* @param settingsProxy - An optional proxy URL from application settings.
|
|
47
|
+
* @returns The proxy URL to use, or `undefined` if no proxy should be used.
|
|
48
|
+
*/
|
|
49
|
+
function getProxyUrl(targetUrl, settingsProxy) {
|
|
50
|
+
let proxyUrl;
|
|
51
|
+
if (settingsProxy) {
|
|
52
|
+
proxyUrl = settingsProxy;
|
|
53
|
+
}
|
|
54
|
+
else if (targetUrl) {
|
|
55
|
+
let scheme;
|
|
56
|
+
try {
|
|
57
|
+
scheme = new URL(targetUrl).protocol;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
if (scheme === 'https:') {
|
|
63
|
+
proxyUrl = process.env.https_proxy
|
|
64
|
+
|| process.env.HTTPS_PROXY
|
|
65
|
+
|| process.env.http_proxy
|
|
66
|
+
|| process.env.HTTP_PROXY;
|
|
67
|
+
}
|
|
68
|
+
else if (scheme === 'http:') {
|
|
69
|
+
proxyUrl = process.env.http_proxy
|
|
70
|
+
|| process.env.HTTP_PROXY;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!proxyUrl) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
// Check no_proxy / NO_PROXY
|
|
77
|
+
const noProxy = process.env.no_proxy ?? process.env.NO_PROXY;
|
|
78
|
+
if ((0, proxy_util_1.shouldBypassProxy)(targetUrl, noProxy)) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return proxyUrl;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=proxy-util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.js","sourceRoot":"","sources":["../../src/node/proxy-util.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAYhF,4CAQC;AAeD,kCAmCC;AApED,iCAAiC;AACjC,qDAAyD;AAEzD;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,QAA4B;IACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACnD,OAAO,CAAC,CAAC,KAA6B,EAAE,IAAkB,EAAE,EAAE,CAC1D,KAAK,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,UAAU,EAAiB,CAAC,CACnD,CAAC;AACtB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,WAAW,CAAC,SAA6B,EAAE,aAAsB;IAC7E,IAAI,QAA4B,CAAC;IAEjC,IAAI,aAAa,EAAE,CAAC;QAChB,QAAQ,GAAG,aAAa,CAAC;IAC7B,CAAC;SAAM,IAAI,SAAS,EAAE,CAAC;QACnB,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACD,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtB,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW;mBAC3B,OAAO,CAAC,GAAG,CAAC,WAAW;mBACvB,OAAO,CAAC,GAAG,CAAC,UAAU;mBACtB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAClC,CAAC;aAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YAC5B,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU;mBAC1B,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QAClC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,4BAA4B;IAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC7D,IAAI,IAAA,8BAAiB,EAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.spec.d.ts","sourceRoot":"","sources":["../../src/node/proxy-util.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const chai_1 = require("chai");
|
|
19
|
+
const proxy_util_1 = require("./proxy-util");
|
|
20
|
+
describe('getProxyUrl', () => {
|
|
21
|
+
const savedEnv = {};
|
|
22
|
+
const envVars = ['http_proxy', 'HTTP_PROXY', 'https_proxy', 'HTTPS_PROXY', 'no_proxy', 'NO_PROXY'];
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
for (const key of envVars) {
|
|
25
|
+
savedEnv[key] = process.env[key];
|
|
26
|
+
delete process.env[key];
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
for (const key of envVars) {
|
|
31
|
+
if (savedEnv[key] !== undefined) {
|
|
32
|
+
process.env[key] = savedEnv[key];
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
delete process.env[key];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
it('should return settingsProxy when provided', () => {
|
|
40
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com', 'http://settings-proxy:8080')).to.equal('http://settings-proxy:8080');
|
|
41
|
+
});
|
|
42
|
+
it('should return undefined when no proxy is configured', () => {
|
|
43
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.be.undefined;
|
|
44
|
+
});
|
|
45
|
+
it('should return undefined when targetUrl is undefined and no settingsProxy', () => {
|
|
46
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)(undefined)).to.be.undefined;
|
|
47
|
+
});
|
|
48
|
+
it('should return undefined when targetUrl is not parseable', () => {
|
|
49
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('not-a-url')).to.be.undefined;
|
|
50
|
+
});
|
|
51
|
+
it('should resolve http_proxy for http URLs', () => {
|
|
52
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
53
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.equal('http://http-proxy:3128');
|
|
54
|
+
});
|
|
55
|
+
it('should resolve HTTP_PROXY for http URLs when http_proxy is not set', () => {
|
|
56
|
+
process.env.HTTP_PROXY = 'http://HTTP-PROXY:3128';
|
|
57
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.equal('http://HTTP-PROXY:3128');
|
|
58
|
+
});
|
|
59
|
+
(process.platform === 'win32' ? it.skip : it)('should prefer http_proxy over HTTP_PROXY for http URLs', () => {
|
|
60
|
+
process.env.http_proxy = 'http://lower-proxy:3128';
|
|
61
|
+
process.env.HTTP_PROXY = 'http://upper-proxy:3128';
|
|
62
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.equal('http://lower-proxy:3128');
|
|
63
|
+
});
|
|
64
|
+
it('should resolve https_proxy for https URLs', () => {
|
|
65
|
+
process.env.https_proxy = 'http://https-proxy:3128';
|
|
66
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://https-proxy:3128');
|
|
67
|
+
});
|
|
68
|
+
it('should fall back to http_proxy for https URLs', () => {
|
|
69
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
70
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://http-proxy:3128');
|
|
71
|
+
});
|
|
72
|
+
it('should prefer https_proxy over http_proxy for https URLs', () => {
|
|
73
|
+
process.env.https_proxy = 'http://https-proxy:3128';
|
|
74
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
75
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://https-proxy:3128');
|
|
76
|
+
});
|
|
77
|
+
it('should resolve HTTPS_PROXY for https URLs', () => {
|
|
78
|
+
process.env.HTTPS_PROXY = 'http://HTTPS-PROXY:3128';
|
|
79
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://HTTPS-PROXY:3128');
|
|
80
|
+
});
|
|
81
|
+
(process.platform === 'win32' ? it.skip : it)('should follow https resolution order: https_proxy > HTTPS_PROXY > http_proxy > HTTP_PROXY', () => {
|
|
82
|
+
process.env.HTTP_PROXY = 'http://HTTP-PROXY:3128';
|
|
83
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://HTTP-PROXY:3128');
|
|
84
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
85
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://http-proxy:3128');
|
|
86
|
+
process.env.HTTPS_PROXY = 'http://HTTPS-PROXY:3128';
|
|
87
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://HTTPS-PROXY:3128');
|
|
88
|
+
process.env.https_proxy = 'http://https-proxy:3128';
|
|
89
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('https://example.com')).to.equal('http://https-proxy:3128');
|
|
90
|
+
});
|
|
91
|
+
it('should bypass proxy when no_proxy matches', () => {
|
|
92
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
93
|
+
process.env.no_proxy = 'example.com';
|
|
94
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.be.undefined;
|
|
95
|
+
});
|
|
96
|
+
it('should bypass proxy when NO_PROXY matches', () => {
|
|
97
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
98
|
+
process.env.NO_PROXY = 'example.com';
|
|
99
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.be.undefined;
|
|
100
|
+
});
|
|
101
|
+
(process.platform === 'win32' ? it.skip : it)('should prefer no_proxy over NO_PROXY', () => {
|
|
102
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
103
|
+
process.env.no_proxy = 'example.com';
|
|
104
|
+
process.env.NO_PROXY = 'other.com';
|
|
105
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.be.undefined;
|
|
106
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://other.com')).to.equal('http://proxy:3128');
|
|
107
|
+
});
|
|
108
|
+
it('should not bypass proxy when no_proxy does not match', () => {
|
|
109
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
110
|
+
process.env.no_proxy = 'other.com';
|
|
111
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com')).to.equal('http://proxy:3128');
|
|
112
|
+
});
|
|
113
|
+
it('should bypass proxy even when settingsProxy is provided', () => {
|
|
114
|
+
process.env.no_proxy = 'example.com';
|
|
115
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com', 'http://settings-proxy:8080')).to.be.undefined;
|
|
116
|
+
});
|
|
117
|
+
it('should bypass proxy with NO_PROXY (uppercase) when settingsProxy is provided', () => {
|
|
118
|
+
process.env.NO_PROXY = 'example.com';
|
|
119
|
+
(0, chai_1.expect)((0, proxy_util_1.getProxyUrl)('http://example.com', 'http://settings-proxy:8080')).to.be.undefined;
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=proxy-util.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-util.spec.js","sourceRoot":"","sources":["../../src/node/proxy-util.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/ai-core",
|
|
3
|
-
"version": "1.70.0-next.
|
|
3
|
+
"version": "1.70.0-next.15+d81f78f65",
|
|
4
4
|
"description": "Theia - AI Core",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@theia/core": "1.70.0-next.
|
|
7
|
-
"@theia/editor": "1.70.0-next.
|
|
8
|
-
"@theia/filesystem": "1.70.0-next.
|
|
9
|
-
"@theia/monaco": "1.70.0-next.
|
|
6
|
+
"@theia/core": "1.70.0-next.15+d81f78f65",
|
|
7
|
+
"@theia/editor": "1.70.0-next.15+d81f78f65",
|
|
8
|
+
"@theia/filesystem": "1.70.0-next.15+d81f78f65",
|
|
9
|
+
"@theia/monaco": "1.70.0-next.15+d81f78f65",
|
|
10
10
|
"@theia/monaco-editor-core": "1.96.302",
|
|
11
|
-
"@theia/output": "1.70.0-next.
|
|
12
|
-
"@theia/variable-resolver": "1.70.0-next.
|
|
13
|
-
"@theia/workspace": "1.70.0-next.
|
|
11
|
+
"@theia/output": "1.70.0-next.15+d81f78f65",
|
|
12
|
+
"@theia/variable-resolver": "1.70.0-next.15+d81f78f65",
|
|
13
|
+
"@theia/workspace": "1.70.0-next.15+d81f78f65",
|
|
14
14
|
"@types/js-yaml": "^4.0.9",
|
|
15
15
|
"fast-deep-equal": "^3.1.3",
|
|
16
16
|
"js-yaml": "^4.1.0",
|
|
17
|
-
"tslib": "^2.6.2"
|
|
17
|
+
"tslib": "^2.6.2",
|
|
18
|
+
"undici": "^7.16.0"
|
|
18
19
|
},
|
|
19
20
|
"main": "lib/common",
|
|
20
21
|
"publishConfig": {
|
|
@@ -57,5 +58,5 @@
|
|
|
57
58
|
"nyc": {
|
|
58
59
|
"extends": "../../configs/nyc.json"
|
|
59
60
|
},
|
|
60
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "d81f78f65913085f58d8783b151a7adebb863ba2"
|
|
61
62
|
}
|
package/src/common/index.ts
CHANGED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { expect } from 'chai';
|
|
18
|
+
import { shouldBypassProxy } from './proxy-util';
|
|
19
|
+
|
|
20
|
+
describe('proxy-util', () => {
|
|
21
|
+
describe('shouldBypassProxy', () => {
|
|
22
|
+
it('should return false when targetUrl is undefined', () => {
|
|
23
|
+
expect(shouldBypassProxy(undefined, 'localhost')).to.be.false;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return false when noProxyValue is undefined', () => {
|
|
27
|
+
expect(shouldBypassProxy('http://example.com', undefined)).to.be.false;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return false when noProxyValue is empty', () => {
|
|
31
|
+
expect(shouldBypassProxy('http://example.com', '')).to.be.false;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should return false when targetUrl cannot be parsed', () => {
|
|
35
|
+
expect(shouldBypassProxy('not-a-url', 'localhost')).to.be.false;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should match exact hostname (case-insensitive)', () => {
|
|
39
|
+
expect(shouldBypassProxy('http://myhost.local/v1', 'myhost.local')).to.be.true;
|
|
40
|
+
expect(shouldBypassProxy('http://MyHost.Local/v1', 'myhost.local')).to.be.true;
|
|
41
|
+
expect(shouldBypassProxy('http://myhost.local/v1', 'MyHost.Local')).to.be.true;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should not match partial hostname', () => {
|
|
45
|
+
expect(shouldBypassProxy('http://notmyhost.local', 'myhost.local')).to.be.false;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should match domain suffix with leading dot', () => {
|
|
49
|
+
expect(shouldBypassProxy('http://api.example.com/v1', '.example.com')).to.be.true;
|
|
50
|
+
expect(shouldBypassProxy('http://deep.sub.example.com', '.example.com')).to.be.true;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should match exact domain for leading dot rule', () => {
|
|
54
|
+
expect(shouldBypassProxy('http://example.com/v1', '.example.com')).to.be.true;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should match suffix without leading dot', () => {
|
|
58
|
+
expect(shouldBypassProxy('http://sub.example.com/v1', 'example.com')).to.be.true;
|
|
59
|
+
expect(shouldBypassProxy('http://example.com/v1', 'example.com')).to.be.true;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should match wildcard', () => {
|
|
63
|
+
expect(shouldBypassProxy('http://anything.com', '*')).to.be.true;
|
|
64
|
+
expect(shouldBypassProxy('https://secure.host.org/path', '*')).to.be.true;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should match IP addresses', () => {
|
|
68
|
+
expect(shouldBypassProxy('http://192.168.1.100:8080/v1', '192.168.1.100')).to.be.true;
|
|
69
|
+
expect(shouldBypassProxy('http://192.168.1.100/v1', '192.168.1.100')).to.be.true;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should not match different IP addresses', () => {
|
|
73
|
+
expect(shouldBypassProxy('http://192.168.1.101/v1', '192.168.1.100')).to.be.false;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should match port-specific rules', () => {
|
|
77
|
+
expect(shouldBypassProxy('http://myhost:8080/v1', 'myhost:8080')).to.be.true;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should not match when port differs', () => {
|
|
81
|
+
expect(shouldBypassProxy('http://myhost:9090/v1', 'myhost:8080')).to.be.false;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should not match port-specific rule when target has no port', () => {
|
|
85
|
+
expect(shouldBypassProxy('http://myhost/v1', 'myhost:8080')).to.be.false;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should trim whitespace around entries', () => {
|
|
89
|
+
expect(shouldBypassProxy('http://example.com', ' example.com ')).to.be.true;
|
|
90
|
+
expect(shouldBypassProxy('http://foo.com', ' foo.com , bar.com ')).to.be.true;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should handle multiple comma-separated rules', () => {
|
|
94
|
+
const noProxy = 'localhost,127.0.0.1,.internal.net';
|
|
95
|
+
expect(shouldBypassProxy('http://localhost/api', noProxy)).to.be.true;
|
|
96
|
+
expect(shouldBypassProxy('http://127.0.0.1:3000', noProxy)).to.be.true;
|
|
97
|
+
expect(shouldBypassProxy('http://service.internal.net', noProxy)).to.be.true;
|
|
98
|
+
expect(shouldBypassProxy('http://external.com', noProxy)).to.be.false;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should skip empty rules from consecutive commas', () => {
|
|
102
|
+
expect(shouldBypassProxy('http://example.com', 'example.com,,localhost')).to.be.true;
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Checks whether the given target URL should bypass the proxy based on `no_proxy` rules.
|
|
19
|
+
*
|
|
20
|
+
* @param targetUrl - The URL to check against the no_proxy rules.
|
|
21
|
+
* @param noProxyValue - A comma-separated list of no_proxy rules.
|
|
22
|
+
* @returns `true` if the target URL should bypass the proxy, `false` otherwise.
|
|
23
|
+
*/
|
|
24
|
+
export function shouldBypassProxy(targetUrl: string | undefined, noProxyValue: string | undefined): boolean {
|
|
25
|
+
if (!targetUrl || !noProxyValue) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let parsed: URL;
|
|
30
|
+
try {
|
|
31
|
+
parsed = new URL(targetUrl);
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
37
|
+
const port = parsed.port;
|
|
38
|
+
|
|
39
|
+
const rules = noProxyValue.split(',');
|
|
40
|
+
for (const rawRule of rules) {
|
|
41
|
+
const rule = rawRule.trim().toLowerCase();
|
|
42
|
+
if (!rule) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (rule === '*') {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let ruleHost: string;
|
|
51
|
+
let rulePort: string | undefined;
|
|
52
|
+
const portSeparatorIndex = rule.lastIndexOf(':');
|
|
53
|
+
// Check if there's a port in the rule (only if the part after ':' is numeric)
|
|
54
|
+
if (portSeparatorIndex !== -1) {
|
|
55
|
+
const possiblePort = rule.substring(portSeparatorIndex + 1);
|
|
56
|
+
if (/^\d+$/.test(possiblePort)) {
|
|
57
|
+
ruleHost = rule.substring(0, portSeparatorIndex);
|
|
58
|
+
rulePort = possiblePort;
|
|
59
|
+
} else {
|
|
60
|
+
ruleHost = rule;
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
ruleHost = rule;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// If the rule specifies a port, the target must match it
|
|
67
|
+
if (rulePort !== undefined && port !== rulePort) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (ruleHost.startsWith('.')) {
|
|
72
|
+
// Domain suffix match: .example.com matches *.example.com
|
|
73
|
+
if (hostname.endsWith(ruleHost) || hostname === ruleHost.substring(1)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
// Exact match or suffix match (without leading dot)
|
|
78
|
+
if (hostname === ruleHost || hostname.endsWith('.' + ruleHost)) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
export * from './proxy-util';
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { expect } from 'chai';
|
|
18
|
+
import { getProxyUrl } from './proxy-util';
|
|
19
|
+
|
|
20
|
+
describe('getProxyUrl', () => {
|
|
21
|
+
const savedEnv: Record<string, string | undefined> = {};
|
|
22
|
+
const envVars = ['http_proxy', 'HTTP_PROXY', 'https_proxy', 'HTTPS_PROXY', 'no_proxy', 'NO_PROXY'];
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
for (const key of envVars) {
|
|
26
|
+
savedEnv[key] = process.env[key];
|
|
27
|
+
delete process.env[key];
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
for (const key of envVars) {
|
|
33
|
+
if (savedEnv[key] !== undefined) {
|
|
34
|
+
process.env[key] = savedEnv[key];
|
|
35
|
+
} else {
|
|
36
|
+
delete process.env[key];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should return settingsProxy when provided', () => {
|
|
42
|
+
expect(getProxyUrl('http://example.com', 'http://settings-proxy:8080')).to.equal('http://settings-proxy:8080');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should return undefined when no proxy is configured', () => {
|
|
46
|
+
expect(getProxyUrl('http://example.com')).to.be.undefined;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should return undefined when targetUrl is undefined and no settingsProxy', () => {
|
|
50
|
+
expect(getProxyUrl(undefined)).to.be.undefined;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should return undefined when targetUrl is not parseable', () => {
|
|
54
|
+
expect(getProxyUrl('not-a-url')).to.be.undefined;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should resolve http_proxy for http URLs', () => {
|
|
58
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
59
|
+
expect(getProxyUrl('http://example.com')).to.equal('http://http-proxy:3128');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should resolve HTTP_PROXY for http URLs when http_proxy is not set', () => {
|
|
63
|
+
process.env.HTTP_PROXY = 'http://HTTP-PROXY:3128';
|
|
64
|
+
expect(getProxyUrl('http://example.com')).to.equal('http://HTTP-PROXY:3128');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
(process.platform === 'win32' ? it.skip : it)('should prefer http_proxy over HTTP_PROXY for http URLs', () => {
|
|
68
|
+
process.env.http_proxy = 'http://lower-proxy:3128';
|
|
69
|
+
process.env.HTTP_PROXY = 'http://upper-proxy:3128';
|
|
70
|
+
expect(getProxyUrl('http://example.com')).to.equal('http://lower-proxy:3128');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should resolve https_proxy for https URLs', () => {
|
|
74
|
+
process.env.https_proxy = 'http://https-proxy:3128';
|
|
75
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://https-proxy:3128');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should fall back to http_proxy for https URLs', () => {
|
|
79
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
80
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://http-proxy:3128');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should prefer https_proxy over http_proxy for https URLs', () => {
|
|
84
|
+
process.env.https_proxy = 'http://https-proxy:3128';
|
|
85
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
86
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://https-proxy:3128');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should resolve HTTPS_PROXY for https URLs', () => {
|
|
90
|
+
process.env.HTTPS_PROXY = 'http://HTTPS-PROXY:3128';
|
|
91
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://HTTPS-PROXY:3128');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
(process.platform === 'win32' ? it.skip : it)('should follow https resolution order: https_proxy > HTTPS_PROXY > http_proxy > HTTP_PROXY', () => {
|
|
95
|
+
process.env.HTTP_PROXY = 'http://HTTP-PROXY:3128';
|
|
96
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://HTTP-PROXY:3128');
|
|
97
|
+
|
|
98
|
+
process.env.http_proxy = 'http://http-proxy:3128';
|
|
99
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://http-proxy:3128');
|
|
100
|
+
|
|
101
|
+
process.env.HTTPS_PROXY = 'http://HTTPS-PROXY:3128';
|
|
102
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://HTTPS-PROXY:3128');
|
|
103
|
+
|
|
104
|
+
process.env.https_proxy = 'http://https-proxy:3128';
|
|
105
|
+
expect(getProxyUrl('https://example.com')).to.equal('http://https-proxy:3128');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should bypass proxy when no_proxy matches', () => {
|
|
109
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
110
|
+
process.env.no_proxy = 'example.com';
|
|
111
|
+
expect(getProxyUrl('http://example.com')).to.be.undefined;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should bypass proxy when NO_PROXY matches', () => {
|
|
115
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
116
|
+
process.env.NO_PROXY = 'example.com';
|
|
117
|
+
expect(getProxyUrl('http://example.com')).to.be.undefined;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
(process.platform === 'win32' ? it.skip : it)('should prefer no_proxy over NO_PROXY', () => {
|
|
121
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
122
|
+
process.env.no_proxy = 'example.com';
|
|
123
|
+
process.env.NO_PROXY = 'other.com';
|
|
124
|
+
expect(getProxyUrl('http://example.com')).to.be.undefined;
|
|
125
|
+
expect(getProxyUrl('http://other.com')).to.equal('http://proxy:3128');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should not bypass proxy when no_proxy does not match', () => {
|
|
129
|
+
process.env.http_proxy = 'http://proxy:3128';
|
|
130
|
+
process.env.no_proxy = 'other.com';
|
|
131
|
+
expect(getProxyUrl('http://example.com')).to.equal('http://proxy:3128');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should bypass proxy even when settingsProxy is provided', () => {
|
|
135
|
+
process.env.no_proxy = 'example.com';
|
|
136
|
+
expect(getProxyUrl('http://example.com', 'http://settings-proxy:8080')).to.be.undefined;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should bypass proxy with NO_PROXY (uppercase) when settingsProxy is provided', () => {
|
|
140
|
+
process.env.NO_PROXY = 'example.com';
|
|
141
|
+
expect(getProxyUrl('http://example.com', 'http://settings-proxy:8080')).to.be.undefined;
|
|
142
|
+
});
|
|
143
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import * as undici from 'undici';
|
|
18
|
+
import { shouldBypassProxy } from '../common/proxy-util';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a custom fetch function that routes requests through the given HTTP proxy.
|
|
22
|
+
* Returns `undefined` if no proxy URL is provided.
|
|
23
|
+
*
|
|
24
|
+
* @param proxyUrl - The proxy URL to use, or `undefined` for no proxy.
|
|
25
|
+
* @returns A custom fetch function using the proxy, or `undefined`.
|
|
26
|
+
*/
|
|
27
|
+
export function createProxyFetch(proxyUrl: string | undefined): typeof fetch | undefined {
|
|
28
|
+
if (!proxyUrl) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const proxyAgent = new undici.ProxyAgent(proxyUrl);
|
|
32
|
+
return ((input: string | URL | Request, init?: RequestInit) =>
|
|
33
|
+
fetch(input, { ...init, dispatcher: proxyAgent } as RequestInit)
|
|
34
|
+
) as typeof fetch;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Resolves the proxy URL to use for a given target URL.
|
|
39
|
+
*
|
|
40
|
+
* Resolution order:
|
|
41
|
+
* 1. If `settingsProxy` is provided (e.g., from Theia `http.proxy` preference), use it.
|
|
42
|
+
* 2. Otherwise check environment variables based on the target URL scheme.
|
|
43
|
+
* 3. If a proxy is resolved, check `no_proxy`/`NO_PROXY` — if bypass, return `undefined`.
|
|
44
|
+
* 4. Return the resolved proxy URL or `undefined` if none found.
|
|
45
|
+
*
|
|
46
|
+
* @param targetUrl - The URL for which to resolve a proxy.
|
|
47
|
+
* @param settingsProxy - An optional proxy URL from application settings.
|
|
48
|
+
* @returns The proxy URL to use, or `undefined` if no proxy should be used.
|
|
49
|
+
*/
|
|
50
|
+
export function getProxyUrl(targetUrl: string | undefined, settingsProxy?: string): string | undefined {
|
|
51
|
+
let proxyUrl: string | undefined;
|
|
52
|
+
|
|
53
|
+
if (settingsProxy) {
|
|
54
|
+
proxyUrl = settingsProxy;
|
|
55
|
+
} else if (targetUrl) {
|
|
56
|
+
let scheme: string;
|
|
57
|
+
try {
|
|
58
|
+
scheme = new URL(targetUrl).protocol;
|
|
59
|
+
} catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (scheme === 'https:') {
|
|
64
|
+
proxyUrl = process.env.https_proxy
|
|
65
|
+
|| process.env.HTTPS_PROXY
|
|
66
|
+
|| process.env.http_proxy
|
|
67
|
+
|| process.env.HTTP_PROXY;
|
|
68
|
+
} else if (scheme === 'http:') {
|
|
69
|
+
proxyUrl = process.env.http_proxy
|
|
70
|
+
|| process.env.HTTP_PROXY;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!proxyUrl) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check no_proxy / NO_PROXY
|
|
79
|
+
const noProxy = process.env.no_proxy ?? process.env.NO_PROXY;
|
|
80
|
+
if (shouldBypassProxy(targetUrl, noProxy)) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return proxyUrl;
|
|
85
|
+
}
|