/ lib / common-node.js
common-node.js
 1  /**
 2   * Functions/constants needed by both the client and server (but only in node).
 3   * These are separate from common.js so they can be skipped when bundling for the browser.
 4   */
 5  
 6  import querystring from 'querystring'
 7  import { concat } from 'uint8-util'
 8  
 9  export const IPV4_RE = /^[\d.]+$/
10  export const IPV6_RE = /^[\da-fA-F:]+$/
11  export const REMOVE_IPV4_MAPPED_IPV6_RE = /^::ffff:/
12  
13  export const CONNECTION_ID = concat([toUInt32(0x417), toUInt32(0x27101980)])
14  export const ACTIONS = { CONNECT: 0, ANNOUNCE: 1, SCRAPE: 2, ERROR: 3 }
15  export const EVENTS = { update: 0, completed: 1, started: 2, stopped: 3, paused: 4 }
16  export const EVENT_IDS = {
17    0: 'update',
18    1: 'completed',
19    2: 'started',
20    3: 'stopped',
21    4: 'paused'
22  }
23  export const EVENT_NAMES = {
24    update: 'update',
25    completed: 'complete',
26    started: 'start',
27    stopped: 'stop',
28    paused: 'pause'
29  }
30  
31  /**
32   * Client request timeout. How long to wait before considering a request to a
33   * tracker server to have timed out.
34   */
35  export const REQUEST_TIMEOUT = 15000
36  
37  /**
38   * Client destroy timeout. How long to wait before forcibly cleaning up all
39   * pending requests, open sockets, etc.
40   */
41  export const DESTROY_TIMEOUT = 1000
42  
43  export function toUInt32 (n) {
44    const buf = new Uint8Array(4)
45    const view = new DataView(buf.buffer)
46    view.setUint32(0, n)
47    return buf
48  }
49  
50  /**
51   * `querystring.parse` using `unescape` instead of decodeURIComponent, since bittorrent
52   * clients send non-UTF8 querystrings
53   * @param  {string} q
54   * @return {Object}
55   */
56  export const querystringParse = q => querystring.parse(q, null, null, { decodeURIComponent: unescape })
57  
58  /**
59   * `querystring.stringify` using `escape` instead of encodeURIComponent, since bittorrent
60   * clients send non-UTF8 querystrings
61   * @param  {Object} obj
62   * @return {string}
63   */
64  export const querystringStringify = obj => {
65    let ret = querystring.stringify(obj, null, null, { encodeURIComponent: escape })
66    ret = ret.replace(/[@*/+]/g, char => // `escape` doesn't encode the characters @*/+ so we do it manually
67    `%${char.charCodeAt(0).toString(16).toUpperCase()}`)
68    return ret
69  }