@juzi/file-box 1.7.19 → 1.8.0

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.
Files changed (64) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/src/config.d.ts +0 -1
  3. package/dist/cjs/src/config.d.ts.map +1 -1
  4. package/dist/cjs/src/config.js +1 -3
  5. package/dist/cjs/src/config.js.map +1 -1
  6. package/dist/cjs/src/file-box.d.ts.map +1 -1
  7. package/dist/cjs/src/file-box.js +2 -2
  8. package/dist/cjs/src/file-box.js.map +1 -1
  9. package/dist/cjs/src/file-box.spec.d.ts.map +1 -1
  10. package/dist/cjs/src/file-box.spec.js +26 -2
  11. package/dist/cjs/src/file-box.spec.js.map +1 -1
  12. package/dist/cjs/src/misc.d.ts.map +1 -1
  13. package/dist/cjs/src/misc.js +254 -50
  14. package/dist/cjs/src/misc.js.map +1 -1
  15. package/dist/cjs/src/misc.spec.js +105 -15
  16. package/dist/cjs/src/misc.spec.js.map +1 -1
  17. package/dist/cjs/src/version.d.ts.map +1 -1
  18. package/dist/cjs/src/version.js +1 -1
  19. package/dist/cjs/src/version.js.map +1 -1
  20. package/dist/cjs/tests/chunk-download.spec.d.ts +3 -0
  21. package/dist/cjs/tests/chunk-download.spec.d.ts.map +1 -0
  22. package/dist/cjs/tests/chunk-download.spec.js +318 -0
  23. package/dist/cjs/tests/chunk-download.spec.js.map +1 -0
  24. package/dist/cjs/tests/misc-error-handling.spec.d.ts +3 -0
  25. package/dist/cjs/tests/misc-error-handling.spec.d.ts.map +1 -0
  26. package/dist/cjs/tests/misc-error-handling.spec.js +352 -0
  27. package/dist/cjs/tests/misc-error-handling.spec.js.map +1 -0
  28. package/dist/cjs/tests/network-timeout.spec.js +15 -2
  29. package/dist/cjs/tests/network-timeout.spec.js.map +1 -1
  30. package/dist/esm/src/config.d.ts +0 -1
  31. package/dist/esm/src/config.d.ts.map +1 -1
  32. package/dist/esm/src/config.js +0 -2
  33. package/dist/esm/src/config.js.map +1 -1
  34. package/dist/esm/src/file-box.d.ts.map +1 -1
  35. package/dist/esm/src/file-box.js +2 -2
  36. package/dist/esm/src/file-box.js.map +1 -1
  37. package/dist/esm/src/file-box.spec.d.ts.map +1 -1
  38. package/dist/esm/src/file-box.spec.js +27 -3
  39. package/dist/esm/src/file-box.spec.js.map +1 -1
  40. package/dist/esm/src/misc.d.ts.map +1 -1
  41. package/dist/esm/src/misc.js +256 -52
  42. package/dist/esm/src/misc.js.map +1 -1
  43. package/dist/esm/src/misc.spec.js +105 -15
  44. package/dist/esm/src/misc.spec.js.map +1 -1
  45. package/dist/esm/src/version.d.ts.map +1 -1
  46. package/dist/esm/src/version.js +1 -1
  47. package/dist/esm/src/version.js.map +1 -1
  48. package/dist/esm/tests/chunk-download.spec.d.ts +3 -0
  49. package/dist/esm/tests/chunk-download.spec.d.ts.map +1 -0
  50. package/dist/esm/tests/chunk-download.spec.js +316 -0
  51. package/dist/esm/tests/chunk-download.spec.js.map +1 -0
  52. package/dist/esm/tests/misc-error-handling.spec.d.ts +3 -0
  53. package/dist/esm/tests/misc-error-handling.spec.d.ts.map +1 -0
  54. package/dist/esm/tests/misc-error-handling.spec.js +350 -0
  55. package/dist/esm/tests/misc-error-handling.spec.js.map +1 -0
  56. package/dist/esm/tests/network-timeout.spec.js +15 -2
  57. package/dist/esm/tests/network-timeout.spec.js.map +1 -1
  58. package/package.json +11 -4
  59. package/src/config.ts +0 -3
  60. package/src/file-box.spec.ts +34 -7
  61. package/src/file-box.ts +5 -5
  62. package/src/misc.spec.ts +120 -18
  63. package/src/misc.ts +242 -57
  64. package/src/version.ts +1 -1
@@ -14,12 +14,15 @@ const https_1 = __importDefault(require("https"));
14
14
  const https_proxy_agent_1 = require("https-proxy-agent");
15
15
  const os_1 = require("os");
16
16
  const path_1 = require("path");
17
+ const stream_1 = require("stream");
18
+ const promises_2 = require("stream/promises");
17
19
  const url_1 = require("url");
18
20
  const config_js_1 = require("./config.js");
19
21
  const protocolMap = {
20
22
  'http:': { agent: http_1.default.globalAgent, request: http_1.default.request },
21
23
  'https:': { agent: https_1.default.globalAgent, request: https_1.default.request },
22
24
  };
25
+ const noop = () => { };
23
26
  const unsupportedRangeDomains = new Set();
24
27
  function getProtocol(protocol) {
25
28
  (0, assert_1.default)(protocolMap[protocol], new Error('unknown protocol: ' + protocol));
@@ -44,8 +47,8 @@ async function httpHeadHeader(url, headers = {}, proxyUrl) {
44
47
  throw new Error(`ttl expired! too many(>${REDIRECT_TTL}) 302 redirection.`);
45
48
  }
46
49
  const res = await fetch(url, {
47
- method: 'HEAD',
48
50
  headers,
51
+ method: 'HEAD',
49
52
  }, proxyUrl);
50
53
  res.destroy();
51
54
  if (!/^3/.test(String(res.statusCode))) {
@@ -58,7 +61,8 @@ async function httpHeadHeader(url, headers = {}, proxyUrl) {
58
61
  if (!res.headers.location) {
59
62
  throw new Error('302 found but no location!');
60
63
  }
61
- url = res.headers.location;
64
+ // Location 可能是相对路径,需要以当前 url 作为 base 解析
65
+ url = new url_1.URL(res.headers.location, url).toString();
62
66
  }
63
67
  }
64
68
  exports.httpHeadHeader = httpHeadHeader;
@@ -87,8 +91,12 @@ async function httpStream(url, headers = {}, proxyUrl) {
87
91
  method: 'GET',
88
92
  };
89
93
  const fileSize = Number(headHeaders['content-length']);
90
- if (!unsupportedRangeDomains.has(hostname) && !config_js_1.NO_SLICE_DOWN && headHeaders['accept-ranges'] === 'bytes' && fileSize > config_js_1.HTTP_CHUNK_SIZE) {
91
- return await downloadFileInChunks(url, options, fileSize, config_js_1.HTTP_CHUNK_SIZE, proxyUrl);
94
+ // 运行时读取 env:方便测试/调用方动态调整
95
+ const noSliceDown = process.env['FILEBOX_NO_SLICE_DOWN'] === 'true';
96
+ // 检查服务器是否支持 range 请求
97
+ const supportsRange = headHeaders['accept-ranges'] === 'bytes';
98
+ if (!unsupportedRangeDomains.has(hostname) && !noSliceDown && supportsRange && fileSize > 0) {
99
+ return await downloadFileInChunks(url, options, proxyUrl);
92
100
  }
93
101
  else {
94
102
  return await fetch(url, options, proxyUrl);
@@ -98,96 +106,292 @@ exports.httpStream = httpStream;
98
106
  async function fetch(url, options, proxyUrl) {
99
107
  const { protocol } = new url_1.URL(url);
100
108
  const { request, agent } = getProtocol(protocol);
109
+ const abortController = new AbortController();
110
+ const signal = abortController.signal;
101
111
  const opts = {
102
112
  agent,
103
113
  ...options,
114
+ signal,
104
115
  };
105
116
  setProxy(opts, proxyUrl);
106
117
  const req = request(url, opts);
107
- req
108
- .on('error', () => {
109
- req.destroy();
118
+ let res;
119
+ // 兜底:任何时候 req.error 都不会变成 uncaughtException
120
+ const onReqError = (err) => {
121
+ const error = err instanceof Error ? err : new Error(String(err));
122
+ // 统一用 abort 中止请求:signal 已挂在 req 上,并且我们会把 abort(reason) 桥接到 res.destroy(...)
123
+ abortController.abort(error);
124
+ };
125
+ req.on('error', noop)
126
+ .on('error', onReqError)
127
+ .once('close', () => {
128
+ // close 后禁用 request timeout,避免定时器晚到触发 destroy -> error 无人监听
129
+ try {
130
+ req.setTimeout(0);
131
+ }
132
+ catch { }
133
+ req.off('error', onReqError);
134
+ req.off('error', noop);
110
135
  })
136
+ // request timeout:只用于“拿到 response 之前”(连接/握手/首包)
111
137
  .setTimeout(config_js_1.HTTP_REQUEST_TIMEOUT, () => {
112
- req.emit('error', new Error(`FileBox: Http request timeout (${config_js_1.HTTP_REQUEST_TIMEOUT})!`));
138
+ // 已经拿到 response 时,不要再用 request timeout 误伤(会导致 aborted/ECONNRESET)
139
+ if (res)
140
+ return;
141
+ abortController.abort(new Error(`FileBox: Http request timeout (${config_js_1.HTTP_REQUEST_TIMEOUT})!`));
113
142
  })
114
143
  .end();
115
- const responseEvents = await (0, events_1.once)(req, 'response');
116
- const res = responseEvents[0];
144
+ try {
145
+ const responseEvent = await (0, events_1.once)(req, 'response', { signal });
146
+ res = responseEvent[0];
147
+ // response 到来后清掉 request timeout,避免误伤长下载导致 aborted/ECONNRESET
148
+ try {
149
+ req.setTimeout(0);
150
+ }
151
+ catch { }
152
+ // 必须尽早挂,避免 “response 刚到就 error/abort” 的竞态导致 uncaughtException
153
+ res.on('error', noop);
154
+ signal.throwIfAborted();
155
+ }
156
+ catch (e) {
157
+ // once(...) 被 signal abort 时通常会抛 AbortError;优先抛出 abort(reason) 的真实原因
158
+ const reason = signal.reason;
159
+ const err = reason instanceof Error
160
+ ? reason
161
+ : (e instanceof Error ? e : new Error(String(e)));
162
+ // 失败时尽量主动清理,避免 socket 悬挂(destroy 重复调用是安全的)
163
+ try {
164
+ res?.destroy(err);
165
+ }
166
+ catch { }
167
+ try {
168
+ req.destroy(err);
169
+ }
170
+ catch { }
171
+ throw err;
172
+ }
173
+ const onAbort = () => {
174
+ const reason = signal.reason;
175
+ res?.destroy(reason instanceof Error ? reason : new Error(String(reason)));
176
+ };
177
+ signal.addEventListener('abort', onAbort, { once: true });
117
178
  res
118
- .on('error', () => {
119
- res.destroy();
120
- });
121
- if (res.socket) {
122
- res.setTimeout(config_js_1.HTTP_RESPONSE_TIMEOUT, () => {
123
- res.emit('error', new Error(`FileBox: Http response timeout (${config_js_1.HTTP_RESPONSE_TIMEOUT})!`));
124
- });
179
+ .once('end', () => { try {
180
+ res.setTimeout(0);
125
181
  }
182
+ catch { } })
183
+ .once('close', () => {
184
+ // close 时做清理/兜底判断(尽力而为)
185
+ try {
186
+ res.setTimeout(0);
187
+ }
188
+ catch { }
189
+ if (!res.complete && !res.destroyed) {
190
+ // 有些场景不会 emit 'aborted',用 close + complete 兜底一次
191
+ res.destroy(new Error('FileBox: Http response aborted!'));
192
+ }
193
+ signal.removeEventListener('abort', onAbort);
194
+ res.off('error', noop);
195
+ })
196
+ .setTimeout(config_js_1.HTTP_RESPONSE_TIMEOUT, () => {
197
+ abortController.abort(new Error(`FileBox: Http response timeout (${config_js_1.HTTP_RESPONSE_TIMEOUT})!`));
198
+ });
126
199
  return res;
127
200
  }
128
- async function downloadFileInChunks(url, options, fileSize, chunkSize = config_js_1.HTTP_CHUNK_SIZE, proxyUrl) {
201
+ function createSkipTransform(skipBytes) {
202
+ let skipped = 0;
203
+ return new stream_1.Transform({
204
+ transform(chunk, _encoding, callback) {
205
+ if (skipped < skipBytes) {
206
+ const remaining = skipBytes - skipped;
207
+ if (chunk.length <= remaining) {
208
+ // 整个 chunk 都需要跳过
209
+ skipped += chunk.length;
210
+ callback();
211
+ return;
212
+ }
213
+ else {
214
+ // 跳过部分 chunk
215
+ skipped = skipBytes;
216
+ callback(null, chunk.subarray(remaining));
217
+ return;
218
+ }
219
+ }
220
+ // 已经跳过足够的字节,直接传递
221
+ callback(null, chunk);
222
+ },
223
+ });
224
+ }
225
+ async function downloadFileInChunks(url, options, proxyUrl) {
129
226
  const tmpFile = (0, path_1.join)((0, os_1.tmpdir)(), `filebox-${(0, crypto_1.randomUUID)()}`);
130
227
  const writeStream = (0, fs_1.createWriteStream)(tmpFile);
228
+ const writeAbortController = new AbortController();
229
+ const signal = writeAbortController.signal;
230
+ const onWriteError = (err) => {
231
+ writeAbortController.abort(err instanceof Error ? err : new Error(String(err)));
232
+ };
233
+ writeStream.once('error', onWriteError);
131
234
  const allowStatusCode = [200, 206];
132
235
  const requestBaseOptions = {
133
236
  headers: {},
134
237
  ...options,
135
238
  };
136
- let chunkSeq = 0;
239
+ // 预期文件大小(初始为 null,从首次 206 响应中获取)
240
+ let expectedTotal = null;
137
241
  let start = 0;
138
- let end = 0;
139
242
  let downSize = 0;
140
243
  let retries = 3;
141
- while (downSize < fileSize) {
142
- end = Math.min(start + chunkSize, fileSize - 1);
143
- const range = `bytes=${start}-${end}`;
244
+ // 标识是否需要回退到非分片下载
245
+ let shouldFallback = false;
246
+ do {
247
+ // 每次循环前检查文件实际大小,作为真实的下载进度
248
+ // 这样在重试时可以从实际写入的位置继续,避免数据重复
249
+ try {
250
+ const fileStats = await (0, promises_1.stat)(tmpFile);
251
+ const actualSize = fileStats.size;
252
+ if (actualSize > downSize) {
253
+ // 文件实际大小比记录的大,说明之前有部分写入
254
+ downSize = actualSize;
255
+ start = actualSize;
256
+ }
257
+ }
258
+ catch (error) {
259
+ // 文件不存在或无法访问,使用当前的 downSize
260
+ }
261
+ const range = `bytes=${start}-`;
144
262
  const requestOptions = Object.assign({}, requestBaseOptions);
145
263
  (0, assert_1.default)(requestOptions.headers, 'Errors that should not happen: Invalid headers');
146
264
  requestOptions.headers['Range'] = range;
265
+ // 每次请求创建独立的 AbortController 来管理当前请求的生命周期
266
+ const requestAbortController = new AbortController();
267
+ requestOptions.signal = requestAbortController.signal;
147
268
  try {
148
269
  const res = await fetch(url, requestOptions, proxyUrl);
149
270
  if (res.statusCode === 416) {
150
- unsupportedRangeDomains.add(new url_1.URL(url).hostname);
151
271
  // 某些云服务商对分片下载的支持可能不规范,需要保留一个回退的方式
152
- writeStream.close();
153
- await (0, promises_1.rm)(tmpFile, { force: true });
154
- return await fetch(url, requestBaseOptions, proxyUrl);
272
+ shouldFallback = true;
273
+ break;
155
274
  }
156
275
  (0, assert_1.default)(allowStatusCode.includes(res.statusCode ?? 0), `Request failed with status code ${res.statusCode}`);
157
- (0, assert_1.default)(Number(res.headers['content-length']) > 0, 'Server returned 0 bytes of data');
158
- try {
159
- const { total } = parseContentRange(res.headers['content-range'] ?? '');
160
- if (total > 0 && total < fileSize) {
276
+ const contentLength = Number(res.headers['content-length']);
277
+ (0, assert_1.default)(contentLength > 0, 'Server returned 0 bytes of data');
278
+ // 206: 部分内容,继续分片下载
279
+ // 200: 完整内容,服务器不支持 range 或返回全部数据
280
+ if (res.statusCode === 206) {
281
+ // 206 响应必须包含有效的 Content-Range 头(RFC 7233)
282
+ const contentRange = res.headers['content-range'];
283
+ if (!contentRange) {
284
+ // Content-Range 缺失,服务器不规范,回退到非分片下载
285
+ shouldFallback = true;
286
+ break;
287
+ }
288
+ let end;
289
+ let total;
290
+ let actualStart;
291
+ try {
292
+ const parsed = parseContentRange(contentRange);
293
+ actualStart = parsed.start;
294
+ end = parsed.end;
295
+ total = parsed.total;
296
+ }
297
+ catch (error) {
298
+ // Content-Range 格式错误,服务器不规范,回退到非分片下载
299
+ shouldFallback = true;
300
+ break;
301
+ }
302
+ if (expectedTotal === null) {
303
+ // 首次获得文件总大小
161
304
  // 某些云服务商(如腾讯云)在 head 方法中返回的 size 是原图大小,但下载时返回的是压缩后的图片,会比原图小。
162
- // 这种在首次下载时虽然请求了原图大小的范围,可能比缩略图大,但会一次性返回完整的原图,而不是报错 416,通过修正 fileSize 跳出循环即可。
163
- fileSize = total;
305
+ // 这种在首次下载时虽然请求了原图大小的范围,可能比缩略图大,但会一次性返回完整的原图,而不是报错 416,通过修正 expectedTotal 跳出循环即可。
306
+ expectedTotal = total;
307
+ }
308
+ else if (total !== expectedTotal) {
309
+ // 服务器返回的文件总大小出现了变化
310
+ throw new Error(`File size mismatch: expected ${expectedTotal}, but server returned ${total}`);
164
311
  }
312
+ // 验证服务器返回的范围是否与请求匹配
313
+ if (actualStart !== start) {
314
+ if (actualStart > start) {
315
+ // 服务器跳过了部分数据,这是严重错误
316
+ throw new Error(`Range mismatch: requested start=${start}, but server returned start=${actualStart} (gap detected)`);
317
+ }
318
+ else {
319
+ // actualStart < start: 服务器返回了重叠数据,需要跳过前面的字节
320
+ const skipBytes = start - actualStart;
321
+ const skipTransform = createSkipTransform(skipBytes);
322
+ await (0, promises_2.pipeline)(res, skipTransform, writeStream, { end: false, signal });
323
+ // 更新进度时使用我们请求的范围,而不是服务器返回的范围
324
+ downSize += end - actualStart + 1 - skipBytes;
325
+ start = downSize;
326
+ retries = 3; // 成功后重置重试次数
327
+ continue;
328
+ }
329
+ }
330
+ // 使用 pipeline,但不关闭 writeStream(继续下载下一个分片)
331
+ await (0, promises_2.pipeline)(res, writeStream, { end: false, signal });
332
+ // pipeline 成功后才更新下载进度
333
+ // end 是最后一个字节的索引,下次从 end+1 开始
334
+ downSize += end - start + 1;
335
+ start = downSize;
165
336
  }
166
- catch (error) { }
167
- for await (const chunk of res) {
168
- (0, assert_1.default)(Buffer.isBuffer(chunk));
169
- downSize += chunk.length;
170
- writeStream.write(chunk);
337
+ else {
338
+ // 200: 服务器返回完整文件,不支持 range
339
+ if (start > 0) {
340
+ // 中途收到 200,服务器停止支持 range,标记并回退到普通下载
341
+ shouldFallback = true;
342
+ break;
343
+ }
344
+ // 首次请求返回 200,正常处理
345
+ await (0, promises_2.pipeline)(res, writeStream, { signal });
346
+ downSize = contentLength;
347
+ break;
171
348
  }
172
- res.destroy();
349
+ // 成功后重置重试次数
350
+ retries = 3;
173
351
  }
174
352
  catch (error) {
175
- const err = error;
353
+ const err = error instanceof Error ? error : new Error(String(error));
176
354
  if (--retries <= 0) {
177
- writeStream.close();
178
- void (0, promises_1.rm)(tmpFile, { force: true });
355
+ writeStream.destroy();
356
+ await (0, promises_1.rm)(tmpFile, { force: true });
179
357
  throw new Error(`Download file with chunk failed! ${err.message}`, { cause: err });
180
358
  }
359
+ // 失败后等待一小段时间再重试
360
+ await new Promise(resolve => setTimeout(resolve, 100));
361
+ }
362
+ finally {
363
+ // 确保请求被清理(成功时也需要 abort 以释放资源)
364
+ requestAbortController.abort();
181
365
  }
182
- chunkSeq++;
183
- start = downSize;
366
+ } while (expectedTotal === null || downSize < expectedTotal);
367
+ // 统一处理回退到非分片下载的情况
368
+ if (shouldFallback) {
369
+ unsupportedRangeDomains.add(new url_1.URL(url).hostname);
370
+ writeStream.destroy();
371
+ try {
372
+ await (0, events_1.once)(writeStream, 'close', { signal });
373
+ }
374
+ catch { }
375
+ await (0, promises_1.rm)(tmpFile, { force: true });
376
+ return await fetch(url, requestBaseOptions, proxyUrl);
377
+ }
378
+ writeStream.end();
379
+ try {
380
+ await (0, events_1.once)(writeStream, 'finish', { signal });
381
+ }
382
+ catch (e) {
383
+ const reason = signal.reason;
384
+ if (reason instanceof Error) {
385
+ throw reason;
386
+ }
387
+ throw e;
388
+ }
389
+ finally {
390
+ writeStream.off('error', onWriteError);
184
391
  }
185
- writeStream.close();
186
392
  const readStream = (0, fs_1.createReadStream)(tmpFile);
187
- readStream
188
- .once('end', () => readStream.close())
189
- .once('close', () => {
190
- void (0, promises_1.rm)(tmpFile, { force: true });
393
+ readStream.once('close', () => {
394
+ (0, promises_1.rm)(tmpFile, { force: true }).catch(() => { });
191
395
  });
192
396
  return readStream;
193
397
  }
@@ -211,8 +415,8 @@ function parseContentRange(contentRange) {
211
415
  throw new Error('Invalid content range');
212
416
  }
213
417
  return {
214
- start: Number(matches[1]),
215
418
  end: Number(matches[2]),
419
+ start: Number(matches[1]),
216
420
  total: Number(matches[3]),
217
421
  };
218
422
  }
@@ -1 +1 @@
1
- {"version":3,"file":"misc.js","sourceRoot":"","sources":["../../../src/misc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"misc.js","sourceRoot":"","sources":["../../../src/misc.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  // tslint:disable:no-shadowed-variable
5
+ const http_1 = require("http");
5
6
  const tstest_1 = require("tstest");
6
7
  const misc_js_1 = require("./misc.js");
7
8
  (0, tstest_1.test)('dataUrl to base64', async (t) => {
@@ -18,11 +19,36 @@ const misc_js_1 = require("./misc.js");
18
19
  t.equal(base64, (0, misc_js_1.dataUrlToBase64)(dataUrl), 'should get base64 from dataUrl');
19
20
  });
20
21
  (0, tstest_1.test)('httpHeadHeader', async (t) => {
21
- const URL = 'https://github.com/huan/file-box/archive/v0.6.tar.gz';
22
- const EXPECTED_HEADERS_KEY = 'content-disposition';
23
- const EXPECTED_HEADERS_VALUE = 'attachment; filename=file-box-0.6.tar.gz';
24
- const headers = await (0, misc_js_1.httpHeadHeader)(URL);
25
- t.equal(headers[EXPECTED_HEADERS_KEY], EXPECTED_HEADERS_VALUE, 'should get the headers right');
22
+ /**
23
+ * 使用本地 server,避免依赖外网(CI/本地网络不稳定会导致 flaky)
24
+ * 同时覆盖:302 Location 为相对路径的跳转逻辑
25
+ */
26
+ const server = (0, http_1.createServer)((req, res) => {
27
+ if (req.url === '/redirect') {
28
+ res.writeHead(302, { Location: '/final' });
29
+ res.end();
30
+ return;
31
+ }
32
+ if (req.url === '/final') {
33
+ res.writeHead(200, {
34
+ 'Content-Disposition': 'attachment; filename=file-box-0.6.tar.gz',
35
+ 'Content-Length': '0',
36
+ });
37
+ res.end();
38
+ return;
39
+ }
40
+ res.writeHead(404);
41
+ res.end();
42
+ });
43
+ const host = await new Promise((resolve) => {
44
+ server.listen(0, '127.0.0.1', () => {
45
+ const addr = server.address();
46
+ resolve(`http://127.0.0.1:${addr.port}`);
47
+ });
48
+ });
49
+ t.teardown(() => { server.close(); });
50
+ const headers = await (0, misc_js_1.httpHeadHeader)(`${host}/redirect`);
51
+ t.equal(headers['content-disposition'], 'attachment; filename=file-box-0.6.tar.gz', 'should get the headers right');
26
52
  });
27
53
  (0, tstest_1.test)('httpHeaderToFileName', async (t) => {
28
54
  const HEADERS_QUOTATION_MARK = {
@@ -38,23 +64,87 @@ const misc_js_1 = require("./misc.js");
38
64
  t.equal(filename, EXPECTED_FILE_NAME, 'should get filename with no quotation mark');
39
65
  });
40
66
  (0, tstest_1.test)('httpStream', async (t) => {
41
- const URL = 'https://httpbin.org/headers';
67
+ const server = (0, http_1.createServer)((req, res) => {
68
+ const content = JSON.stringify({ headers: req.headers });
69
+ // Handle HEAD requests
70
+ if (req.method === 'HEAD') {
71
+ res.writeHead(200, {
72
+ 'Content-Length': String(content.length),
73
+ 'Content-Type': 'application/json',
74
+ });
75
+ res.end();
76
+ return;
77
+ }
78
+ res.writeHead(200, {
79
+ 'Content-Length': String(content.length),
80
+ 'Content-Type': 'application/json',
81
+ });
82
+ res.end(content);
83
+ });
84
+ const host = await new Promise((resolve) => {
85
+ server.listen(0, '127.0.0.1', () => {
86
+ const addr = server.address();
87
+ resolve(`http://127.0.0.1:${addr.port}`);
88
+ });
89
+ });
90
+ t.teardown(() => { server.close(); });
42
91
  const MOL_KEY = 'Mol';
43
92
  const MOL_VAL = '42';
44
93
  const headers = {};
45
94
  headers[MOL_KEY] = MOL_VAL;
46
- const res = await (0, misc_js_1.httpStream)(URL, headers);
95
+ const res = await (0, misc_js_1.httpStream)(`${host}/headers`, headers);
47
96
  const buffer = await (0, misc_js_1.streamToBuffer)(res);
48
97
  const obj = JSON.parse(buffer.toString());
49
- t.equal(obj.headers[MOL_KEY], MOL_VAL, 'should send the header right');
98
+ // Node 会把 header name 规范成小写
99
+ t.equal(obj.headers[MOL_KEY.toLowerCase()], MOL_VAL, 'should send the header right');
50
100
  });
51
101
  (0, tstest_1.test)('httpStream in chunks', async (t) => {
52
- const URL = 'https://media.w3.org/2010/05/sintel/trailer.mp4';
53
- const res = await (0, misc_js_1.httpStream)(URL);
54
- let length = 0;
55
- for await (const chunk of res) {
56
- length += chunk.length;
57
- }
58
- t.equal(length, 4372373, 'should get data in chunks right');
102
+ const FILE_SIZE = 1024 * 1024 + 123; // > 默认 chunk size 触发分片逻辑
103
+ const content = Buffer.alloc(FILE_SIZE, 'A');
104
+ const server = (0, http_1.createServer)((req, res) => {
105
+ // HEAD:让 httpStream 判断是否支持 range + content-length
106
+ if (req.method === 'HEAD') {
107
+ res.writeHead(200, {
108
+ 'Accept-Ranges': 'bytes',
109
+ 'Content-Length': String(FILE_SIZE),
110
+ });
111
+ res.end();
112
+ return;
113
+ }
114
+ const range = req.headers.range;
115
+ if (range) {
116
+ const m = String(range).match(/bytes=(\d+)-(\d*)/);
117
+ if (!m) {
118
+ res.writeHead(416);
119
+ res.end();
120
+ return;
121
+ }
122
+ const start = Number(m[1]);
123
+ const end = m[2] ? Number(m[2]) : FILE_SIZE - 1;
124
+ const chunk = content.subarray(start, end + 1);
125
+ res.writeHead(206, {
126
+ 'Accept-Ranges': 'bytes',
127
+ 'Content-Length': String(chunk.length),
128
+ 'Content-Range': `bytes ${start}-${end}/${FILE_SIZE}`,
129
+ });
130
+ res.end(chunk);
131
+ return;
132
+ }
133
+ res.writeHead(200, {
134
+ 'Accept-Ranges': 'bytes',
135
+ 'Content-Length': String(FILE_SIZE),
136
+ });
137
+ res.end(content);
138
+ });
139
+ const host = await new Promise((resolve) => {
140
+ server.listen(0, '127.0.0.1', () => {
141
+ const addr = server.address();
142
+ resolve(`http://127.0.0.1:${addr.port}`);
143
+ });
144
+ });
145
+ t.teardown(() => { server.close(); });
146
+ const res = await (0, misc_js_1.httpStream)(`${host}/file`);
147
+ const buffer = await (0, misc_js_1.streamToBuffer)(res);
148
+ t.equal(buffer.length, FILE_SIZE, 'should get data in chunks right');
59
149
  });
60
150
  //# sourceMappingURL=misc.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"misc.spec.js","sourceRoot":"","sources":["../../../src/misc.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"misc.spec.js","sourceRoot":"","sources":["../../../src/misc.spec.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAiB,CAAA"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAA"}
@@ -4,5 +4,5 @@ exports.VERSION = void 0;
4
4
  /**
5
5
  * This file was auto generated from scripts/generate-version.sh
6
6
  */
7
- exports.VERSION = '1.7.19';
7
+ exports.VERSION = '1.8.0';
8
8
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/version.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,OAAO,GAAW,QAAQ,CAAA"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/version.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,OAAO,GAAW,OAAO,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env -S node --no-warnings --loader ts-node/esm
2
+ export {};
3
+ //# sourceMappingURL=chunk-download.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-download.spec.d.ts","sourceRoot":"","sources":["../../../tests/chunk-download.spec.ts"],"names":[],"mappings":""}