@firaenix/bittorrent-protocol
Version:
Simple, robust, BitTorrent peer wire protocol implementation
229 lines (228 loc) • 7.8 kB
TypeScript
/// <reference types="node" />
import BitField from 'bitfield';
import stream from 'readable-stream';
import { ExtendedHandshake } from './Extension';
import { IExtension } from './models/IExtension';
import { PieceRequest, RequestCallback } from './models/PieceRequest';
import { ParseRequest } from './models/ParseRequest';
import { WireEvents } from './models/WireEvents';
import { ExtensionsMap } from './models/ExtensionsMap';
export declare class Wire extends stream.Duplex {
_debugId: string;
peerId: string | undefined;
peerIdBuffer: Buffer | undefined;
type: 'webrtc' | 'tcpIncoming' | 'tcpOutgoing' | 'webSeed' | null;
amChoking: boolean;
amInterested: boolean;
peerChoking: boolean;
peerInterested: boolean;
peerPieces: BitField;
peerExtensions: ExtensionsMap;
requests: PieceRequest[];
peerRequests: PieceRequest[];
extendedMapping: {
[key: number]: string;
};
peerExtendedMapping: {
[key: string]: number;
};
extendedHandshake: ExtendedHandshake;
peerExtendedHandshake: ExtendedHandshake;
_ext: {
[extensionName: string]: IExtension;
};
_nextExt: number;
uploaded: number;
downloaded: number;
uploadSpeed: (speed: number) => void;
downloadSpeed: (speed: number) => void;
_keepAliveInterval: number | NodeJS.Timeout | undefined;
_timeout: number | NodeJS.Timeout | undefined;
_timeoutMs: number;
destroyed: boolean;
_finished: boolean;
_parseRequests: Array<ParseRequest>;
_buffer: Buffer;
_timeoutUnref: unknown;
_handshakeSent: boolean;
_extendedHandshakeSent: boolean;
_handshakeSuccess: boolean;
_extendedHandshakeSuccess: boolean;
wireName: string | undefined;
constructor(name?: string);
once<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this;
on<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this;
off<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this;
emit<U extends keyof WireEvents>(event: U, ...args: Parameters<WireEvents[U]>): boolean;
/**
* Set whether to send a "keep-alive" ping (sent every 55s)
* @param {boolean} enable
*/
setKeepAlive(enable: boolean): void;
/**
* Set the amount of time to wait before considering a request to be "timed out"
* @param {number} ms
* @param {boolean=} unref (should the timer be unref'd? default: false)
*/
setTimeout(ms: number, unref?: boolean): void;
destroy(): this;
end(...args: any[]): void;
/**
* Use the specified protocol extension.
* @param {function} Extension
*/
use(newExtension: (wire: Wire) => IExtension): void;
/**
* Message "keep-alive": <len=0000>
*/
keepAlive(): void;
/**
* Message: "handshake" <pstrlen><pstr><reserved><info_hash><peer_id>
* @param {Buffer|string} infoHash (as Buffer or *hex* string)
* @param {Buffer|string} peerId
* @param {Object} extensions
*/
handshake(infoHash: Buffer | string, peerId: Buffer | string, extensions?: any): void;
private _sendExtendedHandshake;
/**
* Message "choke": <len=0001><id=0>
*/
choke(): void;
/**
* Message "unchoke": <len=0001><id=1>
*/
unchoke(): void;
/**
* Message "interested": <len=0001><id=2>
*/
interested(): void;
/**
* Message "uninterested": <len=0001><id=3>
*/
uninterested(): void;
/**
* Message "have": <len=0005><id=4><piece index>
* @param {number} index
*/
have(index: number): void;
/**
* Message "bitfield": <len=0001+X><id=5><bitfield>
* @param {BitField|Buffer} bitfield
*/
bitfield(bitfield: BitField | Buffer): void;
/**
* Callback will be resolved when onPiece(index, offset, length, buffer) is called or something fails when requesting.
*
* NOTE: index,offset,length are used as a key to look up the callback later.
*
* So make sure you specify the length correctly or you will never get your callback.
*
* If the other party sends the same index and offset but a buffer of a different length, you will not recieve your callback.
*
* Message "request": <len=0013><id=6><index><begin><length>
* @param {number} index
* @param {number} offset
* @param {number} length
* @param {function} cb
*/
request(index: number, offset: number, length: number, cb: RequestCallback): void;
/**
* Message "piece": <len=0009+X><id=7><index><begin><block>
* @param {number} index
* @param {number} offset
* @param {Buffer} buffer
*/
piece(index: number, offset: number, buffer: Buffer): void;
/**
* Message "cancel": <len=0013><id=8><index><begin><length>
* @param {number} index
* @param {number} offset
* @param {number} length
*/
cancel(index: number, offset: number, length: number): void;
/**
* Message: "port" <len=0003><id=9><listen-port>
* @param {Number} port
*/
port(port: number): void;
/**
* Message: "extended" <len=0005+X><id=20><ext-number><payload>
* @param {number|string} ext
* @param {Object} obj
*/
extended(ext: number | string, obj: object): void;
/**
* Duplex stream method. Called whenever the remote peer stream wants data. No-op
* since we'll just push data whenever we get it.
*/
_read(): void;
/**
* Send a message to the remote peer.
*/
private _message;
private _push;
private _onKeepAlive;
private _onHandshake;
private _onChoke;
private _onUnchoke;
private _onInterested;
private _onUninterested;
private _onHave;
private _onBitField;
private _onRequest;
private _onPiece;
private _onCancel;
private _onPort;
private onExtendedMessage;
private onExtendedHandshake;
private _onExtended;
private _onTimeout;
/**
* Duplex stream method. Called whenever the remote peer has data for us. Data that the
* remote peer sends gets buffered (i.e. not actually processed) until the right number
* of bytes have arrived, determined by the last call to `this._parse(number, callback)`.
* Once enough bytes have arrived to process the message, the callback function
* (i.e. `this._parser`) gets called with the full buffer of data.
* @param {Buffer} data
* @param {string} encoding
* @param {function} cb
*/
_write(data: Buffer, encoding: string, cb: (e: any) => void): void;
private parseStream;
private _callback;
private _clearTimeout;
private _updateTimeout;
/**
* Takes a number of bytes that the local peer is waiting to receive from the remote peer
* in order to parse a complete message, and a callback function to be called once enough
* bytes have arrived.
* @param {number} size
* @param {function} parser
*/
private _parse;
/**
* Handle the first 4 bytes of a message, to determine the length of bytes that must be
* waited for in order to have the whole message.
* @param {Buffer} buffer
*/
private _onMessageLength;
/**
* Handle a message from the remote peer.
* @param {Buffer} buffer
*/
private _onMessage;
private _parseHandshake;
private _onFinish;
private _debug;
/**
* Retrieves the first entity from the requests array that matches the index, offset and length given.
*
* Often used in conjunction with _callback to call back to waiting piece requests
* @param requests
* @param pieceIdx
* @param offset
* @param length
*/
private _pull;
}
export default Wire;