httpcloak 1.6.7 → 1.6.8-beta.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/lib/index.d.ts CHANGED
@@ -245,6 +245,10 @@ export interface SessionOptions {
245
245
  withoutCookieJar?: boolean;
246
246
  /** Disable ETag / If-Modified-Since handling for the lifetime of the session (default: false) */
247
247
  withoutConditionalCache?: boolean;
248
+ /** Full strip: drop ALL sec-ch-ua client hints (including the always-on trio) for the lifetime of the session (default: false) */
249
+ withoutClientHints?: boolean;
250
+ /** High-entropy strip: keep the always-on trio but drop only the Accept-CH high-entropy hints for the lifetime of the session (default: false) */
251
+ withoutHighEntropyClientHints?: boolean;
248
252
  /** Skip the ECH (Encrypted Client Hello) HTTPS RR lookup. Saves ~15-20ms on first connect (default: false) */
249
253
  disableEch?: boolean;
250
254
  /** Disable HTTP/3 racing while keeping H1/H2 auto-negotiation. Reachable indirectly via httpVersion: "h2" but the explicit flag is cleaner (default: false) */
@@ -315,6 +319,22 @@ export interface RequestOptions {
315
319
  */
316
320
  disableConditionalCache?: boolean;
317
321
 
322
+ /**
323
+ * Per-request full strip of sec-ch-ua client hints. When true, ALL client
324
+ * hints are dropped for this request, including the always-on trio
325
+ * (sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform). One-off only; the
326
+ * session-wide setting is untouched.
327
+ */
328
+ disableClientHints?: boolean;
329
+
330
+ /**
331
+ * Per-request high-entropy strip. When true, this request keeps the
332
+ * always-on trio but drops only the high-entropy Accept-CH hints
333
+ * (e.g. sec-ch-ua-platform-version, -arch, -model, -bitness,
334
+ * -full-version-list). One-off only; the session-wide setting is untouched.
335
+ */
336
+ disableHighEntropyClientHints?: boolean;
337
+
318
338
  /**
319
339
  * AbortSignal for cancelling an in-flight request. Honored by the async
320
340
  * methods (get, post, put, patch, delete, head, options, request). When
@@ -512,6 +532,28 @@ export class Session {
512
532
  /** Read the session's current conditional-cache state. */
513
533
  getConditionalCache(): boolean;
514
534
 
535
+ /**
536
+ * Toggle the session's client-hints handling at runtime (full strip).
537
+ * When disabled, the session drops ALL sec-ch-ua client hints, including
538
+ * the always-on trio (sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform).
539
+ * The change takes effect on the next request and persists until set again.
540
+ */
541
+ setClientHints(enabled: boolean): void;
542
+
543
+ /** Read the session's current client-hints state. */
544
+ getClientHints(): boolean;
545
+
546
+ /**
547
+ * Toggle the session's high-entropy client-hints handling at runtime.
548
+ * When disabled, the session keeps the always-on trio but drops only the
549
+ * high-entropy Accept-CH hints (e.g. sec-ch-ua-platform-version, -arch,
550
+ * -model, -bitness, -full-version-list). Takes effect on the next request.
551
+ */
552
+ setHighEntropyClientHints(enabled: boolean): void;
553
+
554
+ /** Read the session's current high-entropy client-hints state. */
555
+ getHighEntropyClientHints(): boolean;
556
+
515
557
  /**
516
558
  * Toggle the session's redirect-following policy at runtime. The change
517
559
  * takes effect on the next request and persists until set again.
package/lib/index.js CHANGED
@@ -889,6 +889,10 @@ function getLib() {
889
889
  httpcloak_session_touch: nativeLibHandle.func("httpcloak_session_touch", "void", ["int64"]),
890
890
  httpcloak_session_set_conditional_cache: nativeLibHandle.func("httpcloak_session_set_conditional_cache", "void", ["int64", "int"]),
891
891
  httpcloak_session_get_conditional_cache: nativeLibHandle.func("httpcloak_session_get_conditional_cache", "int", ["int64"]),
892
+ httpcloak_session_set_client_hints: nativeLibHandle.func("httpcloak_session_set_client_hints", "void", ["int64", "int"]),
893
+ httpcloak_session_get_client_hints: nativeLibHandle.func("httpcloak_session_get_client_hints", "int", ["int64"]),
894
+ httpcloak_session_set_high_entropy_client_hints: nativeLibHandle.func("httpcloak_session_set_high_entropy_client_hints", "void", ["int64", "int"]),
895
+ httpcloak_session_get_high_entropy_client_hints: nativeLibHandle.func("httpcloak_session_get_high_entropy_client_hints", "int", ["int64"]),
892
896
  httpcloak_session_set_follow_redirects: nativeLibHandle.func("httpcloak_session_set_follow_redirects", "void", ["int64", "int"]),
893
897
  httpcloak_session_get_follow_redirects: nativeLibHandle.func("httpcloak_session_get_follow_redirects", "int", ["int64"]),
894
898
  httpcloak_session_set_max_redirects: nativeLibHandle.func("httpcloak_session_set_max_redirects", "void", ["int64", "int"]),
@@ -1476,6 +1480,8 @@ class Session {
1476
1480
  switchProtocol = null,
1477
1481
  withoutCookieJar = false,
1478
1482
  withoutConditionalCache = false,
1483
+ withoutClientHints = false,
1484
+ withoutHighEntropyClientHints = false,
1479
1485
  disableEch = false,
1480
1486
  disableHttp3 = false,
1481
1487
  ja3 = null,
@@ -1558,6 +1564,14 @@ class Session {
1558
1564
  if (withoutConditionalCache) {
1559
1565
  config.without_conditional_cache = true;
1560
1566
  }
1567
+ // Full strip: drop ALL sec-ch-ua client hints, including the always-on trio.
1568
+ if (withoutClientHints) {
1569
+ config.without_client_hints = true;
1570
+ }
1571
+ // High-entropy strip: keep the always-on trio, drop only the Accept-CH hints.
1572
+ if (withoutHighEntropyClientHints) {
1573
+ config.without_high_entropy_client_hints = true;
1574
+ }
1561
1575
  if (disableEch) {
1562
1576
  config.disable_ech = true;
1563
1577
  }
@@ -1727,7 +1741,7 @@ class Session {
1727
1741
  * @returns {Response} Response object
1728
1742
  */
1729
1743
  getSync(url, options = {}) {
1730
- const { headers = null, params = null, cookies = null, auth = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false } = options;
1744
+ const { headers = null, params = null, cookies = null, auth = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false } = options;
1731
1745
 
1732
1746
  url = addParamsToUrl(url, params);
1733
1747
  let mergedHeaders = this._mergeHeaders(headers);
@@ -1750,6 +1764,12 @@ class Session {
1750
1764
  if (disableConditionalCache) {
1751
1765
  reqOptions.disable_conditional_cache = true;
1752
1766
  }
1767
+ if (disableClientHints) {
1768
+ reqOptions.disable_client_hints = true;
1769
+ }
1770
+ if (disableHighEntropyClientHints) {
1771
+ reqOptions.disable_high_entropy_client_hints = true;
1772
+ }
1753
1773
  const optionsJson = Object.keys(reqOptions).length > 0 ? JSON.stringify(reqOptions) : null;
1754
1774
 
1755
1775
  const startTime = Date.now();
@@ -1779,7 +1799,7 @@ class Session {
1779
1799
  * @returns {Response} Response object
1780
1800
  */
1781
1801
  postSync(url, options = {}) {
1782
- let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false } = options;
1802
+ let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false } = options;
1783
1803
 
1784
1804
  url = addParamsToUrl(url, params);
1785
1805
  let mergedHeaders = this._mergeHeaders(headers);
@@ -1830,6 +1850,12 @@ class Session {
1830
1850
  if (disableConditionalCache) {
1831
1851
  reqOptions.disable_conditional_cache = true;
1832
1852
  }
1853
+ if (disableClientHints) {
1854
+ reqOptions.disable_client_hints = true;
1855
+ }
1856
+ if (disableHighEntropyClientHints) {
1857
+ reqOptions.disable_high_entropy_client_hints = true;
1858
+ }
1833
1859
  const optionsJson = Object.keys(reqOptions).length > 0 ? JSON.stringify(reqOptions) : null;
1834
1860
 
1835
1861
  const bodyPtr = bodyBuffer || Buffer.alloc(0);
@@ -1854,7 +1880,7 @@ class Session {
1854
1880
  * @returns {Response} Response object
1855
1881
  */
1856
1882
  requestSync(method, url, options = {}) {
1857
- let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, timeout = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false } = options;
1883
+ let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, timeout = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false } = options;
1858
1884
 
1859
1885
  url = addParamsToUrl(url, params);
1860
1886
  let mergedHeaders = this._mergeHeaders(headers);
@@ -1899,6 +1925,8 @@ class Session {
1899
1925
  if (fetchMode) requestConfig.fetch_mode = fetchMode;
1900
1926
  if (allowRedirects !== null && allowRedirects !== undefined) requestConfig.follow_redirects = !!allowRedirects;
1901
1927
  if (disableConditionalCache) requestConfig.disable_conditional_cache = true;
1928
+ if (disableClientHints) requestConfig.disable_client_hints = true;
1929
+ if (disableHighEntropyClientHints) requestConfig.disable_high_entropy_client_hints = true;
1902
1930
 
1903
1931
  const bodyPtr = bodyBuffer || Buffer.alloc(0);
1904
1932
  const bodyLen = bodyBuffer ? bodyBuffer.length : 0;
@@ -1929,7 +1957,7 @@ class Session {
1929
1957
  * @returns {Promise<Response>} Response object
1930
1958
  */
1931
1959
  get(url, options = {}) {
1932
- const { headers = null, params = null, cookies = null, auth = null, fetchMode = null, timeout = null, allowRedirects = null, disableConditionalCache = false, signal = null } = options;
1960
+ const { headers = null, params = null, cookies = null, auth = null, fetchMode = null, timeout = null, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false, signal = null } = options;
1933
1961
 
1934
1962
  url = addParamsToUrl(url, params);
1935
1963
  let mergedHeaders = this._mergeHeaders(headers);
@@ -1958,6 +1986,12 @@ class Session {
1958
1986
  if (disableConditionalCache) {
1959
1987
  reqOptions.disable_conditional_cache = true;
1960
1988
  }
1989
+ if (disableClientHints) {
1990
+ reqOptions.disable_client_hints = true;
1991
+ }
1992
+ if (disableHighEntropyClientHints) {
1993
+ reqOptions.disable_high_entropy_client_hints = true;
1994
+ }
1961
1995
  const optionsJson = Object.keys(reqOptions).length > 0 ? JSON.stringify(reqOptions) : null;
1962
1996
 
1963
1997
  // Register async request with callback manager
@@ -1978,7 +2012,7 @@ class Session {
1978
2012
  * @returns {Promise<Response>} Response object
1979
2013
  */
1980
2014
  post(url, options = {}) {
1981
- let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, fetchMode = null, timeout = null, allowRedirects = null, disableConditionalCache = false, signal = null } = options;
2015
+ let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, fetchMode = null, timeout = null, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false, signal = null } = options;
1982
2016
 
1983
2017
  url = addParamsToUrl(url, params);
1984
2018
  let mergedHeaders = this._mergeHeaders(headers);
@@ -2044,6 +2078,12 @@ class Session {
2044
2078
  if (disableConditionalCache) {
2045
2079
  reqOptions.disable_conditional_cache = true;
2046
2080
  }
2081
+ if (disableClientHints) {
2082
+ reqOptions.disable_client_hints = true;
2083
+ }
2084
+ if (disableHighEntropyClientHints) {
2085
+ reqOptions.disable_high_entropy_client_hints = true;
2086
+ }
2047
2087
  if (bodyEncoding) {
2048
2088
  reqOptions.body_encoding = bodyEncoding;
2049
2089
  }
@@ -2068,7 +2108,7 @@ class Session {
2068
2108
  * @returns {Promise<Response>} Response object
2069
2109
  */
2070
2110
  request(method, url, options = {}) {
2071
- let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, timeout = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false, signal = null } = options;
2111
+ let { body = null, json = null, data = null, files = null, headers = null, params = null, cookies = null, auth = null, timeout = null, fetchMode = null, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false, signal = null } = options;
2072
2112
 
2073
2113
  url = addParamsToUrl(url, params);
2074
2114
  let mergedHeaders = this._mergeHeaders(headers);
@@ -2126,6 +2166,8 @@ class Session {
2126
2166
  if (fetchMode) requestConfig.fetch_mode = fetchMode;
2127
2167
  if (allowRedirects !== null && allowRedirects !== undefined) requestConfig.follow_redirects = !!allowRedirects;
2128
2168
  if (disableConditionalCache) requestConfig.disable_conditional_cache = true;
2169
+ if (disableClientHints) requestConfig.disable_client_hints = true;
2170
+ if (disableHighEntropyClientHints) requestConfig.disable_high_entropy_client_hints = true;
2129
2171
 
2130
2172
  // Register async request with callback manager
2131
2173
  const manager = getAsyncManager();
@@ -2359,6 +2401,44 @@ class Session {
2359
2401
  return this._lib.httpcloak_session_get_conditional_cache(this._handle) !== 0;
2360
2402
  }
2361
2403
 
2404
+ /**
2405
+ * Toggle the session's client-hints handling at runtime (full strip).
2406
+ * When disabled, the session drops ALL sec-ch-ua client hints, including
2407
+ * the always-on trio (sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform).
2408
+ * The change takes effect on the next request and persists until set again.
2409
+ * @param {boolean} enabled
2410
+ */
2411
+ setClientHints(enabled) {
2412
+ this._lib.httpcloak_session_set_client_hints(this._handle, enabled ? 1 : 0);
2413
+ }
2414
+
2415
+ /**
2416
+ * Return the session's current client-hints state.
2417
+ * @returns {boolean}
2418
+ */
2419
+ getClientHints() {
2420
+ return this._lib.httpcloak_session_get_client_hints(this._handle) !== 0;
2421
+ }
2422
+
2423
+ /**
2424
+ * Toggle the session's high-entropy client-hints handling at runtime.
2425
+ * When disabled, the session keeps the always-on trio but drops only the
2426
+ * high-entropy Accept-CH hints (e.g. sec-ch-ua-platform-version, -arch,
2427
+ * -model, -bitness, -full-version-list). Takes effect on the next request.
2428
+ * @param {boolean} enabled
2429
+ */
2430
+ setHighEntropyClientHints(enabled) {
2431
+ this._lib.httpcloak_session_set_high_entropy_client_hints(this._handle, enabled ? 1 : 0);
2432
+ }
2433
+
2434
+ /**
2435
+ * Return the session's current high-entropy client-hints state.
2436
+ * @returns {boolean}
2437
+ */
2438
+ getHighEntropyClientHints() {
2439
+ return this._lib.httpcloak_session_get_high_entropy_client_hints(this._handle) !== 0;
2440
+ }
2441
+
2362
2442
  /**
2363
2443
  * Toggle the session's redirect-following policy at runtime. The change
2364
2444
  * takes effect on the next request and persists until set again.
@@ -2689,7 +2769,7 @@ class Session {
2689
2769
  * stream.close();
2690
2770
  */
2691
2771
  getStream(url, options = {}) {
2692
- const { params, headers, cookies, timeout, allowRedirects = null, disableConditionalCache = false } = options;
2772
+ const { params, headers, cookies, timeout, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false } = options;
2693
2773
 
2694
2774
  // Add params to URL
2695
2775
  if (params) {
@@ -2722,6 +2802,12 @@ class Session {
2722
2802
  if (disableConditionalCache) {
2723
2803
  reqOptions.disable_conditional_cache = true;
2724
2804
  }
2805
+ if (disableClientHints) {
2806
+ reqOptions.disable_client_hints = true;
2807
+ }
2808
+ if (disableHighEntropyClientHints) {
2809
+ reqOptions.disable_high_entropy_client_hints = true;
2810
+ }
2725
2811
  const optionsJson = Object.keys(reqOptions).length > 0 ? JSON.stringify(reqOptions) : null;
2726
2812
 
2727
2813
  // Start stream
@@ -2761,7 +2847,7 @@ class Session {
2761
2847
  * @returns {StreamResponse} - Streaming response for chunked reading
2762
2848
  */
2763
2849
  postStream(url, options = {}) {
2764
- const { body: bodyOpt, json: jsonBody, form, params, headers, cookies, timeout, allowRedirects = null, disableConditionalCache = false } = options;
2850
+ const { body: bodyOpt, json: jsonBody, form, params, headers, cookies, timeout, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false } = options;
2765
2851
 
2766
2852
  // Add params to URL
2767
2853
  if (params) {
@@ -2807,6 +2893,12 @@ class Session {
2807
2893
  if (disableConditionalCache) {
2808
2894
  reqOptions.disable_conditional_cache = true;
2809
2895
  }
2896
+ if (disableClientHints) {
2897
+ reqOptions.disable_client_hints = true;
2898
+ }
2899
+ if (disableHighEntropyClientHints) {
2900
+ reqOptions.disable_high_entropy_client_hints = true;
2901
+ }
2810
2902
  const optionsJson = Object.keys(reqOptions).length > 0 ? JSON.stringify(reqOptions) : null;
2811
2903
 
2812
2904
  // Start stream
@@ -2845,7 +2937,7 @@ class Session {
2845
2937
  * @returns {StreamResponse} - Streaming response for chunked reading
2846
2938
  */
2847
2939
  requestStream(method, url, options = {}) {
2848
- const { body, params, headers, cookies, timeout, allowRedirects = null, disableConditionalCache = false } = options;
2940
+ const { body, params, headers, cookies, timeout, allowRedirects = null, disableConditionalCache = false, disableClientHints = false, disableHighEntropyClientHints = false } = options;
2849
2941
 
2850
2942
  // Add params to URL
2851
2943
  if (params) {
@@ -2884,6 +2976,12 @@ class Session {
2884
2976
  if (disableConditionalCache) {
2885
2977
  requestConfig.disable_conditional_cache = true;
2886
2978
  }
2979
+ if (disableClientHints) {
2980
+ requestConfig.disable_client_hints = true;
2981
+ }
2982
+ if (disableHighEntropyClientHints) {
2983
+ requestConfig.disable_high_entropy_client_hints = true;
2984
+ }
2887
2985
 
2888
2986
  // Start stream
2889
2987
  const streamHandle = this._lib.httpcloak_stream_request(this._handle, JSON.stringify(requestConfig));
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/darwin-arm64",
3
- "version": "1.6.7",
3
+ "version": "1.6.8-beta.1",
4
4
  "description": "HTTPCloak native binary for darwin arm64",
5
5
  "os": [
6
6
  "darwin"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/darwin-x64",
3
- "version": "1.6.7",
3
+ "version": "1.6.8-beta.1",
4
4
  "description": "HTTPCloak native binary for darwin x64",
5
5
  "os": [
6
6
  "darwin"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/linux-arm64",
3
- "version": "1.6.7",
3
+ "version": "1.6.8-beta.1",
4
4
  "description": "HTTPCloak native binary for linux arm64",
5
5
  "os": [
6
6
  "linux"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/linux-x64",
3
- "version": "1.6.7",
3
+ "version": "1.6.8-beta.1",
4
4
  "description": "HTTPCloak native binary for linux x64",
5
5
  "os": [
6
6
  "linux"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/win32-x64",
3
- "version": "1.6.7",
3
+ "version": "1.6.8-beta.1",
4
4
  "description": "HTTPCloak native binary for win32 x64",
5
5
  "os": [
6
6
  "win32"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "httpcloak",
3
- "version": "1.6.7",
3
+ "version": "1.6.8-beta.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,11 +49,11 @@
49
49
  "koffi": "^2.9.0"
50
50
  },
51
51
  "optionalDependencies": {
52
- "@httpcloak/darwin-arm64": "1.6.7",
53
- "@httpcloak/darwin-x64": "1.6.7",
54
- "@httpcloak/linux-arm64": "1.6.7",
55
- "@httpcloak/linux-x64": "1.6.7",
56
- "@httpcloak/win32-x64": "1.6.7"
52
+ "@httpcloak/darwin-arm64": "1.6.8-beta.1",
53
+ "@httpcloak/darwin-x64": "1.6.8-beta.1",
54
+ "@httpcloak/linux-arm64": "1.6.8-beta.1",
55
+ "@httpcloak/linux-x64": "1.6.8-beta.1",
56
+ "@httpcloak/win32-x64": "1.6.8-beta.1"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/node": "^25.1.0",