@simonyea/holysheep-cli 1.7.112 → 1.7.114

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonyea/holysheep-cli",
3
- "version": "1.7.112",
3
+ "version": "1.7.114",
4
4
  "description": "Claude Code/Cursor/Cline API relay for China — ¥1=$1, WeChat/Alipay payment, no credit card, no VPN. One command setup for all AI coding tools.",
5
5
  "keywords": [
6
6
  "openai-china",
@@ -181,6 +181,7 @@ function createConnectTunnel(proxyUrl, target, headers) {
181
181
  method: 'CONNECT',
182
182
  path: target,
183
183
  headers,
184
+ timeout: 15000, // CONNECT 握手 15 秒超时
184
185
  })
185
186
 
186
187
  request.once('connect', (response, socket, head) => {
@@ -191,20 +192,49 @@ function createConnectTunnel(proxyUrl, target, headers) {
191
192
  if (head?.length) socket.unshift(head)
192
193
  resolve(socket)
193
194
  })
195
+ request.once('timeout', () => {
196
+ request.destroy(new Error('CONNECT tunnel handshake timeout'))
197
+ })
194
198
  request.once('error', reject)
195
199
  request.end()
196
200
  })
197
201
  }
198
202
 
199
203
  function pipeWithCleanup(a, b) {
200
- // TCP keepalive 检测真正的网络断开(不用 stall timer,会误杀 extended thinking)
201
204
  for (const sock of [a, b]) {
202
205
  if (typeof sock.setKeepAlive === 'function') sock.setKeepAlive(true, 10000)
203
206
  }
204
207
 
208
+ // 双阶段超时:
209
+ // 1. 客户端发了数据,上游 30 秒没回第一个字节 → 断开(node proxy 挂了)
210
+ // 2. 上游在流数据突然停了 120 秒 → 断开(stream 中断)
211
+ // 120 秒足够覆盖 extended thinking 的间歇(thinking 期间服务端仍会发心跳)
212
+ let timer = null
213
+ let streaming = false
214
+ const kill = (reason) => {
215
+ if (timer) clearTimeout(timer)
216
+ a.destroy(new Error(reason))
217
+ b.destroy(new Error(reason))
218
+ }
219
+ a.on('data', () => {
220
+ // 客户端发了数据(请求),等上游响应
221
+ if (!streaming) {
222
+ if (timer) clearTimeout(timer)
223
+ timer = setTimeout(() => kill('upstream response timeout'), 30000)
224
+ }
225
+ })
226
+ b.on('data', () => {
227
+ // 上游回数据了,切换到 stream 模式
228
+ streaming = true
229
+ // 每次收到数据重置 120 秒超时
230
+ if (timer) clearTimeout(timer)
231
+ timer = setTimeout(() => kill('upstream stream stalled'), 120000)
232
+ })
233
+
205
234
  a.pipe(b)
206
235
  b.pipe(a)
207
236
  const close = () => {
237
+ if (responseTimer) clearTimeout(responseTimer)
208
238
  a.destroy()
209
239
  b.destroy()
210
240
  }