From 96c754ddeb614b45a565e8307c9985ee85bcb7fa Mon Sep 17 00:00:00 2001 From: Jesse Chan Date: Mon, 19 Oct 2020 20:52:20 +0800 Subject: [PATCH] server: rTorrent: save torrents and then add them with paths Bug: #164, #741, #773 --- fixtures/multi.torrent | Bin 0 -> 1635 bytes fixtures/single.torrent | Bin 0 -> 75960 bytes server/.jest/auth.setup.js | 6 +- server/.jest/test.setup.js | 2 + server/routes/api/torrents.test.ts | 78 +++++++++++++++++- .../services/rTorrent/clientGatewayService.ts | 52 +++++------- 6 files changed, 100 insertions(+), 38 deletions(-) create mode 100644 fixtures/multi.torrent create mode 100644 fixtures/single.torrent diff --git a/fixtures/multi.torrent b/fixtures/multi.torrent new file mode 100644 index 0000000000000000000000000000000000000000..a04a4533e77ab1e506c687bf4d1ea71e466fb39b GIT binary patch literal 1635 zcma)7yN=~V5JiNWlXo^C!M*OM-A#mqKr0~vG(-fWa(DH(nYMk`?mM$L1HyS;>Q zxn_Kk(_C`?pNaS^P<;3W#M=3>?{O%GD|g+cnfY-jv}fHo7YqyvD;=`ebT|!I*jFdC z%lX1#CK68wYy%cZdEQ=+(?nISC-8STz4|6)oLLVC*1JsfhlLMY@E6?RNnd?B{YH z#Cop(9@zJ`Hy3*6YOlT@3pzGonG)VZX8U;$nSf3BW}haa3C!oTNLV^jY2NR4<3!{h zu$>W)Y(D)K%MaL zA&!A_a&68;n}X&njH7R7b@_9gsNIo&4w~wEDH>;L3#O5^aT$kOf@uXeC|w`46b?0d zX{7O{ij{AyZL3y9(L~$U&@@WBzN8+B1=qT%xzR=`w}a9xK%PH-5@~*uQ$Yehcfb|p zMJ2EmT!au1R2w5k6{W1(wlSL9$VH4z74Z==ZySuJZdb^Su2;mhP`*}`4blqJMz5@!h+xe_M!-9x{@B2JK2J`DN+G?WcSijp literal 0 HcmV?d00001 diff --git a/fixtures/single.torrent b/fixtures/single.torrent new file mode 100644 index 0000000000000000000000000000000000000000..a25d2fb108250736ab1d9eeb726cc05184e50967 GIT binary patch literal 75960 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 fs.rmdirSync(temporaryRuntimeDirectory, {recursive: true})); +afterAll(() => { + // TODO: This leads test flakiness caused by ENOENT error + // NeDB provides no method to close database connection + fs.rmdirSync(temporaryRuntimeDirectory, {recursive: true}); +}); diff --git a/server/.jest/test.setup.js b/server/.jest/test.setup.js index 997da3b3..5470b7fd 100644 --- a/server/.jest/test.setup.js +++ b/server/.jest/test.setup.js @@ -37,6 +37,8 @@ process.argv.push('--rtsocket', rTorrentSocket); afterAll((done) => { rTorrentProcess.on('close', () => { + // TODO: This leads test flakiness caused by ENOENT error + // NeDB provides no method to close database connection fs.rmdirSync(temporaryRuntimeDirectory, {recursive: true}); done(); }); diff --git a/server/routes/api/torrents.test.ts b/server/routes/api/torrents.test.ts index 3aa6f8ea..552b07ab 100644 --- a/server/routes/api/torrents.test.ts +++ b/server/routes/api/torrents.test.ts @@ -1,5 +1,6 @@ import crypto from 'crypto'; import fs from 'fs'; +import path from 'path'; import readline from 'readline'; import stream from 'stream'; import supertest from 'supertest'; @@ -7,8 +8,13 @@ import supertest from 'supertest'; import app from '../../app'; import {getAuthToken} from './auth'; import {getTempPath} from '../../models/TemporaryStorage'; +import paths from '../../../shared/config/paths'; -import type {AddTorrentByURLOptions, SetTorrentsTrackersOptions} from '../../../shared/types/api/torrents'; +import type { + AddTorrentByFileOptions, + AddTorrentByURLOptions, + SetTorrentsTrackersOptions, +} from '../../../shared/types/api/torrents'; import type {TorrentContent} from '../../../shared/types/TorrentContent'; import type {TorrentList, TorrentProperties} from '../../../shared/types/Torrent'; import type {TorrentStatus} from '../../../shared/constants/torrentStatusMap'; @@ -24,6 +30,13 @@ fs.mkdirSync(tempDirectory, {recursive: true}); jest.setTimeout(20000); +const torrentFiles = [ + path.join(paths.appSrc, 'fixtures/single.torrent'), + path.join(paths.appSrc, 'fixtures/multi.torrent'), +].map((torrentPath) => Buffer.from(fs.readFileSync(torrentPath)).toString('base64')); + +const torrentURLs = ['https://releases.ubuntu.com/20.04/ubuntu-20.04.1-live-server-amd64.iso.torrent']; + let torrentHash = ''; const activityStream = new stream.PassThrough(); @@ -32,7 +45,7 @@ request.get('/api/activity-stream').send().set('Cookie', [authToken]).pipe(activ describe('POST /api/torrents/add-urls', () => { const addTorrentByURLOptions: AddTorrentByURLOptions = { - urls: ['https://releases.ubuntu.com/20.04/ubuntu-20.04.1-live-server-amd64.iso.torrent'], + urls: torrentURLs, destination: tempDirectory, tags: ['test'], isBasePath: false, @@ -41,7 +54,7 @@ describe('POST /api/torrents/add-urls', () => { const torrentAdded = new Promise((resolve) => { rl.on('line', (input) => { - if (input.includes('TORRENT_LIST_DIFF_CHANGE')) { + if (input.includes('TORRENT_LIST_ACTION_TORRENT_ADDED')) { resolve(); } }); @@ -62,7 +75,7 @@ describe('POST /api/torrents/add-urls', () => { }); }); - it('GET /api/torrents', (done) => { + it('GET /api/torrents to verify torrents are added via URLs', (done) => { torrentAdded.then(() => { request .get('/api/torrents') @@ -95,6 +108,63 @@ describe('POST /api/torrents/add-urls', () => { }); }); +describe('POST /api/torrents/add-files', () => { + const addTorrentByFileOptions: AddTorrentByFileOptions = { + files: torrentFiles, + destination: tempDirectory, + tags: ['test'], + isBasePath: false, + start: false, + }; + + const torrentAdded = new Promise((resolve) => { + rl.on('line', (input) => { + if (input.includes('TORRENT_LIST_ACTION_TORRENT_ADDED')) { + resolve(); + } + }); + }); + + it('Adds a torrent from files', (done) => { + request + .post('/api/torrents/add-files') + .send(addTorrentByFileOptions) + .set('Cookie', [authToken]) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end((err, _res) => { + if (err) done(err); + + done(); + }); + }); + + it('GET /api/torrents to verify torrents are added via files', (done) => { + torrentAdded.then(() => { + request + .get('/api/torrents') + .send() + .set('Cookie', [authToken]) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end((err, res) => { + if (err) done(err); + + expect(res.body.torrents == null).toBe(false); + const torrentList: TorrentList = res.body.torrents; + + expect(Object.keys(torrentList).length).toBeGreaterThanOrEqual( + torrentFiles.length + (torrentHash !== '' ? 1 : 0), + ); + + done(); + }); + }); + }); +}); + describe('PATCH /api/torrents/trackers', () => { const testTrackers = [ `https://${crypto.randomBytes(8).toString('hex')}.com/announce`, diff --git a/server/services/rTorrent/clientGatewayService.ts b/server/services/rTorrent/clientGatewayService.ts index 5c0266d8..215736a4 100644 --- a/server/services/rTorrent/clientGatewayService.ts +++ b/server/services/rTorrent/clientGatewayService.ts @@ -1,7 +1,8 @@ -import path from 'path'; +import crypto from 'crypto'; import fs from 'fs'; import geoip from 'geoip-country'; import {moveSync} from 'fs-extra'; +import path from 'path'; import sanitize from 'sanitize-filename'; import type {ClientSettings} from '@shared/types/ClientSettings'; @@ -31,6 +32,7 @@ import ClientGatewayService from '../interfaces/clientGatewayService'; import ClientRequestManager from './clientRequestManager'; import scgiUtil from './util/scgiUtil'; import {getMethodCalls, processMethodCallResponse} from './util/rTorrentMethodCallUtil'; +import {getTempPath} from '../../models/TemporaryStorage'; import torrentFileUtil from '../../util/torrentFileUtil'; import { encodeTags, @@ -55,41 +57,25 @@ class RTorrentClientGatewayService extends ClientGatewayService { clientRequestManager = new ClientRequestManager(this.user.client as RTorrentConnectionSettings); async addTorrentsByFile({files, destination, tags, isBasePath, start}: AddTorrentByFileOptions): Promise { - const destinationPath = sanitizePath(destination); + const tempPath = path.join( + getTempPath(this.user._id), + 'torrents', + `${Date.now()}-${crypto.randomBytes(4).toString('hex')}`, + ); + await createDirectory(tempPath); - if (!isAllowedPath(destinationPath)) { - throw accessDeniedError(); - } - - await createDirectory(destinationPath); - - // Each torrent is sent individually because rTorrent might have small - // XMLRPC request size limit. This allows the user to send files reliably. - await Promise.all( - files.map(async (file) => { - const additionalCalls: Array = []; - - additionalCalls.push(`${isBasePath ? 'd.directory_base.set' : 'd.directory.set'}="${destinationPath}"`); - - if (Array.isArray(tags)) { - additionalCalls.push(`d.custom1.set=${encodeTags(tags)}`); - } - - additionalCalls.push(`d.custom.set=addtime,${Date.now() / 1000}`); - - return ( - this.clientRequestManager - .methodCall( - start ? 'load.raw_start' : 'load.raw', - ['', Buffer.from(file, 'base64')].concat(additionalCalls), - ) - .then(this.processClientRequestSuccess, this.processClientRequestError) - .then(() => { - // returns nothing. - }) || Promise.reject() - ); + const torrentPaths = await Promise.all( + files.map(async (file, index) => { + const torrentPath = path.join(tempPath, `${index}.torrent`); + fs.writeFileSync(torrentPath, Buffer.from(file, 'base64'), {}); + return torrentPath; }), ); + + // Delete temp files after 5 minutes. This is more than enough. + setTimeout(() => fs.rmdirSync(tempPath, {recursive: true}), 1000 * 60 * 5); + + return this.addTorrentsByURL({urls: torrentPaths, destination, tags, isBasePath, start}); } async addTorrentsByURL({urls, destination, tags, isBasePath, start}: AddTorrentByURLOptions): Promise {