setMetadata handles info dict or full torrent dict

This commit is contained in:
Feross Aboukhadijeh 2014-06-03 23:11:04 -07:00
parent e2b3a25670
commit 7b4a888157
1 changed files with 27 additions and 25 deletions

View File

@ -31,16 +31,7 @@ module.exports = function (metadata) {
this._bitfield = new BitField(0, { grow: BITFIELD_GROW }) this._bitfield = new BitField(0, { grow: BITFIELD_GROW })
if (Buffer.isBuffer(metadata)) { if (Buffer.isBuffer(metadata)) {
var info = null this.setMetadata(metadata)
try {
// if buffer fails to decode or there is no info key, then metadata is corrupt
info = bncode.encode(bncode.decode(metadata).info)
} catch (err) {
throw new Error('`ut_metadata` constructed with corrupt/invalid metadata')
}
if (info)
this.setMetadata(info)
} }
} }
@ -118,14 +109,32 @@ module.exports = function (metadata) {
this._fetching = false this._fetching = false
} }
ut_metadata.prototype.setMetadata = function (_metadata) { ut_metadata.prototype.setMetadata = function (metadata) {
if (this._metadataComplete) return if (this._metadataComplete) return true
this._metadataComplete = true
this.metadata = _metadata // if full torrent dictionary was passed in, pull out just `info` key
this._metadataSize = this.metadata.length try {
var info = bncode.decode(metadata).info
if (info) {
metadata = bncode.encode(info)
}
} catch (err) {}
// check hash
if (this._infoHash && this._infoHash.toString('hex') !== sha1(metadata)) {
return false
}
this.cancel() this.cancel()
this.metadata = metadata
this._metadataComplete = true
this._metadataSize = this.metadata.length
this._wire.extendedHandshake.metadata_size = this._metadataSize this._wire.extendedHandshake.metadata_size = this._metadataSize
this.emit('metadata', bncode.encode({ info: bncode.decode(this.metadata) })) this.emit('metadata', bncode.encode({ info: bncode.decode(this.metadata) }))
return true
} }
ut_metadata.prototype._send = function (dict, trailer) { ut_metadata.prototype._send = function (dict, trailer) {
@ -203,17 +212,10 @@ module.exports = function (metadata) {
} }
if (!done) return if (!done) return
try { // attempt to set metadata -- may fail sha1 check
// if buffer fails to decode, then data was corrupt var success = this.setMetadata(this.metadata)
bncode.decode(this.metadata)
} catch (err) {
return this._failedMetadata()
}
// check hash if (!success) {
if (sha1(this.metadata) === this._infoHash.toString('hex')) {
this.setMetadata(this.metadata)
} else {
this._failedMetadata() this._failedMetadata()
} }
} }