httpcloak 1.6.1-beta.2 → 1.6.1
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 +47 -36
- package/lib/index.d.ts +46 -10
- package/lib/index.js +126 -33
- package/npm/darwin-arm64/package.json +1 -1
- package/npm/darwin-x64/package.json +1 -1
- package/npm/linux-arm64/package.json +1 -1
- package/npm/linux-x64/package.json +1 -1
- package/npm/win32-arm64/package.json +1 -1
- package/npm/win32-x64/package.json +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npm install httpcloak
|
|
|
16
16
|
const { Session } = require("httpcloak");
|
|
17
17
|
|
|
18
18
|
async function main() {
|
|
19
|
-
const session = new Session({ preset: "chrome-
|
|
19
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
20
20
|
|
|
21
21
|
try {
|
|
22
22
|
// GET request
|
|
@@ -53,7 +53,7 @@ main();
|
|
|
53
53
|
```javascript
|
|
54
54
|
import { Session } from "httpcloak";
|
|
55
55
|
|
|
56
|
-
const session = new Session({ preset: "chrome-
|
|
56
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
57
57
|
|
|
58
58
|
const response = await session.get("https://example.com");
|
|
59
59
|
console.log(response.text);
|
|
@@ -66,7 +66,7 @@ session.close();
|
|
|
66
66
|
```javascript
|
|
67
67
|
const { Session } = require("httpcloak");
|
|
68
68
|
|
|
69
|
-
const session = new Session({ preset: "chrome-
|
|
69
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
70
70
|
|
|
71
71
|
// Sync GET
|
|
72
72
|
const response = session.getSync("https://example.com");
|
|
@@ -86,7 +86,7 @@ session.close();
|
|
|
86
86
|
```javascript
|
|
87
87
|
const { Session } = require("httpcloak");
|
|
88
88
|
|
|
89
|
-
const session = new Session({ preset: "chrome-
|
|
89
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
90
90
|
|
|
91
91
|
// GET with callback
|
|
92
92
|
session.getCb("https://example.com", (err, response) => {
|
|
@@ -121,7 +121,7 @@ const { Session } = require("httpcloak");
|
|
|
121
121
|
const fs = require("fs");
|
|
122
122
|
|
|
123
123
|
async function downloadFile() {
|
|
124
|
-
const session = new Session({ preset: "chrome-
|
|
124
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
125
125
|
|
|
126
126
|
try {
|
|
127
127
|
// Start streaming request
|
|
@@ -158,7 +158,7 @@ downloadFile();
|
|
|
158
158
|
```javascript
|
|
159
159
|
const { Session } = require("httpcloak");
|
|
160
160
|
|
|
161
|
-
const session = new Session({ preset: "chrome-
|
|
161
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
162
162
|
|
|
163
163
|
// Stream GET
|
|
164
164
|
const getStream = session.getStream("https://example.com/data");
|
|
@@ -195,19 +195,19 @@ const { Session } = require("httpcloak");
|
|
|
195
195
|
|
|
196
196
|
// Basic HTTP proxy
|
|
197
197
|
const session = new Session({
|
|
198
|
-
preset: "chrome-
|
|
198
|
+
preset: "chrome-latest",
|
|
199
199
|
proxy: "http://host:port",
|
|
200
200
|
});
|
|
201
201
|
|
|
202
202
|
// With authentication
|
|
203
203
|
const sessionAuth = new Session({
|
|
204
|
-
preset: "chrome-
|
|
204
|
+
preset: "chrome-latest",
|
|
205
205
|
proxy: "http://user:pass@host:port",
|
|
206
206
|
});
|
|
207
207
|
|
|
208
208
|
// HTTPS proxy
|
|
209
209
|
const sessionHttps = new Session({
|
|
210
|
-
preset: "chrome-
|
|
210
|
+
preset: "chrome-latest",
|
|
211
211
|
proxy: "https://user:pass@host:port",
|
|
212
212
|
});
|
|
213
213
|
```
|
|
@@ -219,13 +219,13 @@ const { Session } = require("httpcloak");
|
|
|
219
219
|
|
|
220
220
|
// SOCKS5 proxy (with DNS resolution on proxy)
|
|
221
221
|
const session = new Session({
|
|
222
|
-
preset: "chrome-
|
|
222
|
+
preset: "chrome-latest",
|
|
223
223
|
proxy: "socks5h://host:port",
|
|
224
224
|
});
|
|
225
225
|
|
|
226
226
|
// With authentication
|
|
227
227
|
const sessionAuth = new Session({
|
|
228
|
-
preset: "chrome-
|
|
228
|
+
preset: "chrome-latest",
|
|
229
229
|
proxy: "socks5h://user:pass@host:port",
|
|
230
230
|
});
|
|
231
231
|
|
|
@@ -242,7 +242,7 @@ const { Session } = require("httpcloak");
|
|
|
242
242
|
|
|
243
243
|
// MASQUE proxy (auto-detected for known providers like Bright Data)
|
|
244
244
|
const session = new Session({
|
|
245
|
-
preset: "chrome-
|
|
245
|
+
preset: "chrome-latest",
|
|
246
246
|
proxy: "https://user:pass@brd.superproxy.io:10001",
|
|
247
247
|
});
|
|
248
248
|
|
|
@@ -258,7 +258,7 @@ Use different proxies for TCP (HTTP/1.1, HTTP/2) and UDP (HTTP/3) traffic:
|
|
|
258
258
|
const { Session } = require("httpcloak");
|
|
259
259
|
|
|
260
260
|
const session = new Session({
|
|
261
|
-
preset: "chrome-
|
|
261
|
+
preset: "chrome-latest",
|
|
262
262
|
tcpProxy: "http://tcp-proxy:port", // For HTTP/1.1, HTTP/2
|
|
263
263
|
udpProxy: "https://masque-proxy:port", // For HTTP/3
|
|
264
264
|
});
|
|
@@ -275,7 +275,7 @@ const { Session } = require("httpcloak");
|
|
|
275
275
|
|
|
276
276
|
// Enable ECH for Cloudflare domains
|
|
277
277
|
const session = new Session({
|
|
278
|
-
preset: "chrome-
|
|
278
|
+
preset: "chrome-latest",
|
|
279
279
|
echConfigDomain: "cloudflare-ech.com",
|
|
280
280
|
});
|
|
281
281
|
|
|
@@ -293,7 +293,7 @@ const { Session } = require("httpcloak");
|
|
|
293
293
|
|
|
294
294
|
// Connect to example.com's IP but request www.cloudflare.com
|
|
295
295
|
const session = new Session({
|
|
296
|
-
preset: "chrome-
|
|
296
|
+
preset: "chrome-latest",
|
|
297
297
|
connectTo: { "www.cloudflare.com": "example.com" },
|
|
298
298
|
});
|
|
299
299
|
|
|
@@ -308,7 +308,7 @@ Get HTTP/3 with encrypted SNI through a SOCKS5 proxy:
|
|
|
308
308
|
const { Session } = require("httpcloak");
|
|
309
309
|
|
|
310
310
|
const session = new Session({
|
|
311
|
-
preset: "chrome-
|
|
311
|
+
preset: "chrome-latest",
|
|
312
312
|
proxy: "socks5h://user:pass@host:port",
|
|
313
313
|
echConfigDomain: "cloudflare-ech.com",
|
|
314
314
|
});
|
|
@@ -324,18 +324,31 @@ const { Session } = require("httpcloak");
|
|
|
324
324
|
|
|
325
325
|
const session = new Session();
|
|
326
326
|
|
|
327
|
-
// Set a cookie
|
|
327
|
+
// Set a simple cookie (global, sent to all domains)
|
|
328
328
|
session.setCookie("session_id", "abc123");
|
|
329
329
|
|
|
330
|
-
//
|
|
330
|
+
// Set a domain-scoped cookie with full metadata
|
|
331
|
+
session.setCookie("auth", "token", {
|
|
332
|
+
domain: ".example.com",
|
|
333
|
+
path: "/",
|
|
334
|
+
secure: true,
|
|
335
|
+
httpOnly: true,
|
|
336
|
+
sameSite: "Lax",
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// Get all cookies (returns Cookie[] with full metadata)
|
|
331
340
|
const cookies = session.getCookies();
|
|
332
|
-
|
|
341
|
+
for (const cookie of cookies) {
|
|
342
|
+
console.log(`${cookie.name}=${cookie.value} (domain: ${cookie.domain})`);
|
|
343
|
+
}
|
|
333
344
|
|
|
334
|
-
//
|
|
335
|
-
|
|
345
|
+
// Get a specific cookie by name (returns Cookie or null)
|
|
346
|
+
const cookie = session.getCookie("session_id");
|
|
347
|
+
if (cookie) console.log(cookie.value);
|
|
336
348
|
|
|
337
|
-
// Delete a cookie
|
|
349
|
+
// Delete a cookie (omit domain to delete from all domains)
|
|
338
350
|
session.deleteCookie("session_id");
|
|
351
|
+
session.deleteCookie("auth", ".example.com"); // delete from specific domain
|
|
339
352
|
|
|
340
353
|
// Clear all cookies
|
|
341
354
|
session.clearCookies();
|
|
@@ -349,7 +362,7 @@ session.close();
|
|
|
349
362
|
const { Session } = require("httpcloak");
|
|
350
363
|
|
|
351
364
|
const session = new Session({
|
|
352
|
-
preset: "chrome-
|
|
365
|
+
preset: "chrome-latest", // Browser fingerprint preset
|
|
353
366
|
proxy: null, // Proxy URL
|
|
354
367
|
tcpProxy: null, // Separate TCP proxy
|
|
355
368
|
udpProxy: null, // Separate UDP proxy (MASQUE)
|
|
@@ -371,8 +384,8 @@ const session = new Session({
|
|
|
371
384
|
const { availablePresets } = require("httpcloak");
|
|
372
385
|
|
|
373
386
|
console.log(availablePresets());
|
|
374
|
-
// ['chrome-145', 'chrome-144', 'chrome-143', 'chrome-141', 'chrome-133',
|
|
375
|
-
// 'firefox-133', 'safari-18', 'chrome-
|
|
387
|
+
// ['chrome-146', 'chrome-145', 'chrome-144', 'chrome-143', 'chrome-141', 'chrome-133',
|
|
388
|
+
// 'firefox-133', 'safari-18', 'chrome-146-ios', ...]
|
|
376
389
|
```
|
|
377
390
|
|
|
378
391
|
## Response Object
|
|
@@ -428,7 +441,7 @@ stream.close();
|
|
|
428
441
|
```javascript
|
|
429
442
|
const { Session } = require("httpcloak");
|
|
430
443
|
|
|
431
|
-
const session = new Session({ preset: "chrome-
|
|
444
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
432
445
|
|
|
433
446
|
// GET
|
|
434
447
|
const response = await session.get("https://example.com");
|
|
@@ -452,9 +465,7 @@ const headResponse = await session.head("https://example.com");
|
|
|
452
465
|
const optionsResponse = await session.options("https://example.com");
|
|
453
466
|
|
|
454
467
|
// Custom request
|
|
455
|
-
const customResponse = await session.request({
|
|
456
|
-
method: "PUT",
|
|
457
|
-
url: "https://api.example.com/resource",
|
|
468
|
+
const customResponse = await session.request("PUT", "https://api.example.com/resource", {
|
|
458
469
|
headers: { "X-Custom": "value" },
|
|
459
470
|
body: { data: "value" },
|
|
460
471
|
timeout: 60,
|
|
@@ -490,7 +501,7 @@ HTTPCloak includes TypeScript definitions out of the box:
|
|
|
490
501
|
```typescript
|
|
491
502
|
import { Session, Response, StreamResponse, HTTPCloakError } from "httpcloak";
|
|
492
503
|
|
|
493
|
-
const session = new Session({ preset: "chrome-
|
|
504
|
+
const session = new Session({ preset: "chrome-latest" });
|
|
494
505
|
|
|
495
506
|
async function fetchData(): Promise<Response> {
|
|
496
507
|
return session.get("https://example.com");
|
|
@@ -519,7 +530,7 @@ const { LocalProxy } = require("httpcloak");
|
|
|
519
530
|
const axios = require("axios");
|
|
520
531
|
|
|
521
532
|
// Start local proxy with Chrome fingerprint
|
|
522
|
-
const proxy = new LocalProxy({ preset: "chrome-
|
|
533
|
+
const proxy = new LocalProxy({ preset: "chrome-latest" });
|
|
523
534
|
console.log(`Proxy running on ${proxy.proxyUrl}`);
|
|
524
535
|
|
|
525
536
|
// Use X-HTTPCloak-Scheme header for HTTPS with fingerprinting + streaming
|
|
@@ -558,7 +569,7 @@ const { LocalProxy } = require("httpcloak");
|
|
|
558
569
|
const axios = require("axios");
|
|
559
570
|
|
|
560
571
|
// Start local proxy with Chrome fingerprint
|
|
561
|
-
const proxy = new LocalProxy({ preset: "chrome-
|
|
572
|
+
const proxy = new LocalProxy({ preset: "chrome-latest" });
|
|
562
573
|
|
|
563
574
|
// Standard HTTPS (uses CONNECT tunnel - fingerprinting via upstream proxy only)
|
|
564
575
|
const response = await axios.get("https://example.com", {
|
|
@@ -590,7 +601,7 @@ When your client already provides authentic browser headers, use TLS-only mode:
|
|
|
590
601
|
const { LocalProxy } = require("httpcloak");
|
|
591
602
|
|
|
592
603
|
// Only apply TLS fingerprint, pass headers through
|
|
593
|
-
const proxy = new LocalProxy({ preset: "chrome-
|
|
604
|
+
const proxy = new LocalProxy({ preset: "chrome-latest", tlsOnly: true });
|
|
594
605
|
|
|
595
606
|
// Your client's headers are preserved
|
|
596
607
|
const response = await fetch("https://example.com", {
|
|
@@ -608,10 +619,10 @@ Route different requests through different browser fingerprints:
|
|
|
608
619
|
```javascript
|
|
609
620
|
const { LocalProxy, Session } = require("httpcloak");
|
|
610
621
|
|
|
611
|
-
const proxy = new LocalProxy({ preset: "chrome-
|
|
622
|
+
const proxy = new LocalProxy({ preset: "chrome-latest" });
|
|
612
623
|
|
|
613
624
|
// Create sessions with different fingerprints
|
|
614
|
-
const chromeSession = new Session({ preset: "chrome-
|
|
625
|
+
const chromeSession = new Session({ preset: "chrome-latest" });
|
|
615
626
|
const firefoxSession = new Session({ preset: "firefox-133" });
|
|
616
627
|
|
|
617
628
|
// Register sessions with the proxy
|
|
@@ -638,7 +649,7 @@ proxy.close();
|
|
|
638
649
|
```javascript
|
|
639
650
|
const proxy = new LocalProxy({
|
|
640
651
|
port: 0, // Port (0 = auto-select)
|
|
641
|
-
preset: "chrome-
|
|
652
|
+
preset: "chrome-latest", // Browser fingerprint
|
|
642
653
|
timeout: 30, // Request timeout in seconds
|
|
643
654
|
maxConnections: 1000, // Max concurrent connections
|
|
644
655
|
tcpProxy: null, // Default upstream TCP proxy
|
package/lib/index.d.ts
CHANGED
|
@@ -195,7 +195,7 @@ export class StreamResponse {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
export interface SessionOptions {
|
|
198
|
-
/** Browser preset to use (default: "chrome-
|
|
198
|
+
/** Browser preset to use (default: "chrome-146") */
|
|
199
199
|
preset?: string;
|
|
200
200
|
/** Proxy URL (e.g., "http://user:pass@host:port" or "socks5://host:port") */
|
|
201
201
|
proxy?: string;
|
|
@@ -337,22 +337,50 @@ export class Session {
|
|
|
337
337
|
options(url: string, options?: RequestOptions): Promise<Response>;
|
|
338
338
|
|
|
339
339
|
// Cookie management
|
|
340
|
-
|
|
340
|
+
|
|
341
|
+
/** Get all cookies with full metadata (domain, path, expiry, flags) */
|
|
342
|
+
getCookiesDetailed(): Cookie[];
|
|
343
|
+
|
|
344
|
+
/** Get a specific cookie by name with full metadata */
|
|
345
|
+
getCookieDetailed(name: string): Cookie | null;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Get all cookies as a flat name-value object.
|
|
349
|
+
* @deprecated Will return Cookie[] with full metadata in a future release. Use getCookiesDetailed() for the new format now.
|
|
350
|
+
*/
|
|
341
351
|
getCookies(): Record<string, string>;
|
|
342
352
|
|
|
343
|
-
/**
|
|
353
|
+
/**
|
|
354
|
+
* Get a specific cookie value by name.
|
|
355
|
+
* @deprecated Will return Cookie|null in a future release. Use getCookieDetailed() for the new format now.
|
|
356
|
+
*/
|
|
344
357
|
getCookie(name: string): string | null;
|
|
345
358
|
|
|
346
359
|
/** Set a cookie in the session */
|
|
347
|
-
setCookie(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
360
|
+
setCookie(
|
|
361
|
+
name: string,
|
|
362
|
+
value: string,
|
|
363
|
+
options?: {
|
|
364
|
+
domain?: string;
|
|
365
|
+
path?: string;
|
|
366
|
+
secure?: boolean;
|
|
367
|
+
httpOnly?: boolean;
|
|
368
|
+
sameSite?: string;
|
|
369
|
+
maxAge?: number;
|
|
370
|
+
expires?: string;
|
|
371
|
+
}
|
|
372
|
+
): void;
|
|
373
|
+
|
|
374
|
+
/** Delete a specific cookie by name. If domain is omitted, deletes from all domains. */
|
|
375
|
+
deleteCookie(name: string, domain?: string): void;
|
|
351
376
|
|
|
352
377
|
/** Clear all cookies from the session */
|
|
353
378
|
clearCookies(): void;
|
|
354
379
|
|
|
355
|
-
/**
|
|
380
|
+
/**
|
|
381
|
+
* Get cookies as a property.
|
|
382
|
+
* @deprecated Will return Cookie[] with full metadata in a future release.
|
|
383
|
+
*/
|
|
356
384
|
readonly cookies: Record<string, string>;
|
|
357
385
|
|
|
358
386
|
// Proxy management
|
|
@@ -619,7 +647,7 @@ export class Session {
|
|
|
619
647
|
export interface LocalProxyOptions {
|
|
620
648
|
/** Port to listen on (default: 0 for auto-assign) */
|
|
621
649
|
port?: number;
|
|
622
|
-
/** Browser preset to use (default: "chrome-
|
|
650
|
+
/** Browser preset to use (default: "chrome-146") */
|
|
623
651
|
preset?: string;
|
|
624
652
|
/** Request timeout in seconds (default: 30) */
|
|
625
653
|
timeout?: number;
|
|
@@ -659,7 +687,7 @@ export interface LocalProxyStats {
|
|
|
659
687
|
*
|
|
660
688
|
* @example
|
|
661
689
|
* // Basic usage
|
|
662
|
-
* const proxy = new LocalProxy({ preset: "chrome-
|
|
690
|
+
* const proxy = new LocalProxy({ preset: "chrome-146", tlsOnly: true });
|
|
663
691
|
* console.log(`Proxy running on ${proxy.proxyUrl}`);
|
|
664
692
|
* // Use with any HTTP client pointing to the proxy
|
|
665
693
|
* proxy.close();
|
|
@@ -816,6 +844,10 @@ export function request(method: string, url: string, options?: RequestOptions):
|
|
|
816
844
|
|
|
817
845
|
/** Available browser presets */
|
|
818
846
|
export const Preset: {
|
|
847
|
+
CHROME_146: string;
|
|
848
|
+
CHROME_146_WINDOWS: string;
|
|
849
|
+
CHROME_146_LINUX: string;
|
|
850
|
+
CHROME_146_MACOS: string;
|
|
819
851
|
CHROME_145: string;
|
|
820
852
|
CHROME_145_WINDOWS: string;
|
|
821
853
|
CHROME_145_LINUX: string;
|
|
@@ -833,9 +865,11 @@ export const Preset: {
|
|
|
833
865
|
CHROME_143_IOS: string;
|
|
834
866
|
CHROME_144_IOS: string;
|
|
835
867
|
CHROME_145_IOS: string;
|
|
868
|
+
CHROME_146_IOS: string;
|
|
836
869
|
CHROME_143_ANDROID: string;
|
|
837
870
|
CHROME_144_ANDROID: string;
|
|
838
871
|
CHROME_145_ANDROID: string;
|
|
872
|
+
CHROME_146_ANDROID: string;
|
|
839
873
|
FIREFOX_133: string;
|
|
840
874
|
SAFARI_18: string;
|
|
841
875
|
SAFARI_17_IOS: string;
|
|
@@ -844,9 +878,11 @@ export const Preset: {
|
|
|
844
878
|
IOS_CHROME_143: string;
|
|
845
879
|
IOS_CHROME_144: string;
|
|
846
880
|
IOS_CHROME_145: string;
|
|
881
|
+
IOS_CHROME_146: string;
|
|
847
882
|
ANDROID_CHROME_143: string;
|
|
848
883
|
ANDROID_CHROME_144: string;
|
|
849
884
|
ANDROID_CHROME_145: string;
|
|
885
|
+
ANDROID_CHROME_146: string;
|
|
850
886
|
IOS_SAFARI_17: string;
|
|
851
887
|
IOS_SAFARI_18: string;
|
|
852
888
|
all(): string[];
|
package/lib/index.js
CHANGED
|
@@ -31,7 +31,13 @@ class HTTPCloakError extends Error {
|
|
|
31
31
|
* const session = new httpcloak.Session({ preset: httpcloak.Preset.FIREFOX_133 });
|
|
32
32
|
*/
|
|
33
33
|
const Preset = {
|
|
34
|
-
// Chrome
|
|
34
|
+
// Chrome 146 (latest)
|
|
35
|
+
CHROME_146: "chrome-146",
|
|
36
|
+
CHROME_146_WINDOWS: "chrome-146-windows",
|
|
37
|
+
CHROME_146_LINUX: "chrome-146-linux",
|
|
38
|
+
CHROME_146_MACOS: "chrome-146-macos",
|
|
39
|
+
|
|
40
|
+
// Chrome 145
|
|
35
41
|
CHROME_145: "chrome-145",
|
|
36
42
|
CHROME_145_WINDOWS: "chrome-145-windows",
|
|
37
43
|
CHROME_145_LINUX: "chrome-145-linux",
|
|
@@ -59,9 +65,11 @@ const Preset = {
|
|
|
59
65
|
CHROME_143_IOS: "chrome-143-ios",
|
|
60
66
|
CHROME_144_IOS: "chrome-144-ios",
|
|
61
67
|
CHROME_145_IOS: "chrome-145-ios",
|
|
68
|
+
CHROME_146_IOS: "chrome-146-ios",
|
|
62
69
|
CHROME_143_ANDROID: "chrome-143-android",
|
|
63
70
|
CHROME_144_ANDROID: "chrome-144-android",
|
|
64
71
|
CHROME_145_ANDROID: "chrome-145-android",
|
|
72
|
+
CHROME_146_ANDROID: "chrome-146-android",
|
|
65
73
|
|
|
66
74
|
// Firefox
|
|
67
75
|
FIREFOX_133: "firefox-133",
|
|
@@ -75,9 +83,11 @@ const Preset = {
|
|
|
75
83
|
IOS_CHROME_143: "chrome-143-ios",
|
|
76
84
|
IOS_CHROME_144: "chrome-144-ios",
|
|
77
85
|
IOS_CHROME_145: "chrome-145-ios",
|
|
86
|
+
IOS_CHROME_146: "chrome-146-ios",
|
|
78
87
|
ANDROID_CHROME_143: "chrome-143-android",
|
|
79
88
|
ANDROID_CHROME_144: "chrome-144-android",
|
|
80
89
|
ANDROID_CHROME_145: "chrome-145-android",
|
|
90
|
+
ANDROID_CHROME_146: "chrome-146-android",
|
|
81
91
|
IOS_SAFARI_17: "safari-17-ios",
|
|
82
92
|
IOS_SAFARI_18: "safari-18-ios",
|
|
83
93
|
|
|
@@ -87,12 +97,13 @@ const Preset = {
|
|
|
87
97
|
*/
|
|
88
98
|
all() {
|
|
89
99
|
return [
|
|
100
|
+
this.CHROME_146, this.CHROME_146_WINDOWS, this.CHROME_146_LINUX, this.CHROME_146_MACOS,
|
|
90
101
|
this.CHROME_145, this.CHROME_145_WINDOWS, this.CHROME_145_LINUX, this.CHROME_145_MACOS,
|
|
91
102
|
this.CHROME_144, this.CHROME_144_WINDOWS, this.CHROME_144_LINUX, this.CHROME_144_MACOS,
|
|
92
103
|
this.CHROME_143, this.CHROME_143_WINDOWS, this.CHROME_143_LINUX, this.CHROME_143_MACOS,
|
|
93
104
|
this.CHROME_141, this.CHROME_133,
|
|
94
|
-
this.CHROME_145_IOS, this.CHROME_144_IOS, this.CHROME_143_IOS,
|
|
95
|
-
this.CHROME_145_ANDROID, this.CHROME_144_ANDROID, this.CHROME_143_ANDROID,
|
|
105
|
+
this.CHROME_146_IOS, this.CHROME_145_IOS, this.CHROME_144_IOS, this.CHROME_143_IOS,
|
|
106
|
+
this.CHROME_146_ANDROID, this.CHROME_145_ANDROID, this.CHROME_144_ANDROID, this.CHROME_143_ANDROID,
|
|
96
107
|
this.FIREFOX_133,
|
|
97
108
|
this.SAFARI_18, this.SAFARI_17_IOS, this.SAFARI_18_IOS,
|
|
98
109
|
];
|
|
@@ -789,7 +800,9 @@ function getLib() {
|
|
|
789
800
|
httpcloak_post: nativeLibHandle.func("httpcloak_post", "str", ["int64", "str", "str", "str"]),
|
|
790
801
|
httpcloak_request: nativeLibHandle.func("httpcloak_request", "str", ["int64", "str"]),
|
|
791
802
|
httpcloak_get_cookies: nativeLibHandle.func("httpcloak_get_cookies", "str", ["int64"]),
|
|
792
|
-
httpcloak_set_cookie: nativeLibHandle.func("httpcloak_set_cookie", "void", ["int64", "str"
|
|
803
|
+
httpcloak_set_cookie: nativeLibHandle.func("httpcloak_set_cookie", "void", ["int64", "str"]),
|
|
804
|
+
httpcloak_delete_cookie: nativeLibHandle.func("httpcloak_delete_cookie", "void", ["int64", "str", "str"]),
|
|
805
|
+
httpcloak_clear_cookies: nativeLibHandle.func("httpcloak_clear_cookies", "void", ["int64"]),
|
|
793
806
|
httpcloak_free_string: nativeLibHandle.func("httpcloak_free_string", "void", ["void*"]),
|
|
794
807
|
httpcloak_version: nativeLibHandle.func("httpcloak_version", "str", []),
|
|
795
808
|
httpcloak_available_presets: nativeLibHandle.func("httpcloak_available_presets", "str", []),
|
|
@@ -1162,7 +1175,7 @@ function version() {
|
|
|
1162
1175
|
/**
|
|
1163
1176
|
* Get available browser presets with their supported protocols.
|
|
1164
1177
|
* Returns an object mapping preset names to their info:
|
|
1165
|
-
* { "chrome-
|
|
1178
|
+
* { "chrome-146": { protocols: ["h1", "h2", "h3"] }, ... }
|
|
1166
1179
|
*/
|
|
1167
1180
|
function availablePresets() {
|
|
1168
1181
|
const nativeLib = getLib();
|
|
@@ -1228,7 +1241,7 @@ class Session {
|
|
|
1228
1241
|
/**
|
|
1229
1242
|
* Create a new session
|
|
1230
1243
|
* @param {Object} options - Session options
|
|
1231
|
-
* @param {string} [options.preset="chrome-
|
|
1244
|
+
* @param {string} [options.preset="chrome-146"] - Browser preset to use
|
|
1232
1245
|
* @param {string} [options.proxy] - Proxy URL (e.g., "http://user:pass@host:port" or "socks5://host:port")
|
|
1233
1246
|
* @param {string} [options.tcpProxy] - Proxy URL for TCP protocols (HTTP/1.1, HTTP/2) - use with udpProxy for split config
|
|
1234
1247
|
* @param {string} [options.udpProxy] - Proxy URL for UDP protocols (HTTP/3 via MASQUE) - use with tcpProxy for split config
|
|
@@ -1249,7 +1262,7 @@ class Session {
|
|
|
1249
1262
|
*/
|
|
1250
1263
|
constructor(options = {}) {
|
|
1251
1264
|
const {
|
|
1252
|
-
preset = "chrome-
|
|
1265
|
+
preset = "chrome-146",
|
|
1253
1266
|
proxy = null,
|
|
1254
1267
|
tcpProxy = null,
|
|
1255
1268
|
udpProxy = null,
|
|
@@ -1275,6 +1288,11 @@ class Session {
|
|
|
1275
1288
|
ja3 = null,
|
|
1276
1289
|
akamai = null,
|
|
1277
1290
|
extraFp = null,
|
|
1291
|
+
tcpTtl = null,
|
|
1292
|
+
tcpMss = null,
|
|
1293
|
+
tcpWindowSize = null,
|
|
1294
|
+
tcpWindowScale = null,
|
|
1295
|
+
tcpDf = null,
|
|
1278
1296
|
} = options;
|
|
1279
1297
|
|
|
1280
1298
|
this._lib = getLib();
|
|
@@ -1350,6 +1368,21 @@ class Session {
|
|
|
1350
1368
|
if (extraFp) {
|
|
1351
1369
|
config.extra_fp = extraFp;
|
|
1352
1370
|
}
|
|
1371
|
+
if (tcpTtl != null) {
|
|
1372
|
+
config.tcp_ttl = tcpTtl;
|
|
1373
|
+
}
|
|
1374
|
+
if (tcpMss != null) {
|
|
1375
|
+
config.tcp_mss = tcpMss;
|
|
1376
|
+
}
|
|
1377
|
+
if (tcpWindowSize != null) {
|
|
1378
|
+
config.tcp_window_size = tcpWindowSize;
|
|
1379
|
+
}
|
|
1380
|
+
if (tcpWindowScale != null) {
|
|
1381
|
+
config.tcp_window_scale = tcpWindowScale;
|
|
1382
|
+
}
|
|
1383
|
+
if (tcpDf != null) {
|
|
1384
|
+
config.tcp_df = tcpDf;
|
|
1385
|
+
}
|
|
1353
1386
|
|
|
1354
1387
|
this._handle = this._lib.httpcloak_session_new(JSON.stringify(config));
|
|
1355
1388
|
|
|
@@ -1855,58 +1888,118 @@ class Session {
|
|
|
1855
1888
|
// ===========================================================================
|
|
1856
1889
|
|
|
1857
1890
|
/**
|
|
1858
|
-
* Get all cookies
|
|
1859
|
-
* @returns {
|
|
1891
|
+
* Get all cookies with full metadata (domain, path, expiry, flags).
|
|
1892
|
+
* @returns {Cookie[]} Array of Cookie objects
|
|
1860
1893
|
*/
|
|
1861
|
-
|
|
1894
|
+
getCookiesDetailed() {
|
|
1862
1895
|
const resultPtr = this._lib.httpcloak_get_cookies(this._handle);
|
|
1863
1896
|
const result = resultToString(resultPtr);
|
|
1864
1897
|
if (result) {
|
|
1865
|
-
|
|
1898
|
+
const parsed = JSON.parse(result);
|
|
1899
|
+
return parsed.map(c => new Cookie(c));
|
|
1866
1900
|
}
|
|
1867
|
-
return
|
|
1901
|
+
return [];
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
/**
|
|
1905
|
+
* Get all cookies as a flat name-value object.
|
|
1906
|
+
* @deprecated getCookies() will return Cookie[] with full metadata (domain, path, expiry) in a future release.
|
|
1907
|
+
* Use getCookiesDetailed() if you want the new format now.
|
|
1908
|
+
* @returns {Object} Cookies as key-value pairs
|
|
1909
|
+
*/
|
|
1910
|
+
getCookies() {
|
|
1911
|
+
if (!Session._getCookiesDeprecated) {
|
|
1912
|
+
Session._getCookiesDeprecated = true;
|
|
1913
|
+
process.emitWarning(
|
|
1914
|
+
'getCookies() currently returns a flat {name: value} object. In a future release, it will return Cookie[] with full metadata (domain, path, expiry, etc.), same as getCookiesDetailed(). Update your code accordingly.',
|
|
1915
|
+
'DeprecationWarning'
|
|
1916
|
+
);
|
|
1917
|
+
}
|
|
1918
|
+
const cookies = this.getCookiesDetailed();
|
|
1919
|
+
const result = {};
|
|
1920
|
+
for (const c of cookies) {
|
|
1921
|
+
result[c.name] = c.value;
|
|
1922
|
+
}
|
|
1923
|
+
return result;
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
/**
|
|
1927
|
+
* Get a specific cookie by name with full metadata.
|
|
1928
|
+
* @param {string} name - Cookie name
|
|
1929
|
+
* @returns {Cookie|null} Cookie object or null if not found
|
|
1930
|
+
*/
|
|
1931
|
+
getCookieDetailed(name) {
|
|
1932
|
+
const cookies = this.getCookiesDetailed();
|
|
1933
|
+
return cookies.find(c => c.name === name) || null;
|
|
1868
1934
|
}
|
|
1869
1935
|
|
|
1870
1936
|
/**
|
|
1871
|
-
* Get a specific cookie by name
|
|
1937
|
+
* Get a specific cookie value by name.
|
|
1938
|
+
* @deprecated getCookie() will return a Cookie object (with domain, path, expiry) instead of a string in a future release.
|
|
1939
|
+
* Use getCookieDetailed() if you want the new format now.
|
|
1872
1940
|
* @param {string} name - Cookie name
|
|
1873
1941
|
* @returns {string|null} Cookie value or null if not found
|
|
1874
1942
|
*/
|
|
1875
1943
|
getCookie(name) {
|
|
1876
|
-
|
|
1877
|
-
|
|
1944
|
+
if (!Session._getCookieDeprecated) {
|
|
1945
|
+
Session._getCookieDeprecated = true;
|
|
1946
|
+
process.emitWarning(
|
|
1947
|
+
'getCookie() currently returns a string value. In a future release, it will return a Cookie object with full metadata (domain, path, expiry, etc.), same as getCookieDetailed(). Update your code accordingly.',
|
|
1948
|
+
'DeprecationWarning'
|
|
1949
|
+
);
|
|
1950
|
+
}
|
|
1951
|
+
const cookie = this.getCookieDetailed(name);
|
|
1952
|
+
return cookie ? cookie.value : null;
|
|
1878
1953
|
}
|
|
1879
1954
|
|
|
1880
1955
|
/**
|
|
1881
1956
|
* Set a cookie in the session
|
|
1882
1957
|
* @param {string} name - Cookie name
|
|
1883
1958
|
* @param {string} value - Cookie value
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1959
|
+
* @param {Object} [options] - Cookie options
|
|
1960
|
+
* @param {string} [options.domain] - Cookie domain
|
|
1961
|
+
* @param {string} [options.path] - Cookie path (default: "/")
|
|
1962
|
+
* @param {boolean} [options.secure] - Secure flag
|
|
1963
|
+
* @param {boolean} [options.httpOnly] - HttpOnly flag
|
|
1964
|
+
* @param {string} [options.sameSite] - SameSite attribute (Strict, Lax, None)
|
|
1965
|
+
* @param {number} [options.maxAge] - Max age in seconds (0 means not set)
|
|
1966
|
+
* @param {string} [options.expires] - Expiration date (RFC1123 format)
|
|
1967
|
+
*/
|
|
1968
|
+
setCookie(name, value, options = {}) {
|
|
1969
|
+
const cookie = {
|
|
1970
|
+
name,
|
|
1971
|
+
value,
|
|
1972
|
+
domain: options.domain || "",
|
|
1973
|
+
path: options.path || "/",
|
|
1974
|
+
secure: options.secure || false,
|
|
1975
|
+
http_only: options.httpOnly || false,
|
|
1976
|
+
same_site: options.sameSite || "",
|
|
1977
|
+
max_age: options.maxAge || 0,
|
|
1978
|
+
expires: options.expires || "",
|
|
1979
|
+
};
|
|
1980
|
+
this._lib.httpcloak_set_cookie(this._handle, JSON.stringify(cookie));
|
|
1887
1981
|
}
|
|
1888
1982
|
|
|
1889
1983
|
/**
|
|
1890
1984
|
* Delete a specific cookie by name
|
|
1891
1985
|
* @param {string} name - Cookie name to delete
|
|
1986
|
+
* @param {string} [domain] - Domain to delete from (omit to delete from all domains)
|
|
1892
1987
|
*/
|
|
1893
|
-
deleteCookie(name) {
|
|
1894
|
-
|
|
1895
|
-
this._lib.httpcloak_set_cookie(this._handle, name, "");
|
|
1988
|
+
deleteCookie(name, domain = "") {
|
|
1989
|
+
this._lib.httpcloak_delete_cookie(this._handle, name, domain);
|
|
1896
1990
|
}
|
|
1897
1991
|
|
|
1898
1992
|
/**
|
|
1899
1993
|
* Clear all cookies from the session
|
|
1900
1994
|
*/
|
|
1901
1995
|
clearCookies() {
|
|
1902
|
-
|
|
1903
|
-
for (const name of Object.keys(cookies)) {
|
|
1904
|
-
this.deleteCookie(name);
|
|
1905
|
-
}
|
|
1996
|
+
this._lib.httpcloak_clear_cookies(this._handle);
|
|
1906
1997
|
}
|
|
1907
1998
|
|
|
1908
1999
|
/**
|
|
1909
|
-
* Get cookies as a property
|
|
2000
|
+
* Get cookies as a property.
|
|
2001
|
+
* @deprecated This property will return Cookie[] with full metadata in a future release.
|
|
2002
|
+
* @returns {Object} Cookies as key-value pairs
|
|
1910
2003
|
*/
|
|
1911
2004
|
get cookies() {
|
|
1912
2005
|
return this.getCookies();
|
|
@@ -2077,7 +2170,7 @@ class Session {
|
|
|
2077
2170
|
* @param {string} path - Path to save the session file
|
|
2078
2171
|
*
|
|
2079
2172
|
* Example:
|
|
2080
|
-
* const session = new httpcloak.Session({ preset: "chrome-
|
|
2173
|
+
* const session = new httpcloak.Session({ preset: "chrome-146" });
|
|
2081
2174
|
* await session.get("https://example.com"); // Acquire cookies
|
|
2082
2175
|
* session.save("session.json");
|
|
2083
2176
|
*
|
|
@@ -2715,7 +2808,7 @@ let _defaultConfig = {};
|
|
|
2715
2808
|
/**
|
|
2716
2809
|
* Configure defaults for module-level functions
|
|
2717
2810
|
* @param {Object} options - Configuration options
|
|
2718
|
-
* @param {string} [options.preset="chrome-
|
|
2811
|
+
* @param {string} [options.preset="chrome-146"] - Browser preset
|
|
2719
2812
|
* @param {Object} [options.headers] - Default headers
|
|
2720
2813
|
* @param {Array} [options.auth] - Default basic auth [username, password]
|
|
2721
2814
|
* @param {string} [options.proxy] - Proxy URL
|
|
@@ -2729,7 +2822,7 @@ let _defaultConfig = {};
|
|
|
2729
2822
|
*/
|
|
2730
2823
|
function configure(options = {}) {
|
|
2731
2824
|
const {
|
|
2732
|
-
preset = "chrome-
|
|
2825
|
+
preset = "chrome-146",
|
|
2733
2826
|
headers = null,
|
|
2734
2827
|
auth = null,
|
|
2735
2828
|
proxy = null,
|
|
@@ -2787,7 +2880,7 @@ function configure(options = {}) {
|
|
|
2787
2880
|
*/
|
|
2788
2881
|
function _getDefaultSession() {
|
|
2789
2882
|
if (!_defaultSession) {
|
|
2790
|
-
const preset = _defaultConfig.preset || "chrome-
|
|
2883
|
+
const preset = _defaultConfig.preset || "chrome-146";
|
|
2791
2884
|
const proxy = _defaultConfig.proxy || null;
|
|
2792
2885
|
const timeout = _defaultConfig.timeout || 30;
|
|
2793
2886
|
const httpVersion = _defaultConfig.httpVersion || "auto";
|
|
@@ -2890,7 +2983,7 @@ function request(method, url, options = {}) {
|
|
|
2890
2983
|
* Without registration, cache callbacks will not be triggered for that session.
|
|
2891
2984
|
*
|
|
2892
2985
|
* @example
|
|
2893
|
-
* const proxy = new LocalProxy({ preset: "chrome-
|
|
2986
|
+
* const proxy = new LocalProxy({ preset: "chrome-146", tlsOnly: true });
|
|
2894
2987
|
* console.log(`Proxy running on ${proxy.proxyUrl}`);
|
|
2895
2988
|
*
|
|
2896
2989
|
* // Use with any HTTP client pointing to the proxy
|
|
@@ -2919,7 +3012,7 @@ class LocalProxy {
|
|
|
2919
3012
|
* Create and start a local HTTP proxy server.
|
|
2920
3013
|
* @param {Object} options - Proxy configuration options
|
|
2921
3014
|
* @param {number} [options.port=0] - Port to listen on (0 = auto-select)
|
|
2922
|
-
* @param {string} [options.preset="chrome-
|
|
3015
|
+
* @param {string} [options.preset="chrome-146"] - Browser fingerprint preset
|
|
2923
3016
|
* @param {number} [options.timeout=30] - Request timeout in seconds
|
|
2924
3017
|
* @param {number} [options.maxConnections=1000] - Maximum concurrent connections
|
|
2925
3018
|
* @param {string} [options.tcpProxy] - Default upstream TCP proxy URL
|
|
@@ -2929,7 +3022,7 @@ class LocalProxy {
|
|
|
2929
3022
|
constructor(options = {}) {
|
|
2930
3023
|
const {
|
|
2931
3024
|
port = 0,
|
|
2932
|
-
preset = "chrome-
|
|
3025
|
+
preset = "chrome-146",
|
|
2933
3026
|
timeout = 30,
|
|
2934
3027
|
maxConnections = 1000,
|
|
2935
3028
|
tcpProxy = null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "httpcloak",
|
|
3
|
-
"version": "1.6.1
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Browser fingerprint emulation HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.mjs",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"koffi": "^2.9.0"
|
|
50
50
|
},
|
|
51
51
|
"optionalDependencies": {
|
|
52
|
-
"@httpcloak/darwin-arm64": "1.6.1
|
|
53
|
-
"@httpcloak/darwin-x64": "1.6.1
|
|
54
|
-
"@httpcloak/linux-arm64": "1.6.1
|
|
55
|
-
"@httpcloak/linux-x64": "1.6.1
|
|
56
|
-
"@httpcloak/win32-arm64": "1.6.1
|
|
57
|
-
"@httpcloak/win32-x64": "1.6.1
|
|
52
|
+
"@httpcloak/darwin-arm64": "1.6.1",
|
|
53
|
+
"@httpcloak/darwin-x64": "1.6.1",
|
|
54
|
+
"@httpcloak/linux-arm64": "1.6.1",
|
|
55
|
+
"@httpcloak/linux-x64": "1.6.1",
|
|
56
|
+
"@httpcloak/win32-arm64": "1.6.1",
|
|
57
|
+
"@httpcloak/win32-x64": "1.6.1"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^25.1.0",
|