nlcurl 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -13
- package/dist/cli/args.d.ts +37 -5
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +6 -17
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +25 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +24 -7
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +24 -12
- package/dist/cli/output.js.map +1 -1
- package/dist/cookies/jar.d.ts +45 -13
- package/dist/cookies/jar.d.ts.map +1 -1
- package/dist/cookies/jar.js +88 -29
- package/dist/cookies/jar.js.map +1 -1
- package/dist/cookies/parser.d.ts +25 -3
- package/dist/cookies/parser.d.ts.map +1 -1
- package/dist/cookies/parser.js +12 -7
- package/dist/cookies/parser.js.map +1 -1
- package/dist/core/client.d.ts +49 -33
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +64 -38
- package/dist/core/client.js.map +1 -1
- package/dist/core/errors.d.ts +94 -6
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +95 -6
- package/dist/core/errors.js.map +1 -1
- package/dist/core/request.d.ts +96 -30
- package/dist/core/request.d.ts.map +1 -1
- package/dist/core/request.js +0 -3
- package/dist/core/request.js.map +1 -1
- package/dist/core/response.d.ts +92 -8
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +92 -7
- package/dist/core/response.js.map +1 -1
- package/dist/core/session.d.ts +109 -14
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +124 -46
- package/dist/core/session.js.map +1 -1
- package/dist/fingerprints/akamai.d.ts +11 -11
- package/dist/fingerprints/akamai.d.ts.map +1 -1
- package/dist/fingerprints/akamai.js +10 -14
- package/dist/fingerprints/akamai.js.map +1 -1
- package/dist/fingerprints/database.d.ts +14 -15
- package/dist/fingerprints/database.d.ts.map +1 -1
- package/dist/fingerprints/database.js +14 -19
- package/dist/fingerprints/database.js.map +1 -1
- package/dist/fingerprints/extensions.d.ts +121 -27
- package/dist/fingerprints/extensions.d.ts.map +1 -1
- package/dist/fingerprints/extensions.js +132 -49
- package/dist/fingerprints/extensions.js.map +1 -1
- package/dist/fingerprints/ja3.d.ts +34 -18
- package/dist/fingerprints/ja3.d.ts.map +1 -1
- package/dist/fingerprints/ja3.js +34 -18
- package/dist/fingerprints/ja3.js.map +1 -1
- package/dist/fingerprints/profiles/chrome.d.ts +21 -10
- package/dist/fingerprints/profiles/chrome.d.ts.map +1 -1
- package/dist/fingerprints/profiles/chrome.js +25 -22
- package/dist/fingerprints/profiles/chrome.js.map +1 -1
- package/dist/fingerprints/profiles/edge.d.ts +10 -7
- package/dist/fingerprints/profiles/edge.d.ts.map +1 -1
- package/dist/fingerprints/profiles/edge.js +10 -10
- package/dist/fingerprints/profiles/edge.js.map +1 -1
- package/dist/fingerprints/profiles/firefox.d.ts +11 -3
- package/dist/fingerprints/profiles/firefox.d.ts.map +1 -1
- package/dist/fingerprints/profiles/firefox.js +15 -14
- package/dist/fingerprints/profiles/firefox.js.map +1 -1
- package/dist/fingerprints/profiles/safari.d.ts +14 -3
- package/dist/fingerprints/profiles/safari.d.ts.map +1 -1
- package/dist/fingerprints/profiles/safari.js +16 -13
- package/dist/fingerprints/profiles/safari.js.map +1 -1
- package/dist/fingerprints/profiles/tor.d.ts +8 -7
- package/dist/fingerprints/profiles/tor.d.ts.map +1 -1
- package/dist/fingerprints/profiles/tor.js +8 -14
- package/dist/fingerprints/profiles/tor.js.map +1 -1
- package/dist/fingerprints/types.d.ts +70 -47
- package/dist/fingerprints/types.d.ts.map +1 -1
- package/dist/fingerprints/types.js +0 -7
- package/dist/fingerprints/types.js.map +1 -1
- package/dist/http/h1/client.d.ts +30 -9
- package/dist/http/h1/client.d.ts.map +1 -1
- package/dist/http/h1/client.js +152 -15
- package/dist/http/h1/client.js.map +1 -1
- package/dist/http/h1/encoder.d.ts +9 -6
- package/dist/http/h1/encoder.d.ts.map +1 -1
- package/dist/http/h1/encoder.js +8 -12
- package/dist/http/h1/encoder.js.map +1 -1
- package/dist/http/h1/parser.d.ts +68 -14
- package/dist/http/h1/parser.d.ts.map +1 -1
- package/dist/http/h1/parser.js +92 -37
- package/dist/http/h1/parser.js.map +1 -1
- package/dist/http/h2/client.d.ts +81 -14
- package/dist/http/h2/client.d.ts.map +1 -1
- package/dist/http/h2/client.js +465 -63
- package/dist/http/h2/client.js.map +1 -1
- package/dist/http/h2/frames.d.ts +103 -6
- package/dist/http/h2/frames.d.ts.map +1 -1
- package/dist/http/h2/frames.js +96 -17
- package/dist/http/h2/frames.js.map +1 -1
- package/dist/http/h2/hpack.d.ts +30 -5
- package/dist/http/h2/hpack.d.ts.map +1 -1
- package/dist/http/h2/hpack.js +39 -35
- package/dist/http/h2/hpack.js.map +1 -1
- package/dist/http/negotiator.d.ts +35 -12
- package/dist/http/negotiator.d.ts.map +1 -1
- package/dist/http/negotiator.js +89 -24
- package/dist/http/negotiator.js.map +1 -1
- package/dist/http/pool.d.ts +66 -17
- package/dist/http/pool.d.ts.map +1 -1
- package/dist/http/pool.js +47 -20
- package/dist/http/pool.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -13
- package/dist/index.js.map +1 -1
- package/dist/middleware/interceptor.d.ts +40 -8
- package/dist/middleware/interceptor.d.ts.map +1 -1
- package/dist/middleware/interceptor.js +28 -6
- package/dist/middleware/interceptor.js.map +1 -1
- package/dist/middleware/rate-limiter.d.ts +18 -5
- package/dist/middleware/rate-limiter.d.ts.map +1 -1
- package/dist/middleware/rate-limiter.js +12 -7
- package/dist/middleware/rate-limiter.js.map +1 -1
- package/dist/middleware/retry.d.ts +17 -5
- package/dist/middleware/retry.d.ts.map +1 -1
- package/dist/middleware/retry.js +13 -11
- package/dist/middleware/retry.js.map +1 -1
- package/dist/proxy/http-proxy.d.ts +17 -9
- package/dist/proxy/http-proxy.d.ts.map +1 -1
- package/dist/proxy/http-proxy.js +9 -13
- package/dist/proxy/http-proxy.js.map +1 -1
- package/dist/proxy/socks.d.ts +20 -9
- package/dist/proxy/socks.d.ts.map +1 -1
- package/dist/proxy/socks.js +20 -31
- package/dist/proxy/socks.js.map +1 -1
- package/dist/tls/constants.d.ts +74 -4
- package/dist/tls/constants.d.ts.map +1 -1
- package/dist/tls/constants.js +75 -21
- package/dist/tls/constants.js.map +1 -1
- package/dist/tls/node-engine.d.ts +17 -16
- package/dist/tls/node-engine.d.ts.map +1 -1
- package/dist/tls/node-engine.js +20 -27
- package/dist/tls/node-engine.js.map +1 -1
- package/dist/tls/stealth/client-hello.d.ts +32 -16
- package/dist/tls/stealth/client-hello.d.ts.map +1 -1
- package/dist/tls/stealth/client-hello.js +13 -37
- package/dist/tls/stealth/client-hello.js.map +1 -1
- package/dist/tls/stealth/engine.d.ts +18 -10
- package/dist/tls/stealth/engine.d.ts.map +1 -1
- package/dist/tls/stealth/engine.js +18 -24
- package/dist/tls/stealth/engine.js.map +1 -1
- package/dist/tls/stealth/handshake.d.ts +31 -17
- package/dist/tls/stealth/handshake.d.ts.map +1 -1
- package/dist/tls/stealth/handshake.js +173 -74
- package/dist/tls/stealth/handshake.js.map +1 -1
- package/dist/tls/stealth/key-schedule.d.ts +89 -32
- package/dist/tls/stealth/key-schedule.d.ts.map +1 -1
- package/dist/tls/stealth/key-schedule.js +62 -42
- package/dist/tls/stealth/key-schedule.js.map +1 -1
- package/dist/tls/stealth/record-layer.d.ts +76 -25
- package/dist/tls/stealth/record-layer.d.ts.map +1 -1
- package/dist/tls/stealth/record-layer.js +66 -36
- package/dist/tls/stealth/record-layer.js.map +1 -1
- package/dist/tls/types.d.ts +33 -25
- package/dist/tls/types.d.ts.map +1 -1
- package/dist/tls/types.js +0 -4
- package/dist/tls/types.js.map +1 -1
- package/dist/utils/buffer-reader.d.ts +99 -7
- package/dist/utils/buffer-reader.d.ts.map +1 -1
- package/dist/utils/buffer-reader.js +99 -7
- package/dist/utils/buffer-reader.js.map +1 -1
- package/dist/utils/buffer-writer.d.ts +99 -10
- package/dist/utils/buffer-writer.d.ts.map +1 -1
- package/dist/utils/buffer-writer.js +101 -12
- package/dist/utils/buffer-writer.js.map +1 -1
- package/dist/utils/encoding.d.ts +33 -8
- package/dist/utils/encoding.d.ts.map +1 -1
- package/dist/utils/encoding.js +58 -13
- package/dist/utils/encoding.js.map +1 -1
- package/dist/utils/logger.d.ts +61 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +52 -4
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/url.d.ts +47 -7
- package/dist/utils/url.d.ts.map +1 -1
- package/dist/utils/url.js +47 -7
- package/dist/utils/url.js.map +1 -1
- package/dist/ws/client.d.ts +59 -15
- package/dist/ws/client.d.ts.map +1 -1
- package/dist/ws/client.js +34 -27
- package/dist/ws/client.js.map +1 -1
- package/dist/ws/frame.d.ts +43 -9
- package/dist/ws/frame.d.ts.map +1 -1
- package/dist/ws/frame.js +35 -19
- package/dist/ws/frame.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TLS record layer.
|
|
3
|
-
*
|
|
4
|
-
* Handles framing, encryption, and decryption of TLS records.
|
|
5
|
-
* Operates on raw TCP byte streams.
|
|
6
|
-
*/
|
|
7
1
|
import { createCipheriv, createDecipheriv, } from 'node:crypto';
|
|
8
2
|
import { BufferWriter } from '../../utils/buffer-writer.js';
|
|
9
3
|
import { RecordType, ProtocolVersion } from '../constants.js';
|
|
10
4
|
import { TLSError } from '../../core/errors.js';
|
|
11
|
-
/** Maximum TLS record payload (2^14 = 16384). */
|
|
12
5
|
const MAX_RECORD_PAYLOAD = 16384;
|
|
13
|
-
/** Maximum ciphertext overhead (tag + content type byte). */
|
|
14
6
|
const MAX_CIPHERTEXT_OVERHEAD = 256;
|
|
15
|
-
// ---- Record reading ----
|
|
16
7
|
/**
|
|
17
|
-
*
|
|
8
|
+
* Attempts to parse a single TLS record from `data` beginning at `offset`.
|
|
9
|
+
* Returns `null` without consuming the buffer if fewer than 5 bytes are
|
|
10
|
+
* available or the payload has not been fully received yet.
|
|
18
11
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
12
|
+
* @param {Buffer} data - Buffer containing one or more TLS records.
|
|
13
|
+
* @param {number} offset - Byte offset within `data` to begin parsing.
|
|
14
|
+
* @returns {{ record: TLSRecord; bytesRead: number } | null} Parsed record and byte count, or `null` if more data is needed.
|
|
21
15
|
*/
|
|
22
16
|
export function readRecord(data, offset) {
|
|
23
17
|
if (data.length - offset < 5)
|
|
@@ -34,7 +28,12 @@ export function readRecord(data, offset) {
|
|
|
34
28
|
};
|
|
35
29
|
}
|
|
36
30
|
/**
|
|
37
|
-
*
|
|
31
|
+
* Serializes a TLS record into its 5-byte header plus payload binary form.
|
|
32
|
+
*
|
|
33
|
+
* @param {number} type - TLS content type byte.
|
|
34
|
+
* @param {number} version - TLS record version (e.g. `0x0303`).
|
|
35
|
+
* @param {Buffer} payload - Record payload bytes.
|
|
36
|
+
* @returns {Buffer} The complete serialized TLS record.
|
|
38
37
|
*/
|
|
39
38
|
export function writeRecord(type, version, payload) {
|
|
40
39
|
const w = new BufferWriter(5 + payload.length);
|
|
@@ -45,7 +44,12 @@ export function writeRecord(type, version, payload) {
|
|
|
45
44
|
return w.toBuffer();
|
|
46
45
|
}
|
|
47
46
|
/**
|
|
48
|
-
*
|
|
47
|
+
* Maps a cipher suite name string to the corresponding AEAD algorithm
|
|
48
|
+
* identifier used by the record layer.
|
|
49
|
+
*
|
|
50
|
+
* @param {string} cipherName - Cipher suite name from {@link TLSConnectionInfo} (e.g. `"TLS_AES_128_GCM_SHA256"`).
|
|
51
|
+
* @returns {AEADAlgorithm} The corresponding AEAD algorithm identifier.
|
|
52
|
+
* @throws {TLSError} If the cipher name does not correspond to a supported AEAD algorithm.
|
|
49
53
|
*/
|
|
50
54
|
export function aeadFromCipher(cipherName) {
|
|
51
55
|
if (cipherName.includes('AES_128_GCM') || cipherName.includes('aes-128-gcm')) {
|
|
@@ -59,28 +63,34 @@ export function aeadFromCipher(cipherName) {
|
|
|
59
63
|
}
|
|
60
64
|
throw new TLSError(`Unsupported cipher: ${cipherName}`);
|
|
61
65
|
}
|
|
62
|
-
/** Tag size for all supported AEAD algorithms. */
|
|
63
66
|
const TAG_SIZE = 16;
|
|
64
67
|
/**
|
|
65
|
-
*
|
|
66
|
-
* sequence number (
|
|
68
|
+
* Constructs the per-record nonce by XOR-ing the static IV with the
|
|
69
|
+
* big-endian 64-bit sequence number (RFC 8446 ¥5.3).
|
|
70
|
+
*
|
|
71
|
+
* @param {Buffer} iv - Static IV of length matching the AEAD algorithm.
|
|
72
|
+
* @param {bigint} sequenceNumber - Record sequence number (starts at 0, increments by 1).
|
|
73
|
+
* @returns {Buffer} The per-record nonce.
|
|
67
74
|
*/
|
|
68
75
|
export function buildNonce(iv, sequenceNumber) {
|
|
69
76
|
const nonce = Buffer.from(iv);
|
|
70
77
|
const seqBuf = Buffer.alloc(8);
|
|
71
78
|
seqBuf.writeBigUInt64BE(sequenceNumber);
|
|
72
|
-
// XOR the last 8 bytes of IV with the sequence number
|
|
73
79
|
for (let i = 0; i < 8; i++) {
|
|
74
80
|
nonce[nonce.length - 8 + i] ^= seqBuf[i];
|
|
75
81
|
}
|
|
76
82
|
return nonce;
|
|
77
83
|
}
|
|
78
84
|
/**
|
|
79
|
-
*
|
|
85
|
+
* Encrypts `plaintext` using the specified AEAD algorithm and returns the
|
|
86
|
+
* ciphertext with an appended 16-byte authentication tag.
|
|
80
87
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
88
|
+
* @param {AEADAlgorithm} algorithm - AEAD algorithm identifier.
|
|
89
|
+
* @param {Buffer} key - Encryption key.
|
|
90
|
+
* @param {Buffer} nonce - Per-record nonce.
|
|
91
|
+
* @param {Buffer} plaintext - Data to encrypt.
|
|
92
|
+
* @param {Buffer} additionalData - Additional authenticated data (AAD).
|
|
93
|
+
* @returns {Buffer} Ciphertext followed by the 16-byte authentication tag.
|
|
84
94
|
*/
|
|
85
95
|
export function encryptRecord(algorithm, key, nonce, plaintext, additionalData) {
|
|
86
96
|
const cipher = createCipheriv(algorithm, key, nonce, { authTagLength: TAG_SIZE });
|
|
@@ -91,10 +101,16 @@ export function encryptRecord(algorithm, key, nonce, plaintext, additionalData)
|
|
|
91
101
|
return Buffer.concat([encrypted, final, tag]);
|
|
92
102
|
}
|
|
93
103
|
/**
|
|
94
|
-
*
|
|
104
|
+
* Decrypts and authenticates `ciphertext` using the specified AEAD algorithm.
|
|
105
|
+
* The last 16 bytes of `ciphertext` are treated as the authentication tag.
|
|
95
106
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
107
|
+
* @param {AEADAlgorithm} algorithm - AEAD algorithm identifier.
|
|
108
|
+
* @param {Buffer} key - Decryption key.
|
|
109
|
+
* @param {Buffer} nonce - Per-record nonce.
|
|
110
|
+
* @param {Buffer} ciphertext - Ciphertext including the 16-byte authentication tag.
|
|
111
|
+
* @param {Buffer} additionalData - Additional authenticated data (AAD) for tag verification.
|
|
112
|
+
* @returns {Buffer} Decrypted plaintext bytes.
|
|
113
|
+
* @throws {TLSError} If the ciphertext is too short or authentication fails.
|
|
98
114
|
*/
|
|
99
115
|
export function decryptRecord(algorithm, key, nonce, ciphertext, additionalData) {
|
|
100
116
|
if (ciphertext.length < TAG_SIZE) {
|
|
@@ -115,26 +131,33 @@ export function decryptRecord(algorithm, key, nonce, ciphertext, additionalData)
|
|
|
115
131
|
}
|
|
116
132
|
}
|
|
117
133
|
/**
|
|
118
|
-
*
|
|
134
|
+
* Builds the additional authenticated data (AAD) for a TLS 1.3 application
|
|
135
|
+
* data record, encoded as a 5-byte pseudo-record header per RFC 8446 ¥5.2.
|
|
119
136
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
137
|
+
* @param {number} ciphertextLength - Total length of the ciphertext including the AEAD tag.
|
|
138
|
+
* @returns {Buffer} 5-byte AAD buffer.
|
|
122
139
|
*/
|
|
123
140
|
export function buildAdditionalData(ciphertextLength) {
|
|
124
141
|
const w = new BufferWriter(5);
|
|
125
142
|
w.writeUInt8(RecordType.APPLICATION_DATA);
|
|
126
|
-
w.writeUInt16(ProtocolVersion.TLS_1_2);
|
|
143
|
+
w.writeUInt16(ProtocolVersion.TLS_1_2);
|
|
127
144
|
w.writeUInt16(ciphertextLength);
|
|
128
145
|
return w.toBuffer();
|
|
129
146
|
}
|
|
130
147
|
/**
|
|
131
|
-
*
|
|
148
|
+
* Encodes a TLS 1.3 inner plaintext (content bytes + content type byte) and
|
|
149
|
+
* wraps it in an encrypted TLS record with the appropriate AAD, following
|
|
150
|
+
* RFC 8446 ¥5.2.
|
|
132
151
|
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
152
|
+
* @param {AEADAlgorithm} algorithm - AEAD algorithm identifier.
|
|
153
|
+
* @param {Buffer} key - Application traffic key.
|
|
154
|
+
* @param {Buffer} iv - Application traffic IV.
|
|
155
|
+
* @param {bigint} sequenceNumber - Sequence number for nonce derivation.
|
|
156
|
+
* @param {number} contentType - True content type byte to embed in the inner plaintext.
|
|
157
|
+
* @param {Buffer} plaintext - Application data to encrypt.
|
|
158
|
+
* @returns {Buffer} The complete TLS application_data record ready to send.
|
|
135
159
|
*/
|
|
136
160
|
export function wrapEncryptedRecord(algorithm, key, iv, sequenceNumber, contentType, plaintext) {
|
|
137
|
-
// Build inner plaintext: data + content_type byte
|
|
138
161
|
const inner = Buffer.alloc(plaintext.length + 1);
|
|
139
162
|
plaintext.copy(inner);
|
|
140
163
|
inner[plaintext.length] = contentType;
|
|
@@ -145,15 +168,22 @@ export function wrapEncryptedRecord(algorithm, key, iv, sequenceNumber, contentT
|
|
|
145
168
|
return writeRecord(RecordType.APPLICATION_DATA, ProtocolVersion.TLS_1_2, ciphertext);
|
|
146
169
|
}
|
|
147
170
|
/**
|
|
148
|
-
*
|
|
171
|
+
* Decrypts a TLS 1.3 application_data record, strips the zero-padding, and
|
|
172
|
+
* recovers the true content type embedded as the last non-zero byte of the
|
|
173
|
+
* inner plaintext (RFC 8446 ¥5.2).
|
|
149
174
|
*
|
|
150
|
-
*
|
|
175
|
+
* @param {AEADAlgorithm} algorithm - AEAD algorithm identifier.
|
|
176
|
+
* @param {Buffer} key - Application traffic key.
|
|
177
|
+
* @param {Buffer} iv - Application traffic IV.
|
|
178
|
+
* @param {bigint} sequenceNumber - Sequence number for nonce derivation.
|
|
179
|
+
* @param {TLSRecord} record - Encrypted TLS record received from the remote party.
|
|
180
|
+
* @returns {{ contentType: number; plaintext: Buffer }} Recovered content type and decrypted payload.
|
|
181
|
+
* @throws {TLSError} If decryption or authentication fails, or the record is empty after unpadding.
|
|
151
182
|
*/
|
|
152
183
|
export function unwrapEncryptedRecord(algorithm, key, iv, sequenceNumber, record) {
|
|
153
184
|
const nonce = buildNonce(iv, sequenceNumber);
|
|
154
185
|
const aad = buildAdditionalData(record.fragment.length);
|
|
155
186
|
const inner = decryptRecord(algorithm, key, nonce, record.fragment, aad);
|
|
156
|
-
// Strip trailing zeros and find the real content type
|
|
157
187
|
let i = inner.length - 1;
|
|
158
188
|
while (i >= 0 && inner[i] === 0)
|
|
159
189
|
i--;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-layer.js","sourceRoot":"","sources":["../../../src/tls/stealth/record-layer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"record-layer.js","sourceRoot":"","sources":["../../../src/tls/stealth/record-layer.ts"],"names":[],"mappings":"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"}
|
package/dist/tls/types.d.ts
CHANGED
|
@@ -1,58 +1,66 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TLS engine types and the ITLSEngine interface that both standard
|
|
3
|
-
* (node:tls) and stealth (raw handshake) engines implement.
|
|
4
|
-
*/
|
|
5
1
|
import type { Socket } from 'node:net';
|
|
6
2
|
import type { Duplex } from 'node:stream';
|
|
7
3
|
import type { BrowserProfile } from '../fingerprints/types.js';
|
|
8
4
|
import type { Logger } from '../utils/logger.js';
|
|
5
|
+
/**
|
|
6
|
+
* Options required to establish a TLS connection to a remote server.
|
|
7
|
+
*
|
|
8
|
+
* @typedef {Object} TLSConnectOptions
|
|
9
|
+
* @property {string} host - Remote hostname or IP address.
|
|
10
|
+
* @property {number} port - Remote TCP port.
|
|
11
|
+
* @property {Socket} [socket] - Pre-connected TCP socket to upgrade (e.g. after proxy CONNECT).
|
|
12
|
+
* @property {string} [servername] - TLS SNI hostname; defaults to `host`.
|
|
13
|
+
* @property {boolean} [insecure] - Skip TLS certificate verification when `true`.
|
|
14
|
+
* @property {string[]} [alpnProtocols] - ALPN protocol names to advertise (e.g. `['h2', 'http/1.1']`).
|
|
15
|
+
* @property {number} [timeout] - Handshake timeout in milliseconds.
|
|
16
|
+
* @property {AbortSignal} [signal] - Signal used to abort the connection attempt.
|
|
17
|
+
* @property {4|6} [family] - Force IPv4 (`4`) or IPv6 (`6`) for DNS resolution.
|
|
18
|
+
* @property {Logger} [logger] - Optional logger for diagnostic output.
|
|
19
|
+
*/
|
|
9
20
|
export interface TLSConnectOptions {
|
|
10
21
|
host: string;
|
|
11
22
|
port: number;
|
|
12
|
-
/** Existing TCP socket to wrap (for proxy tunneling). */
|
|
13
23
|
socket?: Socket;
|
|
14
|
-
/** Server name for SNI. Defaults to `host`. */
|
|
15
24
|
servername?: string;
|
|
16
|
-
/** Skip certificate verification. */
|
|
17
25
|
insecure?: boolean;
|
|
18
|
-
/** ALPN protocols to offer. Derived from profile if not given. */
|
|
19
26
|
alpnProtocols?: string[];
|
|
20
|
-
/** Timeout for the TLS handshake in milliseconds. */
|
|
21
27
|
timeout?: number;
|
|
22
|
-
/** Abort signal. */
|
|
23
28
|
signal?: AbortSignal;
|
|
29
|
+
family?: 4 | 6;
|
|
24
30
|
logger?: Logger;
|
|
25
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Metadata describing a successfully negotiated TLS connection.
|
|
34
|
+
*
|
|
35
|
+
* @typedef {Object} TLSConnectionInfo
|
|
36
|
+
* @property {string} version - Negotiated TLS version string (e.g. `"TLSv1.3"`).
|
|
37
|
+
* @property {string|null} alpnProtocol - Negotiated ALPN protocol (e.g. `"h2"`), or `null`.
|
|
38
|
+
* @property {string} cipher - Negotiated cipher suite name.
|
|
39
|
+
* @property {string} [ja3Hash] - JA3 fingerprint hash of the ClientHello, if computed.
|
|
40
|
+
*/
|
|
26
41
|
export interface TLSConnectionInfo {
|
|
27
|
-
/** Negotiated TLS protocol version, e.g. "TLSv1.3". */
|
|
28
42
|
version: string;
|
|
29
|
-
/** Negotiated ALPN protocol, e.g. "h2" or "http/1.1". */
|
|
30
43
|
alpnProtocol: string | null;
|
|
31
|
-
/** Negotiated cipher suite name. */
|
|
32
44
|
cipher: string;
|
|
33
|
-
/** The JA3 hash of the ClientHello actually sent. */
|
|
34
45
|
ja3Hash?: string;
|
|
35
46
|
}
|
|
36
47
|
/**
|
|
37
|
-
* A
|
|
48
|
+
* A duplex stream representing an established TLS connection. Extends
|
|
49
|
+
* `Duplex` with connection metadata and a controlled teardown method.
|
|
50
|
+
*
|
|
51
|
+
* @typedef {Duplex} TLSSocket
|
|
52
|
+
* @property {TLSConnectionInfo} connectionInfo - Metadata about the negotiated TLS session.
|
|
38
53
|
*/
|
|
39
54
|
export interface TLSSocket extends Duplex {
|
|
40
|
-
/** Connection metadata (available after the handshake completes). */
|
|
41
55
|
connectionInfo: TLSConnectionInfo;
|
|
42
|
-
/** Gracefully close the TLS connection. */
|
|
43
56
|
destroyTLS(): void;
|
|
44
57
|
}
|
|
45
58
|
/**
|
|
46
|
-
*
|
|
59
|
+
* Contract for TLS engine implementations. Both the standard Node.js TLS
|
|
60
|
+
* engine and the custom stealth engine implement this interface, allowing
|
|
61
|
+
* them to be substituted transparently by the {@link ProtocolNegotiator}.
|
|
47
62
|
*/
|
|
48
63
|
export interface ITLSEngine {
|
|
49
|
-
/**
|
|
50
|
-
* Open a TLS connection to the given host:port.
|
|
51
|
-
*
|
|
52
|
-
* If a BrowserProfile is supplied the engine MUST configure TLS
|
|
53
|
-
* parameters (cipher suites, curves, extensions, ALPN) to match the
|
|
54
|
-
* profile so that the JA3 fingerprint is correct.
|
|
55
|
-
*/
|
|
56
64
|
connect(options: TLSConnectOptions, profile?: BrowserProfile): Promise<TLSSocket>;
|
|
57
65
|
}
|
|
58
66
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/tls/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tls/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tls/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAU,SAAQ,MAAM;IACvC,cAAc,EAAE,iBAAiB,CAAC;IAClC,UAAU,IAAI,IAAI,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CACnF"}
|
package/dist/tls/types.js
CHANGED
package/dist/tls/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tls/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tls/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,31 +1,123 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Stateful cursor for reading typed values from a `Buffer` in big-endian byte
|
|
3
|
+
* order. Advances an internal position pointer after every read so callers
|
|
4
|
+
* don't need to track offsets manually.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const r = new BufferReader(buf);
|
|
8
|
+
* const version = r.readUInt8();
|
|
9
|
+
* const length = r.readUInt16();
|
|
10
|
+
* const payload = r.readBytes(length);
|
|
5
11
|
*/
|
|
6
12
|
export declare class BufferReader {
|
|
7
13
|
private _buf;
|
|
8
14
|
private _pos;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new BufferReader.
|
|
17
|
+
*
|
|
18
|
+
* @param {Buffer} buf - Buffer to read from.
|
|
19
|
+
* @param {number} [offset=0] - Initial cursor position.
|
|
20
|
+
*/
|
|
9
21
|
constructor(buf: Buffer, offset?: number);
|
|
22
|
+
/** Current byte offset of the read cursor. */
|
|
10
23
|
get position(): number;
|
|
24
|
+
/** Number of bytes remaining after the current cursor position. */
|
|
11
25
|
get remaining(): number;
|
|
26
|
+
/** Total length of the underlying buffer. */
|
|
12
27
|
get length(): number;
|
|
28
|
+
/** The underlying `Buffer` instance. */
|
|
13
29
|
get buffer(): Buffer;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the next `length` bytes without advancing the cursor.
|
|
32
|
+
*
|
|
33
|
+
* @param {number} length - Number of bytes to peek at.
|
|
34
|
+
* @returns {Buffer} A view into the underlying buffer (not a copy).
|
|
35
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
36
|
+
*/
|
|
14
37
|
peek(length: number): Buffer;
|
|
38
|
+
/**
|
|
39
|
+
* Reads one unsigned 8-bit integer and advances the cursor by 1.
|
|
40
|
+
*
|
|
41
|
+
* @returns {number} Unsigned byte value (0–255).
|
|
42
|
+
* @throws {RangeError} If fewer than 1 byte remains.
|
|
43
|
+
*/
|
|
15
44
|
readUInt8(): number;
|
|
45
|
+
/**
|
|
46
|
+
* Reads one big-endian unsigned 16-bit integer and advances the cursor by 2.
|
|
47
|
+
*
|
|
48
|
+
* @returns {number} Unsigned 16-bit value (0–65 535).
|
|
49
|
+
* @throws {RangeError} If fewer than 2 bytes remain.
|
|
50
|
+
*/
|
|
16
51
|
readUInt16(): number;
|
|
52
|
+
/**
|
|
53
|
+
* Reads one big-endian unsigned 24-bit integer and advances the cursor by 3.
|
|
54
|
+
*
|
|
55
|
+
* @returns {number} Unsigned 24-bit value (0–16 777 215).
|
|
56
|
+
* @throws {RangeError} If fewer than 3 bytes remain.
|
|
57
|
+
*/
|
|
17
58
|
readUInt24(): number;
|
|
59
|
+
/**
|
|
60
|
+
* Reads one big-endian unsigned 32-bit integer and advances the cursor by 4.
|
|
61
|
+
*
|
|
62
|
+
* @returns {number} Unsigned 32-bit value (0–4 294 967 295).
|
|
63
|
+
* @throws {RangeError} If fewer than 4 bytes remain.
|
|
64
|
+
*/
|
|
18
65
|
readUInt32(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Reads `length` bytes into a new `Buffer` and advances the cursor.
|
|
68
|
+
*
|
|
69
|
+
* @param {number} length - Number of bytes to read.
|
|
70
|
+
* @returns {Buffer} Copy of the requested bytes.
|
|
71
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
72
|
+
*/
|
|
19
73
|
readBytes(length: number): Buffer;
|
|
20
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Reads a length-prefixed byte vector where the length is encoded as a
|
|
76
|
+
* one-byte (8-bit) unsigned integer immediately preceding the data.
|
|
77
|
+
*
|
|
78
|
+
* @returns {Buffer} The vector payload bytes.
|
|
79
|
+
* @throws {RangeError} If insufficient bytes remain.
|
|
80
|
+
*/
|
|
21
81
|
readVector8(): Buffer;
|
|
22
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* Reads a length-prefixed byte vector where the length is encoded as a
|
|
84
|
+
* big-endian two-byte (16-bit) unsigned integer immediately preceding the data.
|
|
85
|
+
*
|
|
86
|
+
* @returns {Buffer} The vector payload bytes.
|
|
87
|
+
* @throws {RangeError} If insufficient bytes remain.
|
|
88
|
+
*/
|
|
23
89
|
readVector16(): Buffer;
|
|
24
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* Reads a length-prefixed byte vector where the length is encoded as a
|
|
92
|
+
* big-endian three-byte (24-bit) unsigned integer immediately preceding the data.
|
|
93
|
+
*
|
|
94
|
+
* @returns {Buffer} The vector payload bytes.
|
|
95
|
+
* @throws {RangeError} If insufficient bytes remain.
|
|
96
|
+
*/
|
|
25
97
|
readVector24(): Buffer;
|
|
98
|
+
/**
|
|
99
|
+
* Advances the cursor by `length` bytes without returning the data.
|
|
100
|
+
*
|
|
101
|
+
* @param {number} length - Number of bytes to skip.
|
|
102
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
103
|
+
*/
|
|
26
104
|
skip(length: number): void;
|
|
105
|
+
/**
|
|
106
|
+
* Moves the cursor to an absolute byte position within the buffer.
|
|
107
|
+
*
|
|
108
|
+
* @param {number} position - Target byte offset (0 to `length` inclusive).
|
|
109
|
+
* @throws {RangeError} If `position` is negative or beyond the buffer length.
|
|
110
|
+
*/
|
|
27
111
|
seek(position: number): void;
|
|
28
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* Reads `length` bytes from the current position and returns a new
|
|
114
|
+
* `BufferReader` positioned at offset 0 within that sub-slice. The parent
|
|
115
|
+
* cursor advances by `length` bytes.
|
|
116
|
+
*
|
|
117
|
+
* @param {number} length - Byte count to slice into the sub-reader.
|
|
118
|
+
* @returns {BufferReader} Reader over the requested sub-slice.
|
|
119
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
120
|
+
*/
|
|
29
121
|
subReader(length: number): BufferReader;
|
|
30
122
|
private assertAvailable;
|
|
31
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buffer-reader.d.ts","sourceRoot":"","sources":["../../src/utils/buffer-reader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"buffer-reader.d.ts","sourceRoot":"","sources":["../../src/utils/buffer-reader.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IAErB;;;;;OAKG;gBACS,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU;IAK3C,8CAA8C;IAC9C,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,mEAAmE;IACnE,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,6CAA6C;IAC7C,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,wCAAwC;IACxC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;;;OAMG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAK5B;;;;;OAKG;IACH,SAAS,IAAI,MAAM;IAOnB;;;;;OAKG;IACH,UAAU,IAAI,MAAM;IAOpB;;;;;OAKG;IACH,UAAU,IAAI,MAAM;IASpB;;;;;OAKG;IACH,UAAU,IAAI,MAAM;IAOpB;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAOjC;;;;;;OAMG;IACH,WAAW,IAAI,MAAM;IAKrB;;;;;;OAMG;IACH,YAAY,IAAI,MAAM;IAKtB;;;;;;OAMG;IACH,YAAY,IAAI,MAAM;IAKtB;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK1B;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO5B;;;;;;;;OAQG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAOvC,OAAO,CAAC,eAAe;CAOxB"}
|
|
@@ -1,43 +1,84 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Stateful cursor for reading typed values from a `Buffer` in big-endian byte
|
|
3
|
+
* order. Advances an internal position pointer after every read so callers
|
|
4
|
+
* don't need to track offsets manually.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const r = new BufferReader(buf);
|
|
8
|
+
* const version = r.readUInt8();
|
|
9
|
+
* const length = r.readUInt16();
|
|
10
|
+
* const payload = r.readBytes(length);
|
|
5
11
|
*/
|
|
6
12
|
export class BufferReader {
|
|
7
13
|
_buf;
|
|
8
14
|
_pos;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new BufferReader.
|
|
17
|
+
*
|
|
18
|
+
* @param {Buffer} buf - Buffer to read from.
|
|
19
|
+
* @param {number} [offset=0] - Initial cursor position.
|
|
20
|
+
*/
|
|
9
21
|
constructor(buf, offset = 0) {
|
|
10
22
|
this._buf = buf;
|
|
11
23
|
this._pos = offset;
|
|
12
24
|
}
|
|
25
|
+
/** Current byte offset of the read cursor. */
|
|
13
26
|
get position() {
|
|
14
27
|
return this._pos;
|
|
15
28
|
}
|
|
29
|
+
/** Number of bytes remaining after the current cursor position. */
|
|
16
30
|
get remaining() {
|
|
17
31
|
return this._buf.length - this._pos;
|
|
18
32
|
}
|
|
33
|
+
/** Total length of the underlying buffer. */
|
|
19
34
|
get length() {
|
|
20
35
|
return this._buf.length;
|
|
21
36
|
}
|
|
37
|
+
/** The underlying `Buffer` instance. */
|
|
22
38
|
get buffer() {
|
|
23
39
|
return this._buf;
|
|
24
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns the next `length` bytes without advancing the cursor.
|
|
43
|
+
*
|
|
44
|
+
* @param {number} length - Number of bytes to peek at.
|
|
45
|
+
* @returns {Buffer} A view into the underlying buffer (not a copy).
|
|
46
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
47
|
+
*/
|
|
25
48
|
peek(length) {
|
|
26
49
|
this.assertAvailable(length);
|
|
27
50
|
return this._buf.subarray(this._pos, this._pos + length);
|
|
28
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Reads one unsigned 8-bit integer and advances the cursor by 1.
|
|
54
|
+
*
|
|
55
|
+
* @returns {number} Unsigned byte value (0–255).
|
|
56
|
+
* @throws {RangeError} If fewer than 1 byte remains.
|
|
57
|
+
*/
|
|
29
58
|
readUInt8() {
|
|
30
59
|
this.assertAvailable(1);
|
|
31
60
|
const v = this._buf[this._pos];
|
|
32
61
|
this._pos += 1;
|
|
33
62
|
return v;
|
|
34
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Reads one big-endian unsigned 16-bit integer and advances the cursor by 2.
|
|
66
|
+
*
|
|
67
|
+
* @returns {number} Unsigned 16-bit value (0–65 535).
|
|
68
|
+
* @throws {RangeError} If fewer than 2 bytes remain.
|
|
69
|
+
*/
|
|
35
70
|
readUInt16() {
|
|
36
71
|
this.assertAvailable(2);
|
|
37
72
|
const v = this._buf.readUInt16BE(this._pos);
|
|
38
73
|
this._pos += 2;
|
|
39
74
|
return v;
|
|
40
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Reads one big-endian unsigned 24-bit integer and advances the cursor by 3.
|
|
78
|
+
*
|
|
79
|
+
* @returns {number} Unsigned 24-bit value (0–16 777 215).
|
|
80
|
+
* @throws {RangeError} If fewer than 3 bytes remain.
|
|
81
|
+
*/
|
|
41
82
|
readUInt24() {
|
|
42
83
|
this.assertAvailable(3);
|
|
43
84
|
const b0 = this._buf[this._pos];
|
|
@@ -46,44 +87,95 @@ export class BufferReader {
|
|
|
46
87
|
this._pos += 3;
|
|
47
88
|
return (b0 << 16) | (b1 << 8) | b2;
|
|
48
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Reads one big-endian unsigned 32-bit integer and advances the cursor by 4.
|
|
92
|
+
*
|
|
93
|
+
* @returns {number} Unsigned 32-bit value (0–4 294 967 295).
|
|
94
|
+
* @throws {RangeError} If fewer than 4 bytes remain.
|
|
95
|
+
*/
|
|
49
96
|
readUInt32() {
|
|
50
97
|
this.assertAvailable(4);
|
|
51
98
|
const v = this._buf.readUInt32BE(this._pos);
|
|
52
99
|
this._pos += 4;
|
|
53
100
|
return v;
|
|
54
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Reads `length` bytes into a new `Buffer` and advances the cursor.
|
|
104
|
+
*
|
|
105
|
+
* @param {number} length - Number of bytes to read.
|
|
106
|
+
* @returns {Buffer} Copy of the requested bytes.
|
|
107
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
108
|
+
*/
|
|
55
109
|
readBytes(length) {
|
|
56
110
|
this.assertAvailable(length);
|
|
57
111
|
const slice = Buffer.from(this._buf.subarray(this._pos, this._pos + length));
|
|
58
112
|
this._pos += length;
|
|
59
113
|
return slice;
|
|
60
114
|
}
|
|
61
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Reads a length-prefixed byte vector where the length is encoded as a
|
|
117
|
+
* one-byte (8-bit) unsigned integer immediately preceding the data.
|
|
118
|
+
*
|
|
119
|
+
* @returns {Buffer} The vector payload bytes.
|
|
120
|
+
* @throws {RangeError} If insufficient bytes remain.
|
|
121
|
+
*/
|
|
62
122
|
readVector8() {
|
|
63
123
|
const len = this.readUInt8();
|
|
64
124
|
return this.readBytes(len);
|
|
65
125
|
}
|
|
66
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Reads a length-prefixed byte vector where the length is encoded as a
|
|
128
|
+
* big-endian two-byte (16-bit) unsigned integer immediately preceding the data.
|
|
129
|
+
*
|
|
130
|
+
* @returns {Buffer} The vector payload bytes.
|
|
131
|
+
* @throws {RangeError} If insufficient bytes remain.
|
|
132
|
+
*/
|
|
67
133
|
readVector16() {
|
|
68
134
|
const len = this.readUInt16();
|
|
69
135
|
return this.readBytes(len);
|
|
70
136
|
}
|
|
71
|
-
/**
|
|
137
|
+
/**
|
|
138
|
+
* Reads a length-prefixed byte vector where the length is encoded as a
|
|
139
|
+
* big-endian three-byte (24-bit) unsigned integer immediately preceding the data.
|
|
140
|
+
*
|
|
141
|
+
* @returns {Buffer} The vector payload bytes.
|
|
142
|
+
* @throws {RangeError} If insufficient bytes remain.
|
|
143
|
+
*/
|
|
72
144
|
readVector24() {
|
|
73
145
|
const len = this.readUInt24();
|
|
74
146
|
return this.readBytes(len);
|
|
75
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Advances the cursor by `length` bytes without returning the data.
|
|
150
|
+
*
|
|
151
|
+
* @param {number} length - Number of bytes to skip.
|
|
152
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
153
|
+
*/
|
|
76
154
|
skip(length) {
|
|
77
155
|
this.assertAvailable(length);
|
|
78
156
|
this._pos += length;
|
|
79
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Moves the cursor to an absolute byte position within the buffer.
|
|
160
|
+
*
|
|
161
|
+
* @param {number} position - Target byte offset (0 to `length` inclusive).
|
|
162
|
+
* @throws {RangeError} If `position` is negative or beyond the buffer length.
|
|
163
|
+
*/
|
|
80
164
|
seek(position) {
|
|
81
165
|
if (position < 0 || position > this._buf.length) {
|
|
82
166
|
throw new RangeError(`Seek position ${position} out of bounds [0, ${this._buf.length}]`);
|
|
83
167
|
}
|
|
84
168
|
this._pos = position;
|
|
85
169
|
}
|
|
86
|
-
/**
|
|
170
|
+
/**
|
|
171
|
+
* Reads `length` bytes from the current position and returns a new
|
|
172
|
+
* `BufferReader` positioned at offset 0 within that sub-slice. The parent
|
|
173
|
+
* cursor advances by `length` bytes.
|
|
174
|
+
*
|
|
175
|
+
* @param {number} length - Byte count to slice into the sub-reader.
|
|
176
|
+
* @returns {BufferReader} Reader over the requested sub-slice.
|
|
177
|
+
* @throws {RangeError} If `length` bytes are not available.
|
|
178
|
+
*/
|
|
87
179
|
subReader(length) {
|
|
88
180
|
this.assertAvailable(length);
|
|
89
181
|
const sub = new BufferReader(this._buf.subarray(this._pos, this._pos + length));
|