advanced-tls-client 3.0.2 → 3.0.5

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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { EventEmitter } from 'events';
1
2
  import { Readable, PassThrough } from 'stream';
2
3
  interface TLSFingerprint {
3
4
  cipherSuites: number[];
@@ -119,13 +120,34 @@ interface RequestOptions {
119
120
  content_type?: string;
120
121
  uri_modifier?: Function;
121
122
  }
123
+ interface Response extends EventEmitter {
124
+ statusCode: number;
125
+ headers: Record<string, string | string[]>;
126
+ body: Buffer | Readable | any;
127
+ text?: string;
128
+ json?: any;
129
+ timing: {
130
+ socket: number;
131
+ lookup: number;
132
+ connect: number;
133
+ secureConnect: number;
134
+ response: number;
135
+ end: number;
136
+ total: number;
137
+ };
138
+ fingerprints: {
139
+ ja3: string;
140
+ ja3Hash: string;
141
+ akamai: string;
142
+ };
143
+ bytes?: number;
144
+ raw?: Buffer;
145
+ cookies?: Record<string, string>;
146
+ parser?: string;
147
+ }
122
148
  declare class ProfileRegistry {
123
149
  private static getGrease;
124
150
  static chromeMobile143Android(): ChromeProfile;
125
- static chrome133PSK(): ChromeProfile;
126
- static chrome133(): ChromeProfile;
127
- static firefox117(): ChromeProfile;
128
- static safariIOS18(): ChromeProfile;
129
151
  static get(name: string): ChromeProfile;
130
152
  static get latest(): ChromeProfile;
131
153
  static get latestMobile(): ChromeProfile;
@@ -140,7 +162,8 @@ declare class AdvancedTLSClient {
140
162
  private defaults;
141
163
  constructor(profileName?: string);
142
164
  private setup;
143
- request(uri: string, data?: any, options?: RequestOptions, callback?: Function): Promise<FullResponse | PassThrough>;
165
+ private isRequestOptions;
166
+ request(uri: string, dataOrOptions?: any, optionsOrCallback?: RequestOptions | ((err: any, res?: Response) => void), callback?: (err: any, res?: Response) => void): Promise<FullResponse | PassThrough>;
144
167
  private generateJA3;
145
168
  private buildMultipart;
146
169
  private generateMultipart;
package/dist/index.js CHANGED
@@ -177,438 +177,11 @@ class ProfileRegistry {
177
177
  priority: 'u=0, i'
178
178
  };
179
179
  }
180
- static chrome133PSK() {
181
- const grease1 = this.getGrease();
182
- const grease2 = this.getGrease();
183
- const grease3 = this.getGrease();
184
- const grease4 = this.getGrease();
185
- return {
186
- name: 'chrome_133_psk',
187
- version: '133.0.0.0',
188
- tls: {
189
- cipherSuites: [
190
- grease1,
191
- 4865,
192
- 4866,
193
- 4867,
194
- 49195,
195
- 49199,
196
- 49196,
197
- 49200,
198
- 52393,
199
- 52392,
200
- 49171,
201
- 49172,
202
- 156,
203
- 157,
204
- 47,
205
- 53
206
- ],
207
- extensions: [
208
- grease2,
209
- 0,
210
- 23,
211
- 65281,
212
- 10,
213
- 11,
214
- 35,
215
- 16,
216
- 5,
217
- 13,
218
- 18,
219
- 51,
220
- 45,
221
- 43,
222
- 27,
223
- 21,
224
- grease3
225
- ],
226
- supportedGroups: [
227
- grease4,
228
- 25497,
229
- 29,
230
- 23,
231
- 24
232
- ],
233
- signatureAlgorithms: [
234
- 1027,
235
- 2052,
236
- 1025,
237
- 1283,
238
- 2053,
239
- 1281,
240
- 2054,
241
- 1537
242
- ],
243
- supportedVersions: [
244
- grease2,
245
- 772,
246
- 771
247
- ],
248
- ecPointFormats: [0],
249
- alpnProtocols: ['h2', 'http/1.1'],
250
- pskKeyExchangeModes: [1],
251
- compressionMethods: [0],
252
- grease: true,
253
- recordSizeLimit: 16385
254
- },
255
- http2: {
256
- windowUpdate: 15663105,
257
- headerTableSize: 65536,
258
- enablePush: 0,
259
- initialWindowSize: 6291456,
260
- maxFrameSize: 16384,
261
- maxHeaderListSize: 262144,
262
- settingsOrder: [1, 2, 4, 6],
263
- connectionPreface: Buffer.from('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'),
264
- priorityFrames: [
265
- {
266
- streamId: 0,
267
- weight: 256,
268
- dependency: 0,
269
- exclusive: true
270
- }
271
- ],
272
- pseudoHeaderOrder: [':method', ':authority', ':scheme', ':path'],
273
- headerOrder: [
274
- 'cache-control',
275
- 'sec-ch-ua',
276
- 'sec-ch-ua-mobile',
277
- 'sec-ch-ua-platform',
278
- 'upgrade-insecure-requests',
279
- 'user-agent',
280
- 'accept',
281
- 'sec-fetch-site',
282
- 'sec-fetch-mode',
283
- 'sec-fetch-user',
284
- 'sec-fetch-dest',
285
- 'accept-encoding',
286
- 'accept-language'
287
- ]
288
- },
289
- userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
290
- secChUa: '"Google Chrome";v="133", "Chromium";v="133", "Not_A Brand";v="24"',
291
- secChUaPlatform: '"Windows"',
292
- secChUaMobile: '?0',
293
- secFetchSite: 'none',
294
- secFetchMode: 'navigate',
295
- secFetchDest: 'document'
296
- };
297
- }
298
- static chrome133() {
299
- const grease1 = this.getGrease();
300
- const grease2 = this.getGrease();
301
- const grease3 = this.getGrease();
302
- const grease4 = this.getGrease();
303
- return {
304
- name: 'chrome_133',
305
- version: '133.0.0.0',
306
- tls: {
307
- cipherSuites: [
308
- grease1,
309
- 4865,
310
- 4866,
311
- 4867,
312
- 49195,
313
- 49199,
314
- 49196,
315
- 49200,
316
- 52393,
317
- 52392,
318
- 49171,
319
- 49172,
320
- 156,
321
- 157,
322
- 47,
323
- 53
324
- ],
325
- extensions: [
326
- grease2,
327
- 0,
328
- 23,
329
- 65281,
330
- 10,
331
- 11,
332
- 35,
333
- 16,
334
- 5,
335
- 13,
336
- 18,
337
- 51,
338
- 45,
339
- 43,
340
- 27,
341
- 21,
342
- grease3
343
- ],
344
- supportedGroups: [
345
- grease4,
346
- 25497,
347
- 29,
348
- 23,
349
- 24
350
- ],
351
- signatureAlgorithms: [
352
- 1027,
353
- 2052,
354
- 1025,
355
- 1283,
356
- 2053,
357
- 1281,
358
- 2054,
359
- 1537
360
- ],
361
- supportedVersions: [
362
- grease2,
363
- 772,
364
- 771
365
- ],
366
- ecPointFormats: [0],
367
- alpnProtocols: ['h2', 'http/1.1'],
368
- pskKeyExchangeModes: [1],
369
- compressionMethods: [0],
370
- grease: true,
371
- recordSizeLimit: 16385
372
- },
373
- http2: {
374
- windowUpdate: 15663105,
375
- headerTableSize: 65536,
376
- enablePush: 0,
377
- initialWindowSize: 6291456,
378
- maxFrameSize: 16384,
379
- maxHeaderListSize: 262144,
380
- settingsOrder: [1, 2, 4, 6],
381
- connectionPreface: Buffer.from('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'),
382
- priorityFrames: [
383
- {
384
- streamId: 0,
385
- weight: 256,
386
- dependency: 0,
387
- exclusive: true
388
- }
389
- ],
390
- pseudoHeaderOrder: [':method', ':authority', ':scheme', ':path'],
391
- headerOrder: [
392
- 'cache-control',
393
- 'sec-ch-ua',
394
- 'sec-ch-ua-mobile',
395
- 'sec-ch-ua-platform',
396
- 'upgrade-insecure-requests',
397
- 'user-agent',
398
- 'accept',
399
- 'sec-fetch-site',
400
- 'sec-fetch-mode',
401
- 'sec-fetch-user',
402
- 'sec-fetch-dest',
403
- 'accept-encoding',
404
- 'accept-language'
405
- ]
406
- },
407
- userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
408
- secChUa: '"Google Chrome";v="133", "Chromium";v="133", "Not_A Brand";v="24"',
409
- secChUaPlatform: '"Windows"',
410
- secChUaMobile: '?0',
411
- secFetchSite: 'none',
412
- secFetchMode: 'navigate',
413
- secFetchDest: 'document'
414
- };
415
- }
416
- static firefox117() {
417
- return {
418
- name: 'firefox_117',
419
- version: '117.0',
420
- tls: {
421
- cipherSuites: [
422
- 4865,
423
- 4867,
424
- 4866,
425
- 49195,
426
- 49199,
427
- 52393,
428
- 52392,
429
- 49196,
430
- 49200,
431
- 159,
432
- 158,
433
- 49161,
434
- 49162,
435
- 156,
436
- 157,
437
- 47,
438
- 53
439
- ],
440
- extensions: [0, 23, 65281, 10, 11, 35, 16, 5, 34, 51, 43, 13, 45, 28, 21],
441
- supportedGroups: [
442
- 29,
443
- 23,
444
- 24,
445
- 25,
446
- 256,
447
- 257
448
- ],
449
- signatureAlgorithms: [
450
- 1027,
451
- 1283,
452
- 1539,
453
- 2052,
454
- 2053,
455
- 2054,
456
- 1025,
457
- 1281,
458
- 1537,
459
- 513,
460
- 515
461
- ],
462
- supportedVersions: [
463
- 772,
464
- 771
465
- ],
466
- ecPointFormats: [0],
467
- alpnProtocols: ['h2', 'http/1.1'],
468
- pskKeyExchangeModes: [1],
469
- compressionMethods: [0],
470
- grease: false
471
- },
472
- http2: {
473
- windowUpdate: 12517377,
474
- headerTableSize: 65536,
475
- enablePush: 0,
476
- initialWindowSize: 131072,
477
- maxFrameSize: 16384,
478
- settingsOrder: [1, 4, 5],
479
- connectionPreface: Buffer.from('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'),
480
- priorityFrames: [
481
- { streamId: 3, weight: 200, dependency: 0, exclusive: false },
482
- { streamId: 5, weight: 100, dependency: 0, exclusive: false },
483
- { streamId: 7, weight: 0, dependency: 0, exclusive: false },
484
- { streamId: 9, weight: 0, dependency: 7, exclusive: false },
485
- { streamId: 11, weight: 0, dependency: 3, exclusive: false },
486
- { streamId: 13, weight: 240, dependency: 0, exclusive: false }
487
- ],
488
- pseudoHeaderOrder: [':method', ':path', ':authority', ':scheme'],
489
- headerPriority: { streamDep: 13, exclusive: false, weight: 41 },
490
- headerOrder: []
491
- },
492
- userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:117.0) Gecko/20100101 Firefox/117.0',
493
- secChUa: '',
494
- secChUaPlatform: '',
495
- secChUaMobile: '',
496
- secFetchSite: 'none',
497
- secFetchMode: 'navigate',
498
- secFetchDest: 'document'
499
- };
500
- }
501
- static safariIOS18() {
502
- const grease1 = this.getGrease();
503
- const grease2 = this.getGrease();
504
- return {
505
- name: 'safari_ios_18_0',
506
- version: '18.0',
507
- tls: {
508
- cipherSuites: [
509
- grease1,
510
- 4865,
511
- 4866,
512
- 4867,
513
- 49196,
514
- 49195,
515
- 52393,
516
- 49200,
517
- 49199,
518
- 52392,
519
- 159,
520
- 158,
521
- 49162,
522
- 49161,
523
- 157,
524
- 156,
525
- 53,
526
- 47,
527
- 49188,
528
- 49187,
529
- 60
530
- ],
531
- extensions: [
532
- grease2,
533
- 0,
534
- 23,
535
- 65281,
536
- 10,
537
- 11,
538
- 16,
539
- 5,
540
- 13,
541
- 18,
542
- 51,
543
- 45,
544
- 43,
545
- 21
546
- ],
547
- supportedGroups: [
548
- 29,
549
- 23,
550
- 24,
551
- 25
552
- ],
553
- signatureAlgorithms: [
554
- 1027,
555
- 2052,
556
- 1025,
557
- 1283,
558
- 513,
559
- 2053,
560
- 2053,
561
- 1281,
562
- 2054,
563
- 1537,
564
- 515
565
- ],
566
- supportedVersions: [
567
- 772,
568
- 771,
569
- 770,
570
- 769
571
- ],
572
- ecPointFormats: [0],
573
- alpnProtocols: ['h2', 'http/1.1'],
574
- pskKeyExchangeModes: [1],
575
- compressionMethods: [0],
576
- grease: true
577
- },
578
- http2: {
579
- windowUpdate: 10420225,
580
- headerTableSize: 4096,
581
- enablePush: 0,
582
- maxConcurrentStreams: 100,
583
- initialWindowSize: 2097152,
584
- maxFrameSize: 16384,
585
- settingsOrder: [2, 3, 4, 8, 9],
586
- connectionPreface: Buffer.from('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'),
587
- priorityFrames: [],
588
- pseudoHeaderOrder: [':method', ':scheme', ':authority', ':path'],
589
- headerOrder: []
590
- },
591
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1',
592
- secChUa: '',
593
- secChUaPlatform: '',
594
- secChUaMobile: '?1',
595
- secFetchSite: 'none',
596
- secFetchMode: 'navigate',
597
- secFetchDest: 'document'
598
- };
599
- }
600
180
  static get(name) {
601
- switch (name.toLowerCase()) {
602
- case 'chrome_mobile_143_android': return this.chromeMobile143Android();
603
- case 'chrome_133_psk': return this.chrome133PSK();
604
- case 'chrome_133': return this.chrome133();
605
- case 'firefox_117': return this.firefox117();
606
- case 'safari_ios_18_0': return this.safariIOS18();
607
- default: return this.chrome133();
608
- }
181
+ return this.chromeMobile143Android();
609
182
  }
610
183
  static get latest() {
611
- return this.chrome133();
184
+ return this.chromeMobile143Android();
612
185
  }
613
186
  static get latestMobile() {
614
187
  return this.chromeMobile143Android();
@@ -747,13 +320,15 @@ class UnifiedClientManager extends events_1.EventEmitter {
747
320
  }
748
321
  }
749
322
  async requestHttp2(path, options, timingStart, headers, post_data, out, callback) {
323
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`;
750
324
  const reqHeaders = {
751
325
  ':method': options.method?.toUpperCase() || 'GET',
752
326
  ':authority': this.hostname,
753
327
  ':scheme': 'https',
754
- ':path': path,
328
+ ':path': normalizedPath,
755
329
  ...headers
756
330
  };
331
+ console.log('Sending HTTP/2 Request Headers:', reqHeaders);
757
332
  const stream = this.http2Client.request(reqHeaders);
758
333
  const response = new events_1.EventEmitter();
759
334
  response.timing = { socket: timingStart, lookup: 0, connect: 0, secureConnect: 0, response: 0, end: 0, total: 0 };
@@ -1133,7 +708,7 @@ class AdvancedTLSClient {
1133
708
  follow_if_same_location: false,
1134
709
  use_proxy_from_env_var: true
1135
710
  };
1136
- this.profile = ProfileRegistry.get(profileName || 'chrome_133');
711
+ this.profile = ProfileRegistry.get(profileName || 'chrome_mobile_143_android');
1137
712
  this.cleanupInterval = setInterval(() => {
1138
713
  const now = Date.now();
1139
714
  for (const [key, session] of this.sessionCache) {
@@ -1147,7 +722,7 @@ class AdvancedTLSClient {
1147
722
  }
1148
723
  setup(uri, options) {
1149
724
  const config = {
1150
- headers: { ...options.headers },
725
+ headers: {},
1151
726
  proxy: options.proxy || this.defaults.proxy,
1152
727
  decompress: options.decompress !== undefined ? options.decompress : true
1153
728
  };
@@ -1165,12 +740,46 @@ class AdvancedTLSClient {
1165
740
  config.headers['upgrade-insecure-requests'] = this.profile.upgradeInsecureRequests;
1166
741
  if (this.profile.priority)
1167
742
  config.headers['priority'] = this.profile.priority;
743
+ if (options.headers) {
744
+ Object.assign(config.headers, options.headers);
745
+ }
1168
746
  return config;
1169
747
  }
1170
- async request(uri, data, options = {}, callback) {
1171
- if (typeof options === 'function') {
1172
- callback = options;
1173
- options = {};
748
+ isRequestOptions(obj) {
749
+ if (typeof obj !== 'object' || obj === null)
750
+ return false;
751
+ if (Buffer.isBuffer(obj) || obj instanceof stream_1.Readable)
752
+ return false;
753
+ const optionKeys = ['method', 'headers', 'proxy', 'decompress', 'stream', 'multipart', 'boundary', 'json', 'timeout'];
754
+ const keys = Object.keys(obj);
755
+ return keys.some(key => optionKeys.includes(key));
756
+ }
757
+ async request(uri, dataOrOptions, optionsOrCallback, callback) {
758
+ let data = null;
759
+ let options = {};
760
+ let cb = undefined;
761
+ if (typeof dataOrOptions === 'function') {
762
+ cb = dataOrOptions;
763
+ }
764
+ else if (dataOrOptions !== undefined && dataOrOptions !== null) {
765
+ if (this.isRequestOptions(dataOrOptions)) {
766
+ options = dataOrOptions;
767
+ }
768
+ else {
769
+ data = dataOrOptions;
770
+ }
771
+ }
772
+ if (typeof optionsOrCallback === 'function') {
773
+ cb = optionsOrCallback;
774
+ }
775
+ else if (optionsOrCallback !== undefined && optionsOrCallback !== null) {
776
+ options = optionsOrCallback;
777
+ }
778
+ if (callback !== undefined) {
779
+ cb = callback;
780
+ }
781
+ if (data && typeof data !== 'object' && !Buffer.isBuffer(data) && !(data instanceof stream_1.Readable)) {
782
+ throw new Error('Invalid data type');
1174
783
  }
1175
784
  const parsed = new url.URL(uri);
1176
785
  const hostname = parsed.hostname;
@@ -1197,7 +806,10 @@ class AdvancedTLSClient {
1197
806
  session.lastUsed = Date.now();
1198
807
  const config = this.setup(uri, options);
1199
808
  let post_data = null;
1200
- let json = options.json || (options.json !== false && config.headers['content-type']?.includes('application/json'));
809
+ let json = options.json !== undefined ? options.json : false;
810
+ if (json === undefined && config.headers['content-type']?.includes('application/json')) {
811
+ json = true;
812
+ }
1201
813
  if (data) {
1202
814
  if (options.multipart) {
1203
815
  const boundary = options.boundary || this.defaults.boundary;
@@ -1232,11 +844,10 @@ class AdvancedTLSClient {
1232
844
  session.clientManager.request(path, options, startTime, config.headers, post_data, out);
1233
845
  return out;
1234
846
  }
1235
- if (callback) {
1236
- const typedCallback = callback;
1237
- session.clientManager.request(path, options, startTime, config.headers, post_data, out, typedCallback).catch(err => {
1238
- if (typedCallback)
1239
- typedCallback(err);
847
+ if (cb) {
848
+ session.clientManager.request(path, options, startTime, config.headers, post_data, out, cb).catch(err => {
849
+ if (cb)
850
+ cb(err);
1240
851
  });
1241
852
  return out;
1242
853
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "advanced-tls-client",
3
- "version": "3.0.2",
3
+ "version": "3.0.5",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {