@helia/verified-fetch 3.0.2 → 3.1.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 (55) hide show
  1. package/dist/index.min.js +57 -45
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/plugins/plugin-handle-byte-range-context.d.ts.map +1 -1
  4. package/dist/src/plugins/plugin-handle-byte-range-context.js +5 -0
  5. package/dist/src/plugins/plugin-handle-byte-range-context.js.map +1 -1
  6. package/dist/src/plugins/plugin-handle-car.js +2 -2
  7. package/dist/src/plugins/plugin-handle-car.js.map +1 -1
  8. package/dist/src/plugins/plugin-handle-dag-cbor.d.ts.map +1 -1
  9. package/dist/src/plugins/plugin-handle-dag-cbor.js +3 -2
  10. package/dist/src/plugins/plugin-handle-dag-cbor.js.map +1 -1
  11. package/dist/src/plugins/plugin-handle-dag-pb.d.ts +1 -0
  12. package/dist/src/plugins/plugin-handle-dag-pb.d.ts.map +1 -1
  13. package/dist/src/plugins/plugin-handle-dag-pb.js +63 -23
  14. package/dist/src/plugins/plugin-handle-dag-pb.js.map +1 -1
  15. package/dist/src/plugins/plugin-handle-dir-index-html.js +2 -2
  16. package/dist/src/plugins/plugin-handle-dir-index-html.js.map +1 -1
  17. package/dist/src/plugins/plugin-handle-ipns-record.js +2 -2
  18. package/dist/src/plugins/plugin-handle-ipns-record.js.map +1 -1
  19. package/dist/src/plugins/plugin-handle-json.d.ts.map +1 -1
  20. package/dist/src/plugins/plugin-handle-json.js +2 -3
  21. package/dist/src/plugins/plugin-handle-json.js.map +1 -1
  22. package/dist/src/plugins/plugin-handle-raw.d.ts.map +1 -1
  23. package/dist/src/plugins/plugin-handle-raw.js +6 -5
  24. package/dist/src/plugins/plugin-handle-raw.js.map +1 -1
  25. package/dist/src/plugins/plugin-handle-tar.js +2 -2
  26. package/dist/src/plugins/plugin-handle-tar.js.map +1 -1
  27. package/dist/src/utils/byte-range-context.d.ts +39 -16
  28. package/dist/src/utils/byte-range-context.d.ts.map +1 -1
  29. package/dist/src/utils/byte-range-context.js +305 -104
  30. package/dist/src/utils/byte-range-context.js.map +1 -1
  31. package/dist/src/utils/{set-content-type.d.ts → get-content-type.d.ts} +3 -4
  32. package/dist/src/utils/get-content-type.d.ts.map +1 -0
  33. package/dist/src/utils/{set-content-type.js → get-content-type.js} +3 -4
  34. package/dist/src/utils/get-content-type.js.map +1 -0
  35. package/dist/src/utils/responses.d.ts.map +1 -1
  36. package/dist/src/utils/responses.js +16 -4
  37. package/dist/src/utils/responses.js.map +1 -1
  38. package/dist/src/verified-fetch.js +1 -1
  39. package/dist/src/verified-fetch.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/plugins/plugin-handle-byte-range-context.ts +6 -0
  42. package/src/plugins/plugin-handle-car.ts +2 -2
  43. package/src/plugins/plugin-handle-dag-cbor.ts +4 -3
  44. package/src/plugins/plugin-handle-dag-pb.ts +68 -24
  45. package/src/plugins/plugin-handle-dir-index-html.ts +2 -2
  46. package/src/plugins/plugin-handle-ipns-record.ts +2 -2
  47. package/src/plugins/plugin-handle-json.ts +2 -3
  48. package/src/plugins/plugin-handle-raw.ts +7 -5
  49. package/src/plugins/plugin-handle-tar.ts +2 -2
  50. package/src/utils/byte-range-context.ts +373 -103
  51. package/src/utils/{set-content-type.ts → get-content-type.ts} +4 -5
  52. package/src/utils/responses.ts +17 -4
  53. package/src/verified-fetch.ts +1 -1
  54. package/dist/src/utils/set-content-type.d.ts.map +0 -1
  55. package/dist/src/utils/set-content-type.js.map +0 -1
@@ -1,3 +1,4 @@
1
+ import toBrowserReadableStream from 'it-to-browser-readablestream';
1
2
  import { InvalidRangeError } from '../errors.js';
2
3
  import { calculateByteRangeIndexes, getHeader } from './request-headers.js';
3
4
  import { getContentRangeHeader } from './response-headers.js';
@@ -21,14 +22,29 @@ function getBodySizeSync(body) {
21
22
  }
22
23
  function getByteRangeFromHeader(rangeHeader) {
23
24
  /**
24
- * Range: bytes=<start>-<end> | bytes=<start2>- | bytes=-<end2>
25
+ * Range: bytes=<start>-<end> | bytes=<start2>- | bytes=-<end2> | bytes=<start1>-<end1>,<start2>-<end2>,...
25
26
  */
26
- const match = rangeHeader.match(/^bytes=(?<start>\d+)?-(?<end>\d+)?$/);
27
- if (match?.groups == null) {
27
+ if (!rangeHeader.startsWith('bytes=')) {
28
28
  throw new InvalidRangeError('Invalid range request');
29
29
  }
30
- const { start, end } = match.groups;
31
- return { start, end };
30
+ const rangesStr = rangeHeader.substring(6); // Remove "bytes=" prefix
31
+ const rangeParts = rangesStr.split(',').map(part => part.trim());
32
+ const ranges = [];
33
+ for (const part of rangeParts) {
34
+ const match = part.match(/^(?<start>\d+)?-(?<end>\d+)?$/);
35
+ if (match?.groups == null) {
36
+ throw new InvalidRangeError(`Invalid range specification: ${part}`);
37
+ }
38
+ const { start, end } = match.groups;
39
+ ranges.push({
40
+ start: start ?? null,
41
+ end: end ?? null
42
+ });
43
+ }
44
+ if (ranges.length === 0) {
45
+ throw new InvalidRangeError('No valid ranges found');
46
+ }
47
+ return { ranges };
32
48
  }
33
49
  export class ByteRangeContext {
34
50
  headers;
@@ -40,11 +56,15 @@ export class ByteRangeContext {
40
56
  _body = null;
41
57
  rangeRequestHeader;
42
58
  log;
43
- requestRangeStart;
44
- requestRangeEnd;
45
- byteStart;
46
- byteEnd;
47
- byteSize;
59
+ /**
60
+ * multiPartBoundary is required for multipart responses
61
+ */
62
+ multiPartBoundary;
63
+ requestRanges = [];
64
+ byteRanges = [];
65
+ isMultiRangeRequest = false;
66
+ // to be set by isValidRangeRequest so that we don't need to re-check the byteRanges
67
+ _isValidRangeRequest = false;
48
68
  constructor(logger, headers) {
49
69
  this.headers = headers;
50
70
  this.log = logger.forComponent('helia:verified-fetch:byte-range-context');
@@ -53,31 +73,46 @@ export class ByteRangeContext {
53
73
  this.isRangeRequest = true;
54
74
  this.log.trace('range request detected');
55
75
  try {
56
- const { start, end } = getByteRangeFromHeader(this.rangeRequestHeader);
57
- this.requestRangeStart = start != null ? parseInt(start) : null;
58
- this.requestRangeEnd = end != null ? parseInt(end) : null;
76
+ const { ranges } = getByteRangeFromHeader(this.rangeRequestHeader);
77
+ this.isMultiRangeRequest = ranges.length > 1;
78
+ this.requestRanges = ranges.map(range => ({
79
+ start: range.start != null ? parseInt(range.start) : null,
80
+ end: range.end != null ? parseInt(range.end) : null
81
+ }));
82
+ this.multiPartBoundary = `multipart_byteranges_${Math.floor(Math.random() * 1000000000)}`;
59
83
  }
60
84
  catch (e) {
61
- this.log.error('error parsing range request header: %o', e);
62
- this.requestRangeStart = null;
63
- this.requestRangeEnd = null;
85
+ this.log.error('error parsing range request header - %e', e);
86
+ this.requestRanges = [];
64
87
  }
65
88
  this.setOffsetDetails();
66
89
  }
67
90
  else {
68
91
  this.log.trace('no range request detected');
69
92
  this.isRangeRequest = false;
70
- this.requestRangeStart = null;
71
- this.requestRangeEnd = null;
72
93
  }
73
94
  }
74
- setBody(body) {
75
- this._body = body;
76
- // if fileSize was already set, don't recalculate it
77
- this.setFileSize(this._fileSize ?? getBodySizeSync(body));
95
+ getByteRanges() {
96
+ return this.byteRanges;
97
+ }
98
+ /**
99
+ * You can pass a function when you need to support multi-range requests but have your own slicing logic, such as in the case of dag-pb/unixfs.
100
+ *
101
+ * @param bodyOrProvider - A supported body type or a function that returns a supported body type.
102
+ * @param contentType - The content type of the body.
103
+ */
104
+ setBody(bodyOrProvider, contentType = 'application/octet-stream') {
105
+ if (typeof bodyOrProvider === 'function') {
106
+ this._body = this.createRangeStream(bodyOrProvider, contentType);
107
+ }
108
+ else {
109
+ this._body = bodyOrProvider;
110
+ // if fileSize was already set, don't recalculate it
111
+ this.setFileSize(this._fileSize ?? getBodySizeSync(bodyOrProvider));
112
+ }
78
113
  this.log.trace('set request body with fileSize %o', this._fileSize);
79
114
  }
80
- getBody() {
115
+ getBody(responseContentType) {
81
116
  const body = this._body;
82
117
  if (body == null) {
83
118
  this.log.trace('body is null');
@@ -87,30 +122,37 @@ export class ByteRangeContext {
87
122
  this.log.trace('returning body unmodified for non-range, or invalid range, request');
88
123
  return body;
89
124
  }
90
- const byteStart = this.byteStart;
91
- const byteEnd = this.byteEnd;
92
- const byteSize = this.byteSize;
93
- if (byteStart != null || byteEnd != null) {
94
- this.log.trace('returning body with byteStart=%o, byteEnd=%o, byteSize=%o', byteStart, byteEnd, byteSize);
125
+ if (this.isMultiRangeRequest) {
126
+ if (this._body instanceof ReadableStream) {
127
+ return this._body;
128
+ }
129
+ return toBrowserReadableStream(this.getMultipartBody(responseContentType));
130
+ }
131
+ // Single range request handling
132
+ if (this.byteRanges.length > 0) {
133
+ const range = this.byteRanges[0];
95
134
  if (body instanceof ReadableStream) {
96
135
  // stream should already be spliced by `unixfs.cat`
97
136
  // TODO: if the content is not unixfs and unixfs.cat was not called, we need to slice the body here.
98
137
  return body;
99
138
  }
100
- return this.getSlicedBody(body);
139
+ if (range.start != null || range.end != null) {
140
+ this.log.trace('returning body with byteStart=%o, byteEnd=%o, byteSize=%o', range.start, range.end, range.size);
141
+ }
142
+ return this.getSlicedBody(body, range);
101
143
  }
102
144
  // we should not reach this point, but return body untouched.
103
145
  this.log.error('returning unmodified body for valid range request');
104
146
  return body;
105
147
  }
106
- getSlicedBody(body) {
107
- const offset = this.byteStart ?? 0;
148
+ getSlicedBody(body, range) {
149
+ const offset = range.start ?? 0;
108
150
  // Calculate the correct number of bytes to return
109
151
  // For a range like bytes=1000-2000, we want exactly 1001 bytes
110
152
  let length;
111
- if (this.byteEnd != null && this.byteStart != null) {
153
+ if (range.end != null && range.start != null) {
112
154
  // Exact number of bytes is (end - start + 1) due to inclusive ranges
113
- length = this.byteEnd - this.byteStart + 1;
155
+ length = range.end - range.start + 1;
114
156
  }
115
157
  else {
116
158
  length = undefined;
@@ -128,10 +170,8 @@ export class ByteRangeContext {
128
170
  // ArrayBuffer.slice and Uint8Array.slice take start and end positions
129
171
  return body.slice(offset, length !== undefined ? offset + length : undefined);
130
172
  }
131
- else {
132
- // This should never happen due to type constraints
133
- return body;
134
- }
173
+ // This should never happen due to type constraints
174
+ return body;
135
175
  }
136
176
  /**
137
177
  * Sometimes, we need to set the fileSize explicitly because we can't calculate
@@ -141,6 +181,7 @@ export class ByteRangeContext {
141
181
  */
142
182
  setFileSize(size) {
143
183
  this._fileSize = size != null ? Number(size) : null;
184
+ this._isValidRangeRequest = false; // body has changed, so we need to re-validate the byte ranges
144
185
  this.log.trace('set _fileSize to %o', this._fileSize);
145
186
  // when fileSize changes, we need to recalculate the offset details
146
187
  this.setOffsetDetails();
@@ -148,97 +189,111 @@ export class ByteRangeContext {
148
189
  getFileSize() {
149
190
  return this._fileSize;
150
191
  }
151
- isValidByteStart() {
152
- if (this.byteStart != null) {
153
- if (this.byteStart < 0) {
192
+ isValidByteStart(byteStart, byteEnd) {
193
+ if (byteStart != null) {
194
+ if (byteStart < 0) {
154
195
  return false;
155
196
  }
156
- if (this._fileSize != null && this.byteStart >= this._fileSize) {
197
+ if (this._fileSize != null && byteStart >= this._fileSize) {
157
198
  return false;
158
199
  }
159
- if (this.byteEnd != null && this.byteStart > this.byteEnd) {
200
+ if (byteEnd != null && byteStart > byteEnd) {
160
201
  return false;
161
202
  }
162
203
  }
163
204
  return true;
164
205
  }
165
- isValidByteEnd() {
166
- if (this.byteEnd != null) {
167
- if (this.byteEnd < 0) {
206
+ isValidByteEnd(byteStart, byteEnd) {
207
+ if (byteEnd != null) {
208
+ if (byteEnd < 0) {
209
+ this.log.trace('invalid range request, byteEnd is less than 0');
168
210
  return false;
169
211
  }
170
- if (this._fileSize != null && this.byteEnd >= this._fileSize) {
212
+ if (this._fileSize != null && byteEnd >= this._fileSize) {
213
+ this.log.trace('invalid range request, byteEnd is greater than fileSize');
171
214
  return false;
172
215
  }
173
- if (this.byteStart != null && this.byteEnd < this.byteStart) {
216
+ if (byteStart != null && byteEnd < byteStart) {
217
+ this.log.trace('invalid range request, byteEnd is less than byteStart');
174
218
  return false;
175
219
  }
176
220
  }
177
221
  return true;
178
222
  }
223
+ isValidByteRange(range) {
224
+ this.log.trace('validating byte range: %o', range);
225
+ if (range.start != null && !this.isValidByteStart(range.start, range.end)) {
226
+ this.log.trace('invalid range request, byteStart is less than 0 or greater than fileSize');
227
+ return false;
228
+ }
229
+ if (range.end != null && !this.isValidByteEnd(range.start, range.end)) {
230
+ this.log.trace('invalid range request, byteEnd is less than 0 or greater than fileSize');
231
+ return false;
232
+ }
233
+ return true;
234
+ }
179
235
  /**
180
236
  * We may get the values required to determine if this is a valid range request at different times
181
237
  * so we need to calculate it when asked.
182
238
  */
183
239
  get isValidRangeRequest() {
184
- if (!this.isRangeRequest) {
185
- return false;
240
+ if (this._isValidRangeRequest) {
241
+ // prevent unnecessary re-validation of each byte range
242
+ return true;
186
243
  }
187
- if (this.requestRangeStart == null && this.requestRangeEnd == null) {
188
- this.log.trace('invalid range request, range request values not provided');
189
- return false;
190
- }
191
- if (!this.isValidByteStart()) {
192
- this.log.trace('invalid range request, byteStart is less than 0 or greater than fileSize');
244
+ if (!this.isRangeRequest) {
193
245
  return false;
194
246
  }
195
- if (!this.isValidByteEnd()) {
196
- this.log.trace('invalid range request, byteEnd is less than 0 or greater than fileSize');
247
+ if (this.byteRanges.length === 0) {
248
+ this.log.trace('invalid range request, no valid ranges');
197
249
  return false;
198
250
  }
199
- if (this.requestRangeEnd != null && this.requestRangeStart != null) {
200
- // we may not have enough info.. base check on requested bytes
201
- if (this.requestRangeStart > this.requestRangeEnd) {
202
- this.log.trace('invalid range request, start is greater than end');
203
- return false;
204
- }
205
- else if (this.requestRangeStart < 0) {
206
- this.log.trace('invalid range request, start is less than 0');
207
- return false;
208
- }
209
- else if (this.requestRangeEnd < 0) {
210
- this.log.trace('invalid range request, end is less than 0');
211
- return false;
212
- }
213
- }
214
- if (this.byteEnd == null && this.byteStart == null && this.byteSize == null) {
215
- this.log.trace('invalid range request, could not calculate byteStart, byteEnd, or byteSize');
251
+ const isValid = this.byteRanges.every(range => this.isValidByteRange(range));
252
+ if (!isValid) {
253
+ this.log.trace('invalid range request, not all ranges are valid');
216
254
  return false;
217
255
  }
256
+ this._isValidRangeRequest = true;
218
257
  return true;
219
258
  }
220
- /**
221
- * Given all the information we have, this function returns the offset that will be used when:
222
- * 1. calling unixfs.cat
223
- * 2. slicing the body
224
- */
225
- get offset() {
226
- return this.byteStart ?? 0;
227
- }
259
+ // /**
260
+ // * Given all the information we have, this function returns the offset that will be used when:
261
+ // * 1. calling unixfs.cat
262
+ // * 2. slicing the body
263
+ // */
264
+ // public offset (range: ByteRange): number {
265
+ // if (this.byteRanges.length > 0) {
266
+ // return this.byteRanges[0].start ?? 0
267
+ // }
268
+ // return 0
269
+ // }
228
270
  /**
229
271
  * Given all the information we have, this function returns the length that will be used when:
230
272
  * 1. calling unixfs.cat
231
273
  * 2. slicing the body
232
274
  */
233
- get length() {
234
- if (this.byteEnd != null && this.byteStart != null) {
275
+ getLength(range) {
276
+ if (!this.isValidRangeRequest) {
277
+ this.log.error('cannot get length for invalid range request');
278
+ return undefined;
279
+ }
280
+ if (this.isMultiRangeRequest && range == null) {
281
+ /**
282
+ * The content-length for a multi-range request is the sum of the lengths of all the ranges, plus the boundaries and part headers and newlines.
283
+ */
284
+ // TODO: figure out a way to calculate the correct content-length for multi-range requests' response.
285
+ return undefined;
286
+ }
287
+ range ??= this.byteRanges[0];
288
+ this.log.trace('getting length for range: %o', range);
289
+ if (range.end != null && range.start != null) {
235
290
  // For a range like bytes=1000-2000, we want a length of 1001 bytes
236
- return this.byteEnd - this.byteStart + 1;
291
+ return range.end - range.start + 1;
237
292
  }
238
- if (this.byteEnd != null) {
239
- return this.byteEnd + 1;
293
+ if (range.end != null) {
294
+ return range.end + 1;
240
295
  }
241
- return this.byteSize;
296
+ return range.size;
242
297
  }
243
298
  /**
244
299
  * Converts a range request header into helia/unixfs supported range options
@@ -250,31 +305,112 @@ export class ByteRangeContext {
250
305
  * Range: bytes=<range-start>-<range-end>
251
306
  * Range: bytes=<range-start>-
252
307
  * Range: bytes=-<suffix-length> // must pass size so we can calculate the offset. suffix-length is the number of bytes from the end of the file.
253
- *
254
- * NOT SUPPORTED:
255
308
  * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>
256
309
  * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
257
310
  *
258
311
  * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#directives
259
312
  */
260
313
  setOffsetDetails() {
261
- if (this.requestRangeStart == null && this.requestRangeEnd == null) {
262
- this.log.trace('requestRangeStart and requestRangeEnd are null');
314
+ if (this.requestRanges.length === 0) {
315
+ this.log.trace('no request ranges defined');
263
316
  return;
264
317
  }
265
318
  try {
266
- const { start, end, byteSize } = calculateByteRangeIndexes(this.requestRangeStart ?? undefined, this.requestRangeEnd ?? undefined, this._fileSize ?? undefined);
267
- this.log.trace('set byteStart to %o, byteEnd to %o, byteSize to %o', start, end, byteSize);
268
- this.byteStart = start;
269
- this.byteEnd = end;
270
- this.byteSize = byteSize;
319
+ // Calculate byte ranges for all requests
320
+ this.byteRanges = this.requestRanges.map(range => {
321
+ const { start, end, byteSize } = calculateByteRangeIndexes(range.start ?? undefined, range.end ?? undefined, this._fileSize ?? undefined);
322
+ return { start, end, size: byteSize };
323
+ });
324
+ this.log.trace('set byte ranges: %o', this.byteRanges);
271
325
  }
272
326
  catch (e) {
273
327
  this.log.error('error setting offset details: %o', e);
274
- this.byteStart = undefined;
275
- this.byteEnd = undefined;
276
- this.byteSize = undefined;
328
+ this.byteRanges = [];
329
+ }
330
+ }
331
+ /**
332
+ * Helper to convert a SliceableBody to a Uint8Array
333
+ */
334
+ async convertToUint8Array(content) {
335
+ if (typeof content === 'string') {
336
+ return new TextEncoder().encode(content);
337
+ }
338
+ if ('arrayBuffer' in content && typeof content.arrayBuffer === 'function') {
339
+ // This is a Blob
340
+ const buffer = await content.arrayBuffer();
341
+ return new Uint8Array(buffer);
342
+ }
343
+ if ('byteLength' in content && !('buffer' in content)) {
344
+ // This is an ArrayBuffer
345
+ return new Uint8Array(content);
346
+ }
347
+ if ('buffer' in content && 'byteLength' in content && 'byteOffset' in content) {
348
+ // This is a Uint8Array
349
+ return content;
350
+ }
351
+ throw new Error('Unsupported content type for multipart response');
352
+ }
353
+ async *getMultipartBody(responseContentType = 'application/octet-stream') {
354
+ const body = this._body;
355
+ if (body instanceof ReadableStream) {
356
+ // in the case of unixfs, the body is a readable stream, and setBody is called with a function that returns a readable stream that generates the
357
+ // correct multipartBody.. so we just return that body.
358
+ return body;
359
+ }
360
+ if (body === null) {
361
+ throw new Error('Cannot create multipart body from null');
362
+ }
363
+ const encoder = new TextEncoder();
364
+ for (const range of this.byteRanges) {
365
+ if (range.start === undefined || range.end === undefined) {
366
+ continue;
367
+ }
368
+ // Calculate part headers
369
+ const partHeaderString = `\r\n--${this.multiPartBoundary}\r\n` +
370
+ `Content-Type: ${responseContentType}\r\n` +
371
+ `Content-Range: ${getContentRangeHeader({
372
+ byteStart: range.start,
373
+ byteEnd: range.end,
374
+ byteSize: this._fileSize ?? undefined
375
+ })}\r\n\r\n`;
376
+ // Convert header to Uint8Array
377
+ yield encoder.encode(partHeaderString);
378
+ // Get content for this range and convert to Uint8Array
379
+ const slicedContent = this.getSlicedBodyForRange(body, range.start, range.end);
380
+ yield await this.convertToUint8Array(slicedContent);
381
+ }
382
+ // Add final this.multiPartBoundary
383
+ yield encoder.encode(`\r\n--${this.multiPartBoundary}--`);
384
+ }
385
+ getSlicedBodyForRange(body, start, end) {
386
+ // Calculate the correct number of bytes to return
387
+ // For a range like bytes=1000-2000, we want exactly 1001 bytes
388
+ const offset = start;
389
+ const length = end - start + 1;
390
+ this.log.trace('slicing body with offset=%o and length=%o', offset, length);
391
+ if (typeof body === 'string') {
392
+ return body.slice(offset, offset + length);
393
+ }
394
+ else if (body instanceof Blob) {
395
+ return body.slice(offset, offset + length);
396
+ }
397
+ else if (body instanceof ArrayBuffer || body instanceof Uint8Array) {
398
+ return body.slice(offset, offset + length);
399
+ }
400
+ else {
401
+ // This should never happen due to type constraints
402
+ return body;
403
+ }
404
+ }
405
+ /**
406
+ * Returns the content type for the response.
407
+ * For multipart ranges, this will be multipart/byteranges with a boundary.
408
+ */
409
+ getContentType() {
410
+ if (this.isMultiRangeRequest && this.isValidRangeRequest) {
411
+ return `multipart/byteranges; boundary=${this.multiPartBoundary}`;
277
412
  }
413
+ return undefined;
278
414
  }
279
415
  /**
280
416
  * This function returns the value of the "content-range" header.
@@ -289,14 +425,79 @@ export class ByteRangeContext {
289
425
  */
290
426
  // - Content-Range: <unit> */<byteSize> // this is purposefully not in jsdoc block
291
427
  get contentRangeHeaderValue() {
428
+ // For multipart responses, this will be included in each part
429
+ // So this method is only used for single-range responses
292
430
  if (!this.isValidRangeRequest) {
293
431
  this.log.error('cannot get contentRangeHeaderValue for invalid range request');
294
432
  throw new InvalidRangeError('Invalid range request');
295
433
  }
296
- return getContentRangeHeader({
297
- byteStart: this.byteStart,
298
- byteEnd: this.byteEnd,
299
- byteSize: this._fileSize ?? undefined
434
+ if (this.isMultiRangeRequest) {
435
+ this.log.error('contentRangeHeaderValue should not be called for multipart responses');
436
+ throw new InvalidRangeError('Content-Range header not applicable for multipart responses');
437
+ }
438
+ if (this.byteRanges.length > 0) {
439
+ const range = this.byteRanges[0];
440
+ return getContentRangeHeader({
441
+ byteStart: range.start,
442
+ byteEnd: range.end,
443
+ byteSize: this._fileSize ?? undefined
444
+ });
445
+ }
446
+ throw new InvalidRangeError('No valid ranges found');
447
+ }
448
+ // Unified method to create a stream for either single or multi-range requests
449
+ createRangeStream(contentProvider, contentType) {
450
+ const encoder = new TextEncoder();
451
+ const byteRanges = this.byteRanges;
452
+ const multiPartBoundary = this.multiPartBoundary;
453
+ const fileSize = this._fileSize;
454
+ const log = this.log;
455
+ const isMultiRangeRequest = this.isMultiRangeRequest;
456
+ if (byteRanges.length === 0) {
457
+ // TODO: create a stream with a range of *
458
+ log.error('Cannot create range stream with no byte ranges');
459
+ throw new InvalidRangeError('No valid ranges found');
460
+ }
461
+ return new ReadableStream({
462
+ async start(controller) {
463
+ try {
464
+ // For multi-range requests, we need to handle multiple parts with headers
465
+ for (const range of byteRanges) {
466
+ // Write part header for multipart responses
467
+ if (isMultiRangeRequest) {
468
+ const partHeader = `\r\n--${multiPartBoundary}\r\n` +
469
+ `Content-Type: ${contentType}\r\n` +
470
+ `Content-Range: ${getContentRangeHeader({
471
+ byteStart: range.start,
472
+ byteEnd: range.end,
473
+ byteSize: fileSize ?? undefined
474
+ })}\r\n\r\n`;
475
+ controller.enqueue(encoder.encode(partHeader));
476
+ }
477
+ // Get and stream content for this range
478
+ try {
479
+ // Get content for this range
480
+ const rangeContent = contentProvider(range);
481
+ for await (const chunk of rangeContent) {
482
+ controller.enqueue(chunk);
483
+ }
484
+ }
485
+ catch (err) {
486
+ log.error('Error processing range %o: %o', range, err);
487
+ throw err; // Re-throw to be caught by the outer try/catch
488
+ }
489
+ }
490
+ if (isMultiRangeRequest) {
491
+ // Write final boundary for multipart
492
+ controller.enqueue(encoder.encode(`\r\n--${multiPartBoundary}--`));
493
+ }
494
+ controller.close();
495
+ }
496
+ catch (err) {
497
+ log.error('Error processing range(s): %o', err);
498
+ controller.error(err);
499
+ }
500
+ }
300
501
  });
301
502
  }
302
503
  }
@@ -1 +1 @@
1
- {"version":3,"file":"byte-range-context.js","sourceRoot":"","sources":["../../../src/utils/byte-range-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"byte-range-context.js","sourceRoot":"","sources":["../../../src/utils/byte-range-context.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,8 @@
1
1
  import type { ContentTypeParser } from '../types.js';
2
2
  import type { Logger } from '@libp2p/interface';
3
- export interface SetContentTypeOptions {
3
+ export interface GetContentTypeOptions {
4
4
  bytes: Uint8Array;
5
5
  path: string;
6
- response: Response;
7
6
  defaultContentType?: string;
8
7
  contentTypeParser: ContentTypeParser | undefined;
9
8
  log: Logger;
@@ -14,5 +13,5 @@ export interface SetContentTypeOptions {
14
13
  */
15
14
  filename?: string;
16
15
  }
17
- export declare function setContentType({ bytes, path, response, contentTypeParser, log, defaultContentType, filename: filenameParam }: SetContentTypeOptions): Promise<void>;
18
- //# sourceMappingURL=set-content-type.d.ts.map
16
+ export declare function getContentType({ bytes, path, contentTypeParser, log, defaultContentType, filename: filenameParam }: GetContentTypeOptions): Promise<string>;
17
+ //# sourceMappingURL=get-content-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-content-type.d.ts","sourceRoot":"","sources":["../../../src/utils/get-content-type.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,UAAU,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAA;IAChD,GAAG,EAAE,MAAM,CAAA;IAEX;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAsB,cAAc,CAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,kBAA+C,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC/L"}
@@ -1,6 +1,6 @@
1
1
  import { defaultMimeType } from './content-type-parser.js';
2
2
  import { isPromise } from './type-guards.js';
3
- export async function setContentType({ bytes, path, response, contentTypeParser, log, defaultContentType = 'application/octet-stream', filename: filenameParam }) {
3
+ export async function getContentType({ bytes, path, contentTypeParser, log, defaultContentType = 'application/octet-stream', filename: filenameParam }) {
4
4
  let contentType;
5
5
  if (contentTypeParser != null) {
6
6
  try {
@@ -32,7 +32,6 @@ export async function setContentType({ bytes, path, response, contentTypeParser,
32
32
  // if the content type is the default in our content-type-parser, instead, set it to the default content type provided to this function.
33
33
  contentType = defaultContentType;
34
34
  }
35
- log.trace('setting content type to "%s"', contentType ?? defaultContentType);
36
- response.headers.set('content-type', contentType ?? defaultContentType);
35
+ return contentType ?? defaultContentType;
37
36
  }
38
- //# sourceMappingURL=set-content-type.js.map
37
+ //# sourceMappingURL=get-content-type.js.map