const Rpc = Class({ implements: [Logged], name: 'rpc', initialize: function() { this.handlers = {}; this.tag = 'rpc'; }, onMessage: function(message) { this.debug('request: '+JSON.stringify(message)); let response = {}; try { //this.debug(this.handlers[message.method]); response.arguments = this.handlers[message.method](message.arguments); response.result = 'success'; } catch (e) { this.error('error while handling '+message.method+': '+e); console.exception(e); response.result = e; } response.tag = message.tag; this.debug('response: '+JSON.stringify(response)); return response; }, on: function(method, handler) { this.debug('registering handler for '+method); this.handlers[method] = handler; } });
const {Server} = require('./net'); const {Logged} = require('./log'); const {EventTarget} = require('event/target'); const {emit} = require('event/core'); const {Class} = require('heritage'); const Listener = Class({ implements: [Logged, EventTarget], name: 'Listener', initialize: function() { this.port = 6881 + Math.floor(10*Math.random()); this.tag = this.port; this.server = new Server(); this.server.on('connection', (function(conn) { emit(this, 'newpeer', conn); }).bind(this)); }, start: function() { this.server.listen(this.port); } }); exports.Listener = Listener;
const HttpTracker = Class({ implements: [Logged, EventTarget], initialize: function(url, params) { this.url = url; this.announce = url.spec; this.tag = url.host; this.params = params; }, set interval (interval) { if (this.timer) { timers.clearInterval(this.timer); } this.timer = timers.setInterval(this.ping.bind(this), interval); }, ping: function() { let existingParams = querystring.parse(this.url.query); for (name in existingParams) { params[name] = existingParams[name]; } this.debug('base url: '+this.url.spec); let trackerUrl = url.URL(this.url.filePath + '?' + querystring.stringify(this.params), this.url); this.info('pinging tracker '+trackerUrl.spec); this.httpRequestHelper(trackerUrl, {}, 10, { success: (function(body) { try { let result = bencode.decode(body); this.debug('parsed tracker response'); emit(this, 'announce', result); } catch (e) { this.error('failed to parse tracker response: '+e); emit(this, 'error', e); } }).bind(this), error: (function(error) { this.error('tracker responded with error: '+error); emit(this, 'error', error); }).bind(this) }); }, // callback(exception, response, body) // Handles redirects, coalescing response. httpRequestHelper: function(uri, headers, redirectLimit, options) { var request = http.ClientRequest({ uri: uri, headers: headers, method: 'GET', }); request.on('response', (function(response){ var statusCode = response.statusCode; this.debug('received response. status='+statusCode); var body = ''; if (statusCode == 200) { response.setEncoding('binary'); response.on('error', function(error){ options.error(error); }); response.on('end', function(){ options.success(body); }); response.on('data', function(chunk){ body += chunk; }); } else { if (statusCode >= 300 && statusCode <= 399) { if (redirectLimit <= 0) { options.error(Error('too many redirects')); } else { this.info('redirect ' + statusCode + ' ' + JSON.stringify(body)); httpRequestHelper(method, host, port, path, headers, redirectLimit - 1, options); } } else { options.error(new http.HttpError(statusCode)); } } }).bind(this)); request.end(); } });
var Manager = Class({ initialize : function (config) { this.paths = config.paths || []; this.ignore = config.ignore || []; }, setPaths : function (paths) { this.paths = paths || []; }, addPath : function (path) { this.paths.push(path); }, resolvePath : function (file) { var ignores = this.getIgnorePaths(file); file = file.replace(/^(\/|\.\/)/i, ""); for (var i in this.paths) { var _path = path.join(this.paths[i], file); var skip = false; for (var j in ignores) { if (_path.indexOf(ignores[j]) === 0 || _path == ignores[j]) { skip = true; break; } } if (skip) { continue; } if (fs.existsSync(_path)) { return _path; } } throw new Error("Cannot resolve path: " + file); }, require : function (path) { try { var realPath = this.resolvePath(path); return require(realPath); } catch (e) { console.error(e); console.error(e.stack); throw new Error("Failed to require path:" + path); } }, requireMerged : function (file) { var paths = JSON.parse(JSON.stringify(this.paths)); paths.reverse(); file = file.replace(/^(\/|\.\/)/i, ""); var final = {}; for (var i in paths) { var _path = path.join(paths[i], file); if (fs.existsSync(_path)) { final = merge(final, require(_path)); } } return final; }, getIgnorePaths: function (file) { var ignores = JSON.parse(JSON.stringify(this.ignore)); for (var i = 1; i < stackTrace.get().length; i++) { if ( stackTrace.get()[i].getFileName() && !stackTrace.get()[i].getFileName().match(/swag-require/ig) && stackTrace.get()[i].getFileName().indexOf(file) >= 0 ) { ignores.push(stackTrace.get()[i].getFileName()); break; } } return ignores; } });
const Protocol = Class({ extends: Unknown, implements: [Logged], interfaces: [Ci.nsIProtocolHandler], scheme: 'torrent', protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE, allowPort: function(port, scheme) { return false; }, tag: 'torrentproto', name: 'Protocol', newURI: function(spec, charset, baseURI) { try { let uri = Cc['@mozilla.org/network/simple-uri;1'].createInstance(Ci.nsIURI); this.debug('creating url from '+spec); uri.spec = spec; return uri; } catch (e) { console.exception(e); throw e; } }, newChannel: function(uri) { try { this.debug('creating channel from uri '+uri.spec); return Channel(uri); } catch (e) { console.exception(e); throw e; } } });
const Protocol = Class({ extends: Unknown, implements: [Logged], interfaces: [Ci.nsIProtocolHandler], scheme: 'magnet', protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE, allowPort: function(port, scheme) { return false; }, tag: 'magnet', name: 'Protocol', newURI: function(spec, charset, baseURI) { try { let uri = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL); this.debug('creating url from '+spec); uri.init(1, 0, spec, null, null); return uri.QueryInterface(Ci.nsIURI); } catch (e) { console.exception(e); throw e; } }, newChannel: function(uri) { try { this.debug('creating channel from uri '+uri.spec); return new Channel(uri.QueryInterface(Ci.nsIURL)); } catch (e) { console.exception(e); throw e; } } });