forked from crates-pro/cratespro-frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproxy-config.ts
143 lines (125 loc) · 4.5 KB
/
proxy-config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import { HttpsProxyAgent } from "https-proxy-agent"
import { setGlobalDispatcher, ProxyAgent as UndiciProxyAgent, Dispatcher } from 'undici'
// 保存原始的 dispatcher 以便恢复
let originalDispatcher: Dispatcher | null = null;
// 代理状态标志
let proxyEnabled = false;
// 代理配置类型
export type ProxyConfig = {
isEnabled: boolean;
proxyUrl?: string;
httpsAgent?: HttpsProxyAgent;
}
// 获取代理配置
export function getProxyConfig(): ProxyConfig {
const proxyUrl = process.env.HTTPS_PROXY;
if (!proxyUrl || !proxyEnabled) {
return { isEnabled: false };
}
// 保存当前的 dispatcher 如果还没保存
if (!originalDispatcher) {
try {
// @ts-ignore - 获取当前的 dispatcher
originalDispatcher = globalThis[Symbol.for('undici.globalDispatcher.1')];
} catch (e) {
console.warn('Failed to save original dispatcher:', e);
}
}
// 配置 undici 代理
setGlobalDispatcher(new UndiciProxyAgent({
uri: proxyUrl,
connect: {
timeout: 60000,
},
keepAliveTimeout: 60000,
keepAliveMaxTimeout: 60000,
}));
// 创建 https-proxy-agent 实例
const httpsAgent = new HttpsProxyAgent(proxyUrl);
return {
isEnabled: true,
proxyUrl,
httpsAgent,
};
}
// 启用代理
export function enableProxy() {
console.log('Enabling proxy for GitHub OAuth...');
proxyEnabled = true;
return getProxyConfig();
}
// 禁用代理
export function disableProxy() {
console.log('Disabling proxy...');
proxyEnabled = false;
try {
// 恢复原始的 dispatcher
if (originalDispatcher) {
try {
setGlobalDispatcher(originalDispatcher);
console.log('Restored original dispatcher');
} catch (e) {
console.warn('Failed to restore original dispatcher:', e);
// 创建一个新的默认 dispatcher
setGlobalDispatcher(new UndiciProxyAgent({ uri: '' }));
}
} else {
// 如果没有原始 dispatcher,创建一个新的默认 dispatcher
setGlobalDispatcher(new UndiciProxyAgent({ uri: '' }));
}
// 重置全局 fetch 如果它被修改了
if (typeof globalThis !== 'undefined' && globalThis.fetch) {
// 尝试恢复原始的 fetch
try {
// @ts-ignore - 访问可能存在的原始 fetch
if (globalThis._originalFetch) {
// @ts-ignore
globalThis.fetch = globalThis._originalFetch;
console.log('Restored original fetch');
}
} catch (e) {
console.warn('Failed to restore original fetch:', e);
}
}
} catch (error) {
console.error('Error disabling proxy:', error);
}
return { isEnabled: false };
}
// 扩展的请求配置类型
export interface ExtendedRequestInit extends RequestInit {
agent?: HttpsProxyAgent;
timeout?: number;
}
// 配置全局 fetch - 不再自动启用代理
export function setupGlobalFetch() {
// 初始化时不启用代理,只保存原始 fetch
if (typeof globalThis !== 'undefined' && globalThis.fetch) {
const originalFetch = globalThis.fetch;
// 保存原始的 fetch 以便恢复
// @ts-ignore
globalThis._originalFetch = originalFetch;
globalThis.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
// 获取当前代理配置
const { isEnabled, httpsAgent } = getProxyConfig();
// 将 input 转换为字符串以检查 URL
const inputStr = input instanceof URL ? input.toString() : input.toString();
// 只有当代理启用且是 GitHub OAuth 相关请求时才使用代理
if (isEnabled && (
inputStr.includes('github.com/login/oauth') ||
inputStr.includes('api.github.com/user')
)) {
console.log('Using proxy for GitHub OAuth request:', inputStr);
const extendedInit: ExtendedRequestInit = {
...init,
agent: httpsAgent,
timeout: 60000,
};
return originalFetch(input, extendedInit as RequestInit);
} else {
// 其他请求不使用代理
return originalFetch(input, init);
}
};
}
}