mirror of
https://github.com/webtorrent/bittorrent-tracker.git
synced 2024-12-14 19:36:24 +00:00
0aadcc1cbb
If the user calls: client.stop() client.destroy() We should ensure that the final 'stopped' message reaches the tracker server, even though the client will not get the response (because they destroyed the client and no more events will be emitted). If there are pending requests when destroy() is called, then a 1s timer is set after which point all requests are forcibly cleaned up. If the requests complete before the 1s timer fires, then cleanup happens right away (so we're not stuck waiting for the 1s timer). So, destroy() can happen one of three ways: - immediately, if no pending requests exist - after exactly 1s, if pending requests exist and they don't complete within 1s - less than 1s, if pending requests exist and they all complete before the 1s timer fires
79 lines
2.1 KiB
JavaScript
79 lines
2.1 KiB
JavaScript
/**
|
|
* Functions/constants needed by both the client and server (but only in node).
|
|
* These are separate from common.js so they can be skipped when bundling for the browser.
|
|
*/
|
|
|
|
var Buffer = require('safe-buffer').Buffer
|
|
var querystring = require('querystring')
|
|
|
|
exports.IPV4_RE = /^[\d.]+$/
|
|
exports.IPV6_RE = /^[\da-fA-F:]+$/
|
|
exports.REMOVE_IPV4_MAPPED_IPV6_RE = /^::ffff:/
|
|
|
|
exports.CONNECTION_ID = Buffer.concat([ toUInt32(0x417), toUInt32(0x27101980) ])
|
|
exports.ACTIONS = { CONNECT: 0, ANNOUNCE: 1, SCRAPE: 2, ERROR: 3 }
|
|
exports.EVENTS = { update: 0, completed: 1, started: 2, stopped: 3 }
|
|
exports.EVENT_IDS = {
|
|
0: 'update',
|
|
1: 'completed',
|
|
2: 'started',
|
|
3: 'stopped'
|
|
}
|
|
exports.EVENT_NAMES = {
|
|
update: 'update',
|
|
completed: 'complete',
|
|
started: 'start',
|
|
stopped: 'stop'
|
|
}
|
|
|
|
/**
|
|
* Client request timeout. How long to wait before considering a request to a
|
|
* tracker server to have timed out.
|
|
*/
|
|
exports.REQUEST_TIMEOUT = 15000
|
|
|
|
/**
|
|
* Client destroy timeout. How long to wait before forcibly cleaning up all
|
|
* pending requests, open sockets, etc.
|
|
*/
|
|
exports.DESTROY_TIMEOUT = 1000
|
|
|
|
function toUInt32 (n) {
|
|
var buf = Buffer.allocUnsafe(4)
|
|
buf.writeUInt32BE(n, 0)
|
|
return buf
|
|
}
|
|
exports.toUInt32 = toUInt32
|
|
|
|
/**
|
|
* `querystring.parse` using `unescape` instead of decodeURIComponent, since bittorrent
|
|
* clients send non-UTF8 querystrings
|
|
* @param {string} q
|
|
* @return {Object}
|
|
*/
|
|
exports.querystringParse = function (q) {
|
|
var saved = querystring.unescape
|
|
querystring.unescape = unescape // global
|
|
var ret = querystring.parse(q)
|
|
querystring.unescape = saved
|
|
return ret
|
|
}
|
|
|
|
/**
|
|
* `querystring.stringify` using `escape` instead of encodeURIComponent, since bittorrent
|
|
* clients send non-UTF8 querystrings
|
|
* @param {Object} obj
|
|
* @return {string}
|
|
*/
|
|
exports.querystringStringify = function (obj) {
|
|
var saved = querystring.escape
|
|
querystring.escape = escape // global
|
|
var ret = querystring.stringify(obj)
|
|
ret = ret.replace(/[@*/+]/g, function (char) {
|
|
// `escape` doesn't encode the characters @*/+ so we do it manually
|
|
return '%' + char.charCodeAt(0).toString(16).toUpperCase()
|
|
})
|
|
querystring.escape = saved
|
|
return ret
|
|
}
|