Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/webtorrent/webtorrent.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeross Aboukhadijeh <feross@feross.org>2014-02-24 06:45:31 +0400
committerFeross Aboukhadijeh <feross@feross.org>2014-02-24 06:45:31 +0400
commit70d6a18c0b078e39fd59e5bfc9e53307097c0d96 (patch)
treeea7817359486f35a34a3bf66a30c2648e7e50021 /lib/torrent.js
parentdf7be73a9327ed8f6d62912269f00035c2931f61 (diff)
clean up metadata fetching code (BEP 9) (#27)
Diffstat (limited to 'lib/torrent.js')
-rw-r--r--lib/torrent.js158
1 files changed, 87 insertions, 71 deletions
diff --git a/lib/torrent.js b/lib/torrent.js
index 5a9c988..a5536ac 100644
--- a/lib/torrent.js
+++ b/lib/torrent.js
@@ -9,6 +9,10 @@ var Swarm = require('bittorrent-swarm')
var METADATA_BLOCK_SIZE = 16 * 1024
var WIRE_TIMEOUT = 10000
+var EXTENDED_MESSAGES = {
+ ut_metadata: 1
+}
+
inherits(Torrent, EventEmitter)
function Torrent (uri, opts) {
@@ -66,12 +70,14 @@ Torrent.prototype._onWire = function (wire) {
wire.setKeepAlive(true)
// If peer supports DHT, send PORT message to report DHT node listening port
- if (wire.peerExtensions.dht)
+ if (wire.peerExtensions.dht) {
+ console.log(wire.remoteAddress, 'supports DHT')
wire.port(self.dhtPort)
+ }
// When peer sends PORT, add them to the routing table
wire.on('port', function (port) {
- console.log('received PORT: ', port)
+ console.log(wire.remoteAddress, 'port', port)
// TODO: DHT doesn't have a routing table yet
// dht.add(wire.remoteAddress, port)
})
@@ -82,12 +88,10 @@ Torrent.prototype._onWire = function (wire) {
// Support extended messages:
// - ut_metadata (metadata fetching, trackerless torrents)
if (wire.peerExtensions.extended) {
- console.log(wire.remoteAddress + ' supports extended messages', wire.peerExtensions)
+ console.log(wire.remoteAddress, 'supports extended messages', wire.peerExtensions)
var extendedMessage = {
- m: {
- ut_metadata: 1
- }
+ m: EXTENDED_MESSAGES
}
// Only send metadata_size if we have complete metadata
@@ -98,76 +102,88 @@ Torrent.prototype._onWire = function (wire) {
}
wire.on('extended', function (ext, buf) {
- var dict
- console.log('Received extended message ' + ext + ' from ' + wire.remoteAddress)
-
- if (ext === 0) { // handshake
+ console.log(wire.remoteAddress, 'extended', ext)
- try {
- console.log('decoding ' + buf.toString())
- dict = bncode.decode(buf.toString())
- console.log('got extended handshake: ' + JSON.stringify(dict))
- } catch (e) {
- console.error('Error decoding extended message: ' + e.message)
- }
+ if (ext === 0) // 0 = handshake
+ self._onExtendedHandshake(wire, buf)
+ else if (ext === EXTENDED_MESSAGES.ut_metadata)
+ self._onUtMetadata(wire, buf)
+ })
+}
- if (dict.m.ut_metadata && dict.metadata_size) {
- var metadataSize = dict.metadata_size
- var numPieces = Math.ceil(metadataSize / METADATA_BLOCK_SIZE)
- console.log('metadata size: ' + metadataSize)
- console.log(numPieces + ' pieces')
-
- wire.metadata = new Buffer(metadataSize)
-
- // request all pieces
- for (var piece = 0; piece < numPieces; piece++) {
- wire.extended(dict.m.ut_metadata, {
- msg_type: 0,
- piece: piece
- })
- }
- }
+Torrent.prototype._onExtendedHandshake = function (wire, buf) {
+ var self = this
+ var dict
+ try {
+ dict = bncode.decode(buf.toString())
+ console.log(wire.remoteAddress, 'extended handshake' + JSON.stringify(dict))
+ } catch (e) {
+ console.error(wire.remoteAddress, 'extended handshake error', e.message)
+ return
+ }
+ if (!dict) return
+
+ // If torrent is missing metadata and peer supports ut_metadata extension,
+ // then request all metadata pieces
+ if (!self.metadata && dict.metadata_size && dict.m && dict.m.ut_metadata) {
+ var numPieces = Math.ceil(dict.metadata_size / METADATA_BLOCK_SIZE)
+ wire.metadata = new Buffer(dict.metadata_size)
+
+ console.log('metadata size: ' + dict.metadata_size)
+ console.log(numPieces + ' pieces')
+
+ // request all pieces
+ for (var piece = 0; piece < numPieces; piece++) {
+ wire.extended(dict.m.ut_metadata, {
+ msg_type: 0,
+ piece: piece
+ })
+ }
+ }
+}
- } else if (ext === 1) { // ut_metadata
-
- // 0 - request
- // 1 - data
- // 2 - reject
-
- var str
- var dataIndex
- var data
- try {
- str = buf.toString()
- console.log('decoding ' + str)
- dataIndex = str.indexOf('ee') + 2
- var msg = str.substring(0, dataIndex)
- console.log('using ' + msg)
- dict = bncode.decode(msg)
- data = buf.slice(dataIndex)
- console.log('got metadata: ' + JSON.stringify(dict))
- console.log('got metadata data: ' + data.length + ' bytes')
- } catch (e) {
- console.error('Error decoding extended message: ' + e.message)
- }
+// 0 - request
+// 1 - data
+// 2 - reject
+Torrent.prototype._onUtMetadata = function (wire, buf) {
+ var self = this
- // {'msg_type': 1, 'piece': 0, 'total_size': 3425}
- if (dict.msg_type === 1) { // data
- console.log('total_size: ' + dict.total_size)
- data.copy(wire.metadata, dict.piece * METADATA_BLOCK_SIZE)
-
- console.log('METADATA')
- console.log(wire.metadata.toString())
- self.metadata = {
- 'announce-list': [],
- info: bncode.decode(wire.metadata),
- // info_hash:
- }
- console.log(self.metadata)
- self.emit('metadata', this.metadata)
+ var dict
+ var data
+ try {
+ var str = buf.toString()
+ var dataIndex = str.indexOf('ee') + 2
+ dict = bncode.decode(str.substring(0, dataIndex))
+ data = buf.slice(dataIndex)
+ console.log(wire.remoteAddress, 'ut_metadata', JSON.stringify(dict), 'metadata byte length', data.length)
+ } catch (e) {
+ console.error('Error decoding extended message: ' + e.message)
+ }
+ if (!dict) return
+
+ switch (dict.msg_type) {
+ // ut_metadata request (from peer)
+ // example: {'msg_type': 0, 'piece': 0}
+ case 0:
+ // TODO
+ break
+ // ut_metadata data (in response to our request)
+ // example: {'msg_type': 1, 'piece': 0, 'total_size': 3425}
+ case 1:
+ data.copy(wire.metadata, dict.piece * METADATA_BLOCK_SIZE)
+
+ self.metadata = {
+ 'announce-list': [],
+ info: bncode.decode(wire.metadata)
}
- }
- })
+ self.emit('metadata', this.metadata)
+ break
+ // ut_metadata reject (peer doesn't have piece we requested)
+ // {'msg_type': 2, 'piece': 0}
+ case 2:
+ // TODO
+ break
+ }
}
//