diff options
author | Feross Aboukhadijeh <feross@feross.org> | 2014-11-06 08:14:19 +0300 |
---|---|---|
committer | Feross Aboukhadijeh <feross@feross.org> | 2014-11-06 08:14:19 +0300 |
commit | 93c684fec3a83d784fb236a66129aab83d1ce33c (patch) | |
tree | 1cc88dc730539d57870cb09f841f10d27d4dda5d /lib/torrent.js | |
parent | ccd8efc5c39a28b721f1048e8c118512c5768739 (diff) |
Support http torrent urls with redirects
Fixes #176
Diffstat (limited to 'lib/torrent.js')
-rw-r--r-- | lib/torrent.js | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/lib/torrent.js b/lib/torrent.js index 7659314..28d3603 100644 --- a/lib/torrent.js +++ b/lib/torrent.js @@ -8,6 +8,7 @@ var EventEmitter = require('events').EventEmitter var fs = require('fs') // browser exclude var hh = require('http-https') // browser exclude var inherits = require('inherits') +var once = require('once') var parallel = require('run-parallel') var parseTorrent = require('parse-torrent') var RarityMap = require('./rarity-map') @@ -15,6 +16,7 @@ var reemit = require('re-emitter') var Server = require('./server') // browser exclude var Storage = require('./storage') var Swarm = require('bittorrent-swarm') // `webtorrent-swarm` in browser +var url = require('url') var ut_metadata = require('ut_metadata') var ut_pex = require('ut_pex') // browser exclude @@ -75,12 +77,10 @@ function Torrent (torrentId, opts) { } else if (typeof hh.get === 'function' && /^https?:/.test(torrentId)) { // http or https url to torrent file - hh.get(torrentId, function (res) { - res.pipe(concat(function (torrent) { - onTorrentId(torrent) - })) - }).on('error', function (err) { - self.emit('error', new Error('error downloading torrent: ' + err.message)) + httpGet(torrentId, function (err, torrent) { + if (err) + return self.emit('error', new Error('error downloading torrent: ' + err.message)) + onTorrentId(torrent) }) } else if (typeof fs.readFile === 'function') { @@ -997,3 +997,33 @@ function randomizedForEach (array, cb) { cb(array[index], index, array) }) } + +/** + * Make http or https request, following redirects. + * @param {string} u + * @param {function} + * @param {number=} maxRedirects + * @return {http.ClientRequest} + */ +function httpGet (u, cb, maxRedirects) { + cb = once(cb) + if (!maxRedirects) maxRedirects = 5 + if (maxRedirects === 0) return cb(new Error('too many redirects')) + + hh.get(u, function (res) { + // Check for redirect + if (res.statusCode >= 300 && res.statusCode < 400 && 'location' in res.headers) { + var location = res.headers.location + if (!url.parse(location).host) { + // If relative redirect, prepend host of current url + var parsed = url.parse(u) + location = parsed.protocol + '//' + parsed.host + location + } + res.resume() // discard response + return httpGet(location, cb, --maxRedirects) + } + res.pipe(concat(function (data) { + cb(null, data) + })) + }).on('error', cb) +} |