Permalink
Browse files

parsing tracker response

  • Loading branch information...
1 parent 84825ae commit dd830ab7ae08d89bc88a99fd438f3ee20e6962c1 @usoban committed Sep 4, 2011
Showing with 86 additions and 5 deletions.
  1. +11 −2 jstorrent.js
  2. +75 −3 lib/tracker.js
View
@@ -10,8 +10,17 @@ torrentServer.start(6621);
// Create client and announce
-var c = new torrentClient('./torrents/test1.torrent');
+var c = new torrentClient('./torrents/test2.torrent');
c.on('ready', function(){
c.announceAll('started');
-});
+});
+
+process.on('exit', function(){
+ c.announceAll('stopped');
+});
+
+/*
+process.on('uncaughtException', function(){
+ c.announceAll('stopped');
+});*/
View
@@ -5,7 +5,10 @@ var events = require('events'),
url = require('url'),
util = require('util'),
encoder = require('./util.js').urlEncodeBuffer,
- qs = require('querystring');
+ qs = require('querystring'),
+ hexy = require('hexy'),
+ Buffers = require('buffers'),
+ Peer = require('./peer.js');
module.exports = Tracker;
@@ -28,6 +31,18 @@ function Tracker(params){
this.trackerInfo = url.parse(this.url);
+ // Tracker response (defaults)
+ this.response = {
+ 'failure reason' : null,
+ 'warning message' : null,
+ interval : 2700,
+ 'min interval' : 2700,
+ 'tracker id' : null,
+ complete : 0,
+ incomplete : 0,
+ peers : []
+ };
+
// Has event 'started' been announced
this.announcedStart = false;
@@ -84,11 +99,27 @@ Tracker.prototype.announce = function(event){
* Receives response from the tracker
*/
function receive(res){
+ /*if(res.headers['content-type'] != 'text/plain'){
+ console.log('Tracker didn\' respond with text/plain');
+ return;
+ }*/
console.log('Tracker responded: ' + util.inspect(res.headers));
+
+ var buffs = Buffers(),
+ buffer,
+ response;
/* !! */
res.on('data', function(chunk){
- console.log(chunk.toString('utf8'));
+ buffs.push(chunk);
+ });
+
+ res.on('end', function(){
+ buffer = new Buffer(buffs.length);
+ buffs.copy(buffer, 0, 0, buffs.length);
+
+ self._parseResponse(buffer);
+ //Tracker.prototype._parseResponse.call(self, buffer);
});
/* !! */
@@ -102,6 +133,7 @@ Tracker.prototype.announce = function(event){
function dummyEncoder(x){ return x; }
+ /* Preparing parameters for announcement */
var params = {
info_hash : encoder(this.metainfo.infohash),
peer_id : encodeURIComponent(this.peerId()),
@@ -122,21 +154,61 @@ Tracker.prototype.announce = function(event){
// The dirty work:
// Substitute escape function - using native,
- // info_hash'd get encoded twice
+ // info_hash'd get encoded twice, which we do
+ // not want - need better solution?
encodingFunc = qs.escape;
qs.escape = dummyEncoder;
reqString = qs.stringify(params, '&', '=');
qs.escape = encodingFunc;
+ // Send the announcement
send();
};
/**
+ * Parses tracker response
+ *
+ * @param {Buffer} resultBuffer
+ */
+Tracker.prototype._parseResponse = function(resultBuffer){
+ var response = bencode.bdecode(resultBuffer);
+
+ // If present, don't process response any further
+ if(response['failure reason']){
+ this.response['failure reason'] = response['failure reason'];
+ return;
+ }
+
+ // Set response info
+ this.response['failure reason'] = null;
+ this.response['warning message'] = response['warning message'] || null;
+ this.response['interval'] = response['interval']; // || this.response['interval'];
+ this.response['min interval'] = response['min interval'] || this.response['min interval'];
+ this.response['tracker id'] = response['tracker id'] || this.response['tracker id'];
+ this.response['complete'] = response['complete']; // || this.response['complete'];
+ this.response['incomplete'] = response['incomplete'];
+
+ // Peers binary model. First 4 bytes represent IP, last 2 represent port
+ var peersBinary = response['peers'],
+ peers = [],
+ peer;
+
+ // @TODO
+ for(var i = 0, ii = peersBinary.length; i < ii; i+=6){
+ peer = new Peer(peersBinary.slice(i, i+4), peersBinary.slice(i+5, i+6));
+ peers.push(peer);
+ }
+
+ // @TODO: peers dictionary model
+};
+
+/**
* Returns event type
* @param {String} event
*/
Tracker.prototype._getEvent = function(event){
if(!this.announcedStart){
+ this.announcedStart = true;
return 'started';
}
else if (event == 'started' && this.announcedStart || event == 'completed' && this.announcedCompletion){

0 comments on commit dd830ab

Please sign in to comment.