code style

This commit is contained in:
Feross Aboukhadijeh 2014-03-27 19:49:51 -07:00
parent 0557ce6f65
commit 5c09dcd55f

236
index.js
View File

@ -13,10 +13,14 @@ var string2compact = require('string2compact')
var dgram = require('dgram') var dgram = require('dgram')
var parseUrl = require('url').parse var parseUrl = require('url').parse
var CONNECTION_ID = Buffer.concat([fromInt32(0x417), fromInt32(0x27101980)]); var CONNECTION_ID = Buffer.concat([toUInt32(0x417), toUInt32(0x27101980)])
var CONNECT = fromInt32(0); var CONNECT = toUInt32(0)
var ANNOUNCE = fromInt32(1); var ANNOUNCE = toUInt32(1)
var EVENTS = {completed:1, started:2, stopped:3}; var EVENTS = {
completed: 1,
started: 2,
stopped: 3
}
inherits(Client, EventEmitter) inherits(Client, EventEmitter)
@ -84,77 +88,6 @@ Client.prototype.setInterval = function (intervalMs) {
} }
} }
Client.prototype._requestUdp = function(url, opts) {
var parsed = parseUrl(url)
var socket = dgram.createSocket('udp4')
var self = this
var timeout = setTimeout(function() {
socket.close()
}, 5000)
socket.on('error', function(err) {
self.emit('error', err)
})
socket.on('message', function(message, rinfo) {
var action = message.readUInt32BE(0)
switch (action) {
case 0:
if (message.length < 16) return self.emit('error', new Error('invalid udp handshake'))
announce(message.slice(8, 16), opts)
return;
case 1:
if (message.length < 20) return self.emit('error', new Error('invalid announce message'))
self.emit('update', {
announce: url,
complete: message.readUInt32BE(16),
incomplete: message.readUInt32BE(12)
})
for (var i = 20; i < message.length; i += 6) {
self.emit('peer', compact2string(message.slice(i, i+6)))
}
clearTimeout(timeout)
socket.close()
}
});
function announce(connectionId, opts) {
opts = opts || {}
send(Buffer.concat([
connectionId,
ANNOUNCE,
new Buffer(hat(32), 'hex'),
new Buffer(self._infoHash, 'hex'),
new Buffer(self._peerId, 'utf-8'),
fromInt32(0), fromInt32(opts.downloaded || 0), // fromUint32(0) to expand this to 64bit
fromInt32(0), fromInt32(opts.left || 0),
fromInt32(0), fromInt32(opts.uploaded || 0),
fromInt32(EVENTS[opts.event] || 0),
fromInt32(0),
fromInt32(0),
fromInt32(self._numWant),
fromInt16(self._port || 0)
]));
};
function send(message) {
socket.send(message, 0, message.length, parsed.port, parsed.hostname)
};
send(Buffer.concat([
CONNECTION_ID,
CONNECT,
new Buffer(hat(32), 'hex')
]));
};
/** /**
* Send a request to the tracker * Send a request to the tracker
*/ */
@ -175,34 +108,115 @@ Client.prototype._request = function (opts) {
opts.trackerid = self._trackerId opts.trackerid = self._trackerId
} }
var q = querystring.stringify(opts) self._announce.forEach(function (announceUrl) {
if (announceUrl.indexOf('udp:') === 0) {
self._announce.forEach(function (announce) { self._requestUdp(announceUrl, opts)
if (announce.indexOf('udp:') === 0) return self._requestUdp(announce, opts) } else {
self._requestHttp(announceUrl, opts)
var url = announce + '?' + q }
var req = http.get(url, function (res) {
var data = ''
if (res.statusCode !== 200) {
res.resume() // consume the whole stream
self.emit('error', new Error('Invalid response code ' + res.statusCode + ' from tracker'))
return
}
res.on('data', function (chunk) {
data += chunk
})
res.on('end', function () {
self._handleResponse(data, announce)
})
})
req.on('error', function (err) {
self.emit('error', err)
})
}) })
} }
Client.prototype._handleResponse = function (data, announce) { Client.prototype._requestHttp = function (announceUrl, opts) {
var self = this
var url = announceUrl + '?' + querystring.stringify(opts)
var req = http.get(url, function (res) {
var data = ''
if (res.statusCode !== 200) {
res.resume() // consume the whole stream
self.emit('error', new Error('Invalid response code ' + res.statusCode + ' from tracker'))
return
}
res.on('data', function (chunk) {
data += chunk
})
res.on('end', function () {
self._handleResponse(data, announceUrl)
})
})
req.on('error', function (err) {
self.emit('error', err)
})
}
Client.prototype._requestUdp = function (announceUrl, opts) {
var parsed = parseUrl(announceUrl)
var socket = dgram.createSocket('udp4')
var self = this
var timeout = setTimeout(function() {
socket.close()
}, 5000)
socket.on('error', function(err) {
self.emit('error', err)
})
socket.on('message', function(message, rinfo) {
var action = message.readUInt32BE(0)
switch (action) {
case 0:
if (message.length < 16) {
return self.emit('error', new Error('invalid udp handshake'))
}
announce(message.slice(8, 16), opts)
return
case 1:
if (message.length < 20) {
return self.emit('error', new Error('invalid announce message'))
}
self.emit('update', {
announce: announceUrl,
complete: message.readUInt32BE(16),
incomplete: message.readUInt32BE(12)
})
for (var i = 20; i < message.length; i += 6) {
self.emit('peer', compact2string(message.slice(i, i+6)))
}
clearTimeout(timeout)
socket.close()
}
})
function announce (connectionId, opts) {
opts = opts || {}
send(Buffer.concat([
connectionId,
ANNOUNCE,
new Buffer(hat(32), 'hex'),
new Buffer(self._infoHash, 'hex'),
new Buffer(self._peerId, 'utf-8'),
toUInt32(0), toUInt32(opts.downloaded || 0), // fromUint32(0) to expand this to 64bit
toUInt32(0), toUInt32(opts.left || 0),
toUInt32(0), toUInt32(opts.uploaded || 0),
toUInt32(EVENTS[opts.event] || 0),
toUInt32(0),
toUInt32(0),
toUInt32(self._numWant),
toUInt16(self._port || 0)
]))
}
function send (message) {
socket.send(message, 0, message.length, parsed.port, parsed.hostname)
}
send(Buffer.concat([
CONNECTION_ID,
CONNECT,
new Buffer(hat(32), 'hex')
]))
}
Client.prototype._handleResponse = function (data, announceUrl) {
var self = this var self = this
try { try {
@ -234,7 +248,7 @@ Client.prototype._handleResponse = function (data, announce) {
} }
self.emit('update', { self.emit('update', {
announce: announce, announce: announceUrl,
complete: data.complete, complete: data.complete,
incomplete: data.incomplete incomplete: data.incomplete
}) })
@ -436,17 +450,17 @@ Server.prototype._getPeersCompact = function (swarm) {
// HELPERS // HELPERS
// //
function fromInt16(n) { function toUInt16 (n) {
var buf = new Buffer(2); var buf = new Buffer(2)
buf.writeUInt16BE(n, 0); buf.writeUInt16BE(n, 0)
return buf; return buf
}; }
function fromInt32(n) { function toUInt32 (n) {
var buf = new Buffer(4); var buf = new Buffer(4)
buf.writeUInt32BE(n, 0); buf.writeUInt32BE(n, 0)
return buf; return buf
}; }
function bytewiseEncodeURIComponent (buf) { function bytewiseEncodeURIComponent (buf) {
if (!Buffer.isBuffer(buf)) { if (!Buffer.isBuffer(buf)) {