Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for PR #799 #809

Merged
merged 3 commits into from May 19, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

Fixes for PR #799

- Support multiple &xs= params in parallel
- Fail on 'error' 'warning' events
  • Loading branch information
feross committed May 19, 2016
commit e8dea8e588045b43c7a5d4931cde692fd135a21d
@@ -114,7 +114,7 @@ function Torrent (torrentId, client, opts) {

// for cleanup
this._servers = []
this._xsRequest = null
this._xsRequests = []

// TODO: remove this and expose a hook instead
// optimization: don't recheck every file if it hasn't changed
@@ -271,38 +271,6 @@ Torrent.prototype._onParsedTorrent = function (parsedTorrent) {
self._onListening()
})
}

if (parsedTorrent.xs && !self.info) {
// TODO: Could try multiple in parallel here
var src = parsedTorrent.xs instanceof Array ? parsedTorrent.xs[0] : parsedTorrent.xs
var isHTTP = src.substring(0, 7) === 'http://' || src.substring(0, 8) === 'https://'

if (isHTTP) {
var opts = {
url: src,
method: 'GET',
headers: {
'user-agent': 'WebTorrent (http://webtorrent.io)'
}
}
this._xsRequest = get.concat(opts, function (err, res, torrent) {
if (err || res.statusCode !== 200 || !torrent.length) return

var parsedTorrent
try {
parsedTorrent = parseTorrent(torrent)
} catch (err) {}

if (parsedTorrent) {
if (parsedTorrent.infoHash !== self.infoHash) {
return
}

self._onMetadata(parsedTorrent)
}
})
}
}
}

Torrent.prototype._processParsedTorrent = function (parsedTorrent) {
@@ -395,23 +363,96 @@ Torrent.prototype._onListening = function () {
self.emit('warning', err)
}

// if full metadata was included in initial torrent id, use it immediately. Otherwise,
// wait for torrent-discovery to find peers and ut_metadata to get the metadata.
if (self.info) self._onMetadata(self)
if (self.info) {
// if full metadata was included in initial torrent id, use it immediately. Otherwise,
// wait for torrent-discovery to find peers and ut_metadata to get the metadata.
self._onMetadata(self)
} else if (self.xs) {
self._getMetadataFromServer()

This comment has been minimized.

Copy link
@feross

feross May 19, 2016

Author Member

Moved to after listening event since it's really fast and it's when the other discovery happens. This may prevent future bugs where we expect to already be listening.

}
}

Torrent.prototype._getMetadataFromServer = function () {
var self = this
var urls = Array.isArray(self.xs) ? self.xs : [ self.xs ]

var tasks = urls.map(function (url) {
return function (cb) {
getMetadataFromURL(url, cb)
}
})
parallel(tasks)

function getMetadataFromURL (url, cb) {
if (url.indexOf('http://') !== 0 && url.indexOf('https://') !== 0) {
self._debug('skipping non-http xs param: %s', url)
return cb(null)
}

var opts = {
url: url,
method: 'GET',
headers: {
'user-agent': 'WebTorrent (https://webtorrent.io)'
}
}
var req
try {
req = get.concat(opts, onResponse)
} catch (err) {
self._debug('skipping invalid url xs param: %s', url)
return cb(null)
}

self._xsRequests.push(req)

function onResponse (err, res, torrent) {
if (self.destroyed) return cb(null)
if (self.metadata) return cb(null)

if (err) {
self._debug('http error from xs param: %s', url)
return cb(null)
}
if (res.statusCode !== 200) {
self._debug('non-200 status code from xs param: %s', url)

This comment has been minimized.

Copy link
@Sebmaster

Sebmaster May 19, 2016

Contributor

Print the specific status code here?

This comment has been minimized.

Copy link
@feross

feross May 19, 2016

Author Member

Good idea!

return cb(null)
}

var parsedTorrent
try {
parsedTorrent = parseTorrent(torrent)
} catch (err) {}

if (!parsedTorrent) {
self._debug('got invalid torrent file from xs param: %s', url)
return cb(null)
}

if (parsedTorrent.infoHash !== self.infoHash) {
self._debug('got torrent file with incorrect info hash from xs param: %s', url)
return cb(null)
}

self._onMetadata(parsedTorrent)
cb(null)
}
}
}

/**
* Called when the full torrent metadata is received.
*/
Torrent.prototype._onMetadata = function (metadata) {
var self = this
if (self._xsRequest) {
self._xsRequest.abort()
self._xsRequest = null
}
if (self.metadata || self.destroyed) return
self._debug('got metadata')

self._xsRequests.forEach(function (req) {
req.abort()
})
self._xsRequests = []

var parsedTorrent
if (metadata && metadata.infoHash) {
// `metadata` is a parsed torrent (from parse-torrent module)
@@ -591,13 +632,14 @@ Torrent.prototype._destroy = function (err, cb) {
self.destroyed = true
self._debug('destroy')

if (self._xsRequest) {
self._xsRequest.abort()
}
self.client._remove(self)

clearInterval(self._rechokeIntervalId)

self._xsRequests.forEach(function (req) {
req.abort()
})

if (self._rarityMap) {
self._rarityMap.destroy()
}
@@ -653,7 +695,7 @@ Torrent.prototype._destroy = function (err, cb) {
self._rarityMap = null
self._peers = null
self._servers = null
self._xsRequest = null
self._xsRequests = null
}

Torrent.prototype.addPeer = function (peer) {
@@ -25,9 +25,12 @@ test('Download metadata for magnet URI with xs parameter', function (t) {

var client = new WebTorrent({ dht: false, tracker: false })

client.on('error', function (err) { t.fail(err) })
client.on('warning', function (err) { t.fail(err) })

createServer(fixtures.leaves.torrent, function (url, next) {
client.add(fixtures.leaves.magnetURI + '&xs=' + encodeURIComponent(url), function (torrent) {
t.equal(torrent.name, 'Leaves of Grass by Walt Whitman.epub')
t.equal(torrent.files[0].name, 'Leaves of Grass by Walt Whitman.epub')

client.destroy(function (err) { t.error(err, 'client destroyed') })
next()
@@ -40,12 +43,15 @@ test('Download metadata for magnet URI with xs parameter', function (t) {

var client = new WebTorrent({ dht: false, tracker: false })

client.on('error', function (err) { t.fail(err) })
client.on('warning', function (err) { t.fail(err) })

createServer(fixtures.leaves.torrent, function (url, next) {
var encoded = encodeURIComponent(url)
var uri = fixtures.leaves.magnetURI + '&xs=' + encoded + '&xs=' + encoded + '2'

client.add(uri, function (torrent) {
t.equal(torrent.name, 'Leaves of Grass by Walt Whitman.epub')
t.equal(torrent.files[0].name, 'Leaves of Grass by Walt Whitman.epub')

client.destroy(function (err) { t.error(err, 'client destroyed') })
next()
@@ -54,12 +60,17 @@ test('Download metadata for magnet URI with xs parameter', function (t) {
})

test('Download metadata magnet URI with unsupported protocol in xs parameter', function (t) {
t.plan(2)
t.plan(1)

var client = new WebTorrent({ dht: false, tracker: false })

client.on('error', function (err) { t.fail(err) })
client.on('warning', function (err) { t.fail(err) })

client.add(fixtures.leaves.magnetURI + '&xs=' + encodeURIComponent('invalidurl:example'))

setTimeout(function () {
t.ok(true, 'no crash')
// no crash by now
client.destroy(function (err) { t.error(err, 'client destroyed') })
}, 100)
})
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.