Skip to content

Commit 1264106

Browse files
authored
feat: add maxPieceLength option (#267)
* feat: add maxPieceLength option to address #266 * fix: update default maxPieceLength to be 4 MiB, rather than Infinity.
1 parent f342a69 commit 1264106

3 files changed

Lines changed: 61 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Or, an **array of `string`, `File`, `Buffer`, or `stream.Readable` objects**.
6868
filterJunkFiles: Boolean, // remove hidden and other junk files? (default = true)
6969
private: Boolean, // is this a private .torrent? (default = false)
7070
pieceLength: Number, // force a custom piece length (number of bytes)
71+
maxPieceLength: Number, // force a maximum piece length for auto piece length selection, does not affect pieceLength option (default = 4 MiB)
7172
announceList: [[String]], // custom trackers (array of arrays of strings) (see [bep12](http://www.bittorrent.org/beps/bep_0012.html))
7273
urlList: [String], // web seed urls (see [bep19](http://www.bittorrent.org/beps/bep_0019.html))
7374
info: Object, // add non-standard info dict entries, e.g. info.source, a convention for cross-seeding

index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const announceList = [
3434
* @param {string=} opts.createdBy
3535
* @param {boolean|number=} opts.private
3636
* @param {number=} opts.pieceLength
37+
* @param {number=} opts.maxPieceLength
3738
* @param {Array.<Array.<string>>=} opts.announceList
3839
* @param {Array.<string>=} opts.urlList
3940
* @param {Object=} opts.info
@@ -151,6 +152,10 @@ function _parseInput (input, opts, cb) {
151152
opts.name = `Unnamed Torrent ${Date.now()}`
152153
}
153154

155+
if (!opts.maxPieceLength) {
156+
opts.maxPieceLength = 4 * 1024 * 1024
157+
}
158+
154159
const numPaths = input.reduce((sum, item) => sum + Number(typeof item === 'string'), 0)
155160

156161
let isSingleFileTorrent = (input.length === 1)
@@ -300,7 +305,7 @@ function onFiles (files, opts, cb) {
300305
if (opts.urlList !== undefined) torrent['url-list'] = opts.urlList
301306

302307
const estimatedTorrentLength = files.reduce(sumLength, 0)
303-
const pieceLength = opts.pieceLength || calcPieceLength(estimatedTorrentLength)
308+
const pieceLength = opts.pieceLength || Math.min(calcPieceLength(estimatedTorrentLength), opts.maxPieceLength)
304309
torrent.info['piece length'] = pieceLength
305310

306311
getPieceList(

test/basic.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,57 @@ test('implicit torrent name from file names with slashes in them', t => {
205205
t.equal(parsedTorrent.files[1].path, path.join('My Cool Folder', 'My Cool File 2'))
206206
})
207207
})
208+
209+
test('verify torrent length with maxPieceLength set', t => {
210+
t.plan(8)
211+
212+
const buf1 = Buffer.from('buf1')
213+
buf1.name = 'My Cool Folder/My Cool File 1'
214+
215+
const buf2 = Buffer.from('buf2')
216+
buf2.name = 'My Cool Folder/My Cool File 2'
217+
218+
createTorrent([buf1, buf2], { maxPieceLength: 10 }, async (err, torrent) => {
219+
t.error(err)
220+
const parsedTorrent = await parseTorrent(torrent)
221+
222+
t.equal(parsedTorrent.name, 'My Cool Folder')
223+
224+
t.equal(parsedTorrent.files.length, 2)
225+
226+
t.equal(parsedTorrent.files[0].name, 'My Cool File 1')
227+
t.equal(parsedTorrent.files[0].path, path.join('My Cool Folder', 'My Cool File 1'))
228+
229+
t.equal(parsedTorrent.files[1].name, 'My Cool File 2')
230+
t.equal(parsedTorrent.files[1].path, path.join('My Cool Folder', 'My Cool File 2'))
231+
232+
t.equal(parsedTorrent.pieceLength, 10)
233+
})
234+
})
235+
236+
test('verify maxPieceLength is ignored when pieceLength is manually set', t => {
237+
t.plan(8)
238+
239+
const buf1 = Buffer.from('buf1')
240+
buf1.name = 'My Cool Folder/My Cool File 1'
241+
242+
const buf2 = Buffer.from('buf2')
243+
buf2.name = 'My Cool Folder/My Cool File 2'
244+
245+
createTorrent([buf1, buf2], { pieceLength: 1024, maxPieceLength: 10 }, async (err, torrent) => {
246+
t.error(err)
247+
const parsedTorrent = await parseTorrent(torrent)
248+
249+
t.equal(parsedTorrent.name, 'My Cool Folder')
250+
251+
t.equal(parsedTorrent.files.length, 2)
252+
253+
t.equal(parsedTorrent.files[0].name, 'My Cool File 1')
254+
t.equal(parsedTorrent.files[0].path, path.join('My Cool Folder', 'My Cool File 1'))
255+
256+
t.equal(parsedTorrent.files[1].name, 'My Cool File 2')
257+
t.equal(parsedTorrent.files[1].path, path.join('My Cool Folder', 'My Cool File 2'))
258+
259+
t.equal(parsedTorrent.pieceLength, 1024)
260+
})
261+
})

0 commit comments

Comments
 (0)