@torrent-tv/proxy 2.95.40 → 2.95.41

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": "@torrent-tv/proxy",
3
- "version": "2.95.40",
3
+ "version": "2.95.41",
4
4
  "description": "Torrent proxy client that exposes webseed-like HTTP stream endpoint.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": {
@@ -174,16 +174,28 @@ export async function readHeldRanges(torrent, fileIndex, ranges, maxBytes, logge
174
174
  if (!file || !store || !Array.isArray(ranges) || ranges.length === 0 ||
175
175
  !Number.isSafeInteger(maxBytes) || maxBytes <= 0 || !(pieceLength > 0)) return null;
176
176
  const indexes = new Set();
177
+ const pieceSpans = new Map();
177
178
  let bytes = 0;
178
- for (const range of ranges) {
179
+ for (let rangeIndex = 0; rangeIndex < ranges.length; rangeIndex++) {
180
+ const range = ranges[rangeIndex];
179
181
  if (!Array.isArray(range) || range.length !== 2) return null;
180
182
  const [start, end] = range;
181
183
  if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start || end >= file.length) return null;
182
184
  bytes += end - start + 1;
183
185
  if (!Number.isSafeInteger(bytes) || bytes > maxBytes) return null;
184
- const first = Math.floor(((Number(file.offset) || 0) + start) / pieceLength);
185
- const last = Math.floor(((Number(file.offset) || 0) + end) / pieceLength);
186
- for (let index = first; index <= last; index++) indexes.add(index);
186
+ const absoluteStart = (Number(file.offset) || 0) + start;
187
+ const absoluteEnd = (Number(file.offset) || 0) + end;
188
+ const first = Math.floor(absoluteStart / pieceLength);
189
+ const last = Math.floor(absoluteEnd / pieceLength);
190
+ for (let index = first; index <= last; index++) {
191
+ indexes.add(index);
192
+ const pieceStart = index * pieceLength;
193
+ const span = pieceSpans.get(index) ?? { start: Number.POSITIVE_INFINITY, end: -1, ranges: [] };
194
+ span.start = Math.min(span.start, Math.max(absoluteStart, pieceStart));
195
+ span.end = Math.max(span.end, Math.min(absoluteEnd, pieceStart + pieceLength - 1));
196
+ span.ranges.push({ rangeIndex, absoluteStart, absoluteEnd });
197
+ pieceSpans.set(index, span);
198
+ }
187
199
  }
188
200
  const release = store.holdAvailable([...indexes]);
189
201
  if (!release) {
@@ -199,13 +211,29 @@ export async function readHeldRanges(torrent, fileIndex, ranges, maxBytes, logge
199
211
  return null;
200
212
  }
201
213
  try {
202
- const result = [];
203
- for (const [start, end] of ranges) {
204
- const owned = await readHeldBytes(torrent, fileIndex, start, end, logger);
205
- if (!owned) return null;
206
- result.push(owned);
214
+ const result = ranges.map(([start, end]) => Buffer.allocUnsafeSlow(end - start + 1));
215
+ for (const [index, span] of pieceSpans) {
216
+ const pieceStart = index * pieceLength;
217
+ const offset = span.start - pieceStart;
218
+ const length = span.end - span.start + 1;
219
+ const buffer = await new Promise((resolve, reject) => {
220
+ store.get(index, { offset, length }, (error, value) => {
221
+ if (error) reject(error);
222
+ else resolve(value);
223
+ });
224
+ });
225
+ if (!buffer || buffer.length !== length) return null;
226
+ for (const { rangeIndex, absoluteStart, absoluteEnd } of span.ranges) {
227
+ const from = Math.max(absoluteStart, pieceStart);
228
+ const to = Math.min(absoluteEnd, pieceStart + pieceLength - 1);
229
+ const sourceStart = from - span.start;
230
+ result[rangeIndex].set(buffer.subarray(sourceStart, sourceStart + to - from + 1), from - absoluteStart);
231
+ }
207
232
  }
208
233
  return result;
234
+ } catch (error) {
235
+ logger?.info?.(`held ranges read ${fileIndex} failed: ${error?.message ?? error}`);
236
+ return null;
209
237
  } finally {
210
238
  release();
211
239
  }