Skip to content

Commit 0970060

Browse files
committed
feat: 更新 undici, fetch-socks; 修正 throwOnMaxRedirect; 请求参数支持传入 proxyTunnel
1 parent 0f4d78d commit 0970060

6 files changed

Lines changed: 91 additions & 13 deletions

File tree

backend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"dotenv": "^16.4.7",
3535
"express": "^4.17.1",
3636
"fastestsmallesttextencoderdecoder": "^1.0.22",
37-
"fetch-socks": "^1.3.2",
37+
"fetch-socks": "^1.3.3",
3838
"http-proxy-middleware": "^3.0.3",
3939
"ip-address": "^9.0.5",
4040
"js-base64": "^3.7.2",
@@ -45,7 +45,7 @@
4545
"ms": "^2.1.3",
4646
"nanoid": "^3.3.3",
4747
"semver": "^7.6.3",
48-
"undici": "^7.4.0",
48+
"undici": "^8.8.0",
4949
"yaml": "^2.9.0"
5050
},
5151
"devDependencies": {

backend/pnpm-lock.yaml

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/src/test/utils/download.spec.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
let $;
1414
let openApi;
1515
let download;
16+
let downloadFile;
1617
let resourceCache;
1718
let headersResourceCache;
1819
let originalRead;
@@ -49,7 +50,7 @@ describe('download github proxy regex', function () {
4950
({
5051
default: headersResourceCache,
5152
} = require('@/utils/headers-resource-cache'));
52-
({ default: download } = require('@/utils/download'));
53+
({ default: download, downloadFile } = require('@/utils/download'));
5354
ageUtils = require('@/utils/age');
5455

5556
originalRead = $.read.bind($);
@@ -321,4 +322,43 @@ describe('download github proxy regex', function () {
321322
wrongPair['age-secret-key'],
322323
);
323324
});
325+
326+
it('uses the Undici option that throws at the file redirect limit', async function () {
327+
const undici = eval("require('undici')");
328+
const originalAgent = undici.Agent;
329+
const originalRedirect = undici.interceptors.redirect;
330+
const originalRequest = undici.request;
331+
let redirectOptions;
332+
let error;
333+
334+
undici.Agent = class {
335+
compose() {
336+
return this;
337+
}
338+
};
339+
undici.interceptors.redirect = (options) => {
340+
redirectOptions = options;
341+
return () => {};
342+
};
343+
undici.request = async () => ({ statusCode: 500 });
344+
345+
try {
346+
await downloadFile(
347+
'https://example.com/redirecting-file',
348+
path.join(tempDir, 'redirecting-file'),
349+
);
350+
} catch (e) {
351+
error = e;
352+
} finally {
353+
undici.Agent = originalAgent;
354+
undici.interceptors.redirect = originalRedirect;
355+
undici.request = originalRequest;
356+
}
357+
358+
expect(error).to.be.instanceOf(Error);
359+
expect(redirectOptions).to.deep.equal({
360+
maxRedirections: 3,
361+
throwOnMaxRedirect: true,
362+
});
363+
});
324364
});

backend/src/test/vendor/open-api.spec.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ describe('open-api HTTP adapter', function () {
1919
let originalEnv;
2020
let originalEnvHttpProxyAgent;
2121
let originalProxyAgent;
22+
let originalRedirect;
2223
let originalRequest;
2324
let agentOptions;
25+
let redirectOptions;
2426
let requestOptions;
2527

2628
beforeEach(function () {
@@ -33,8 +35,10 @@ describe('open-api HTTP adapter', function () {
3335

3436
originalEnvHttpProxyAgent = undici.EnvHttpProxyAgent;
3537
originalProxyAgent = undici.ProxyAgent;
38+
originalRedirect = undici.interceptors.redirect;
3639
originalRequest = undici.request;
3740
agentOptions = [];
41+
redirectOptions = undefined;
3842
requestOptions = undefined;
3943

4044
class CapturingAgent {
@@ -49,6 +53,10 @@ describe('open-api HTTP adapter', function () {
4953

5054
undici.EnvHttpProxyAgent = CapturingAgent;
5155
undici.ProxyAgent = CapturingAgent;
56+
undici.interceptors.redirect = (options) => {
57+
redirectOptions = options;
58+
return () => {};
59+
};
5260
undici.request = async (_url, options) => {
5361
requestOptions = options;
5462
return {
@@ -65,6 +73,7 @@ describe('open-api HTTP adapter', function () {
6573
afterEach(function () {
6674
undici.EnvHttpProxyAgent = originalEnvHttpProxyAgent;
6775
undici.ProxyAgent = originalProxyAgent;
76+
undici.interceptors.redirect = originalRedirect;
6877
undici.request = originalRequest;
6978
proxyEnvKeys.forEach((key) => {
7079
if (originalEnv[key] == null) {
@@ -96,6 +105,33 @@ describe('open-api HTTP adapter', function () {
96105
expect(agentOptions[0].requestTls.allowH2).to.equal(false);
97106
});
98107

108+
it('passes proxyTunnel to undici proxy agents', async function () {
109+
await HTTP().get({
110+
url: 'http://example.com/subscription',
111+
proxy: 'http://127.0.0.1:8080',
112+
proxyTunnel: true,
113+
});
114+
await HTTP().get({
115+
url: 'http://example.com/subscription',
116+
proxyTunnel: true,
117+
});
118+
119+
expect(agentOptions).to.have.length(2);
120+
expect(agentOptions.map(({ proxyTunnel }) => proxyTunnel)).to.deep.equal([
121+
true,
122+
true,
123+
]);
124+
});
125+
126+
it('uses the Undici option that throws at the redirect limit', async function () {
127+
await HTTP().get('https://example.com/subscription');
128+
129+
expect(redirectOptions).to.deep.equal({
130+
maxRedirections: 3,
131+
throwOnMaxRedirect: true,
132+
});
133+
});
134+
99135
it('normalizes Node.js request header names to lowercase', async function () {
100136
await HTTP({
101137
headers: {

backend/src/utils/download.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ export async function downloadFile(url, file) {
521521
dispatcher: new Agent().compose(
522522
interceptors.redirect({
523523
maxRedirections: 3,
524-
throwOnRedirect: true,
524+
throwOnMaxRedirect: true,
525525
}),
526526
),
527527
});

backend/src/vendor/open-api.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,12 +570,14 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
570570
...agentOpts,
571571
uri: opts.proxy,
572572
requestTls: tlsOptions,
573+
proxyTunnel: opts.proxyTunnel,
573574
});
574575
}
575576
} else {
576577
dispatcher = new EnvHttpProxyAgent({
577578
...agentOpts,
578579
requestTls: tlsOptions,
580+
proxyTunnel: opts.proxyTunnel,
579581
});
580582
}
581583
const response = await request(opts.url, {
@@ -584,7 +586,7 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
584586
dispatcher: dispatcher.compose(
585587
interceptors.redirect({
586588
maxRedirections: 3,
587-
throwOnMaxRedirects: true,
589+
throwOnMaxRedirect: true,
588590
}),
589591
),
590592
});

0 commit comments

Comments
 (0)