Permalink
Browse files

clean up metadata fetching code (BEP 9) (#27)

  • Loading branch information...
1 parent df7be73 commit 70d6a18c0b078e39fd59e5bfc9e53307097c0d96 @feross feross committed Feb 24, 2014
Showing with 89 additions and 73 deletions.
  1. +87 −71 lib/torrent.js
  2. +2 −2 package.json
View
@@ -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
+ }
}
//
View
@@ -28,8 +28,6 @@
"bittorrent-swarm": "0.x",
"bncode": "^0.5.2",
"brfs": "^0.2.1",
- "browserify": "3.x",
- "browserify-shim": "^3.2.2",
"chrome-portfinder": "^0.2.4",
"font-awesome": "git://github.com/FortAwesome/Font-Awesome",
"hat": "0.0.3",
@@ -42,6 +40,8 @@
"speedometer": "^0.1.2"
},
"devDependencies": {
+ "browserify": "3.x",
+ "browserify-shim": "^3.2.2",
"nib": "^1.0.2",
"nodemon": "^1.0.15",
"stylus": "^0.42.2",

0 comments on commit 70d6a18

Please sign in to comment.