@browsercore/testing 0.2.1 → 0.2.3

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 CHANGED
@@ -73,6 +73,16 @@ console.log(result.matches);
73
73
  // Benchmark a TLS handshake over 100 iterations (stub — throws until implemented):
74
74
  // const stats = benchmarkTlsHandshake(100);
75
75
  // console.log("p99:", stats.p99, "ms");
76
+
77
+ // Fingerprint a ClientHello and an HTTP/2 connection (Cat 4):
78
+ import { computeJa3, buildAkamaiFingerprint } from "@browsercore/testing";
79
+ const ja3 = computeJa3(clientHelloBytes);
80
+ const akamai = buildAkamaiFingerprint({
81
+ settings: [{ id: 1, value: 65536 }],
82
+ windowUpdateIncrement: 15663105,
83
+ priorityFrameCount: 0,
84
+ pseudoHeaderOrder: [":method", ":authority", ":scheme", ":path"],
85
+ });
76
86
  ```
77
87
 
78
88
  ## Types
@@ -86,6 +96,9 @@ console.log(result.matches);
86
96
  | `runHttp1Compliance()` | function | HTTP/1.1 RFC 9110 compliance suite |
87
97
  | `benchmarkTlsHandshake()` | function | TLS handshake benchmark |
88
98
  | `benchmarkHttp2Request()` | function | HTTP/2 request benchmark |
99
+ | `computeJa3()` | function | JA3 TLS ClientHello fingerprint digest |
100
+ | `computeJa4()` | function | JA4 four-part TLS ClientHello fingerprint tag |
101
+ | `buildAkamaiFingerprint()` | function | Akamai HTTP/2 fingerprint string from connection params |
89
102
  | `GoldenCapture` | interface | A recorded packet capture |
90
103
  | `ComparisonResult` | interface | Outcome of a golden comparison |
91
104
  | `BenchStats` | interface | p50/p95/p99 latency stats |
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Akamai HTTP/2 fingerprint (docs/TEST-SUITE.md, Category 4).
3
+ *
4
+ * The "Akamai fingerprint" (a.k.a. the HTTP/2 fingerprint popularized by
5
+ * Akamai's bot-detection research) serializes a connection's HTTP/2
6
+ * signature into a single pipe-delimited string:
7
+ *
8
+ * SETTINGS|WINDOW_UPDATE|PRIORITY_FRAMES|PSEUDO_HEADER_ORDER
9
+ *
10
+ * where:
11
+ * SETTINGS = `id:value;id:value;…` — each SETTINGS parameter in
12
+ * the order the client emitted it (RFC 9113 §6.5.2).
13
+ * WINDOW_UPDATE = the single connection-level WINDOW_UPDATE increment
14
+ * the client sent in its preface.
15
+ * PRIORITY_FRAMES = count of PRIORITY frames in the connection preface.
16
+ * PSEUDO_HEADER_ORDER = comma-joined single-letter codes for the pseudo
17
+ * header order on the first request
18
+ * (`:method`→m, `:authority`→a, `:scheme`→s,
19
+ * `:path`→p).
20
+ *
21
+ * Example Chrome 131 string:
22
+ * `1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p`
23
+ *
24
+ * This is an HTTP-layer fingerprint — independent of the TLS ClientHello
25
+ * parsing in {@link ./ja4.ts}.
26
+ */
27
+ /** HTTP/2 SETTINGS parameter identifiers (RFC 9113 §6.5.2). */
28
+ export declare const H2_SETTINGS: {
29
+ /** SETTINGS_HEADER_TABLE_SIZE. */
30
+ readonly HEADER_TABLE_SIZE: 1;
31
+ /** SETTINGS_ENABLE_PUSH. */
32
+ readonly ENABLE_PUSH: 2;
33
+ /** SETTINGS_MAX_CONCURRENT_STREAMS. */
34
+ readonly MAX_CONCURRENT_STREAMS: 3;
35
+ /** SETTINGS_INITIAL_WINDOW_SIZE. */
36
+ readonly INITIAL_WINDOW_SIZE: 4;
37
+ /** SETTINGS_MAX_FRAME_SIZE. */
38
+ readonly MAX_FRAME_SIZE: 5;
39
+ /** SETTINGS_MAX_HEADER_LIST_SIZE. */
40
+ readonly MAX_HEADER_LIST_SIZE: 6;
41
+ /** SETTINGS_ENABLE_CONNECT_PROTOCOL. */
42
+ readonly ENABLE_CONNECT_PROTOCOL: 8;
43
+ };
44
+ /** A single HTTP/2 SETTINGS parameter, in the wire order it was sent. */
45
+ export interface H2Setting {
46
+ /** IANA SETTINGS identifier (e.g. 1 for HEADER_TABLE_SIZE). */
47
+ readonly id: number;
48
+ /** The parameter value as a 32-bit unsigned integer. */
49
+ readonly value: number;
50
+ }
51
+ /** The four HTTP/2 request pseudo-headers (RFC 9113 §8.1). */
52
+ export type H2PseudoHeader = ":method" | ":authority" | ":scheme" | ":path";
53
+ /**
54
+ * HTTP/2 connection parameters needed to build the Akamai fingerprint.
55
+ *
56
+ * `settings` is in the order the client emitted them — Akamai fingerprinting
57
+ * is order-sensitive, so callers must preserve wire order. `pseudoHeaderOrder`
58
+ * is the order of pseudo-headers on the first (HEADERS) request.
59
+ */
60
+ export interface AkamaiFingerprintInput {
61
+ /** SETTINGS parameters in wire order. */
62
+ readonly settings: readonly H2Setting[];
63
+ /** Connection-level WINDOW_UPDATE increment sent in the preface. */
64
+ readonly windowUpdateIncrement: number;
65
+ /** Number of PRIORITY frames in the connection preface. */
66
+ readonly priorityFrameCount: number;
67
+ /** Pseudo-header order of the first request. */
68
+ readonly pseudoHeaderOrder: readonly H2PseudoHeader[];
69
+ }
70
+ /**
71
+ * Build the Akamai HTTP/2 fingerprint string from connection parameters.
72
+ *
73
+ * The result is `SETTINGS|WINDOW_UPDATE|PRIORITY_FRAMES|PSEUDO_HEADER_ORDER`.
74
+ * An empty SETTINGS list serializes to an empty segment (leading `|`).
75
+ */
76
+ export declare function buildAkamaiFingerprint(input: AkamaiFingerprintInput): string;
77
+ //# sourceMappingURL=akamai-http2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"akamai-http2.d.ts","sourceRoot":"","sources":["../../src/fingerprint/akamai-http2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,+DAA+D;AAC/D,eAAO,MAAM,WAAW;IACpB,kCAAkC;aAClC,iBAAiB,EAAE,CAAC;IACpB,4BAA4B;aAC5B,WAAW,EAAE,CAAC;IACd,uCAAuC;aACvC,sBAAsB,EAAE,CAAC;IACzB,oCAAoC;aACpC,mBAAmB,EAAE,CAAC;IACtB,+BAA+B;aAC/B,cAAc,EAAE,CAAC;IACjB,qCAAqC;aACrC,oBAAoB,EAAE,CAAC;IACvB,wCAAwC;aACxC,uBAAuB,EAAE,CAAC;CACpB,CAAC;AAEX,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAED,8DAA8D;AAC9D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACnC,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,oEAAoE;IACpE,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,iBAAiB,EAAE,SAAS,cAAc,EAAE,CAAC;CACzD;AAgBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAW5E"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Akamai HTTP/2 fingerprint (docs/TEST-SUITE.md, Category 4).
3
+ *
4
+ * The "Akamai fingerprint" (a.k.a. the HTTP/2 fingerprint popularized by
5
+ * Akamai's bot-detection research) serializes a connection's HTTP/2
6
+ * signature into a single pipe-delimited string:
7
+ *
8
+ * SETTINGS|WINDOW_UPDATE|PRIORITY_FRAMES|PSEUDO_HEADER_ORDER
9
+ *
10
+ * where:
11
+ * SETTINGS = `id:value;id:value;…` — each SETTINGS parameter in
12
+ * the order the client emitted it (RFC 9113 §6.5.2).
13
+ * WINDOW_UPDATE = the single connection-level WINDOW_UPDATE increment
14
+ * the client sent in its preface.
15
+ * PRIORITY_FRAMES = count of PRIORITY frames in the connection preface.
16
+ * PSEUDO_HEADER_ORDER = comma-joined single-letter codes for the pseudo
17
+ * header order on the first request
18
+ * (`:method`→m, `:authority`→a, `:scheme`→s,
19
+ * `:path`→p).
20
+ *
21
+ * Example Chrome 131 string:
22
+ * `1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p`
23
+ *
24
+ * This is an HTTP-layer fingerprint — independent of the TLS ClientHello
25
+ * parsing in {@link ./ja4.ts}.
26
+ */
27
+ /** HTTP/2 SETTINGS parameter identifiers (RFC 9113 §6.5.2). */
28
+ export const H2_SETTINGS = {
29
+ /** SETTINGS_HEADER_TABLE_SIZE. */
30
+ HEADER_TABLE_SIZE: 1,
31
+ /** SETTINGS_ENABLE_PUSH. */
32
+ ENABLE_PUSH: 2,
33
+ /** SETTINGS_MAX_CONCURRENT_STREAMS. */
34
+ MAX_CONCURRENT_STREAMS: 3,
35
+ /** SETTINGS_INITIAL_WINDOW_SIZE. */
36
+ INITIAL_WINDOW_SIZE: 4,
37
+ /** SETTINGS_MAX_FRAME_SIZE. */
38
+ MAX_FRAME_SIZE: 5,
39
+ /** SETTINGS_MAX_HEADER_LIST_SIZE. */
40
+ MAX_HEADER_LIST_SIZE: 6,
41
+ /** SETTINGS_ENABLE_CONNECT_PROTOCOL. */
42
+ ENABLE_CONNECT_PROTOCOL: 8,
43
+ };
44
+ /** Single-letter Akamai code for a pseudo-header. */
45
+ function pseudoHeaderCode(header) {
46
+ switch (header) {
47
+ case ":method":
48
+ return "m";
49
+ case ":authority":
50
+ return "a";
51
+ case ":scheme":
52
+ return "s";
53
+ case ":path":
54
+ return "p";
55
+ }
56
+ }
57
+ /**
58
+ * Build the Akamai HTTP/2 fingerprint string from connection parameters.
59
+ *
60
+ * The result is `SETTINGS|WINDOW_UPDATE|PRIORITY_FRAMES|PSEUDO_HEADER_ORDER`.
61
+ * An empty SETTINGS list serializes to an empty segment (leading `|`).
62
+ */
63
+ export function buildAkamaiFingerprint(input) {
64
+ const settingsPart = input.settings
65
+ .map((s) => `${s.id}:${s.value}`)
66
+ .join(";");
67
+ const pseudoPart = input.pseudoHeaderOrder.map(pseudoHeaderCode).join(",");
68
+ return [
69
+ settingsPart,
70
+ String(input.windowUpdateIncrement),
71
+ String(input.priorityFrameCount),
72
+ pseudoPart,
73
+ ].join("|");
74
+ }
75
+ //# sourceMappingURL=akamai-http2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"akamai-http2.js","sourceRoot":"","sources":["../../src/fingerprint/akamai-http2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,kCAAkC;IAClC,iBAAiB,EAAE,CAAC;IACpB,4BAA4B;IAC5B,WAAW,EAAE,CAAC;IACd,uCAAuC;IACvC,sBAAsB,EAAE,CAAC;IACzB,oCAAoC;IACpC,mBAAmB,EAAE,CAAC;IACtB,+BAA+B;IAC/B,cAAc,EAAE,CAAC;IACjB,qCAAqC;IACrC,oBAAoB,EAAE,CAAC;IACvB,wCAAwC;IACxC,uBAAuB,EAAE,CAAC;CACpB,CAAC;AA+BX,qDAAqD;AACrD,SAAS,gBAAgB,CAAC,MAAsB;IAC5C,QAAQ,MAAM,EAAE,CAAC;QACb,KAAK,SAAS;YACV,OAAO,GAAG,CAAC;QACf,KAAK,YAAY;YACb,OAAO,GAAG,CAAC;QACf,KAAK,SAAS;YACV,OAAO,GAAG,CAAC;QACf,KAAK,OAAO;YACR,OAAO,GAAG,CAAC;IACnB,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAA6B;IAChE,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;SAChC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,MAAM,UAAU,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3E,OAAO;QACH,YAAY;QACZ,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC;QAChC,UAAU;KACb,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChB,CAAC"}
@@ -5,4 +5,6 @@ export { computeJa4, computeJa4Fingerprint, Ja4ParseError } from "./ja4.js";
5
5
  export type { Ja4ClientHello, Ja4Fingerprint } from "./ja4.js";
6
6
  export { computeJa4h } from "./ja4h.js";
7
7
  export type { Ja4hFingerprint, Ja4hRequest } from "./ja4h.js";
8
+ export { buildAkamaiFingerprint, H2_SETTINGS } from "./akamai-http2.js";
9
+ export type { AkamaiFingerprintInput, H2PseudoHeader, H2Setting, } from "./akamai-http2.js";
8
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fingerprint/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC5E,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fingerprint/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC5E,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG9D,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACxE,YAAY,EACR,sBAAsB,EACtB,cAAc,EACd,SAAS,GACZ,MAAM,mBAAmB,CAAC"}
@@ -2,4 +2,6 @@
2
2
  export { computeJa3, parseClientHello, Ja3ParseError } from "./ja3.js";
3
3
  export { computeJa4, computeJa4Fingerprint, Ja4ParseError } from "./ja4.js";
4
4
  export { computeJa4h } from "./ja4h.js";
5
+ // Akamai HTTP/2 fingerprint string builder (Cat 4).
6
+ export { buildAkamaiFingerprint, H2_SETTINGS } from "./akamai-http2.js";
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fingerprint/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEvE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fingerprint/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEvE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxC,oDAAoD;AACpD,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -30,6 +30,8 @@ export { createReferenceProvider, CurlImpersonateProvider, RealBrowserCapturePro
30
30
  export type { CurlImpersonateOptions, Fingerprint, RealBrowserOptions, ReferenceProvider, ReferenceProviderKind, } from "./reference/reference.js";
31
31
  export { computeJa3, computeJa4, Ja3ParseError, parseClientHello } from "./fingerprint/index.js";
32
32
  export type { Ja3Segments } from "./fingerprint/index.js";
33
+ export { buildAkamaiFingerprint, H2_SETTINGS, } from "./fingerprint/index.js";
34
+ export type { AkamaiFingerprintInput, H2PseudoHeader, H2Setting, } from "./fingerprint/index.js";
33
35
  export { nodeCrypto, nodeDns, nodeZlib, nodeHttp, toError, compareBytesOutcome, } from "./reference/node-reference.js";
34
36
  export type { CompareOutcome, HashAlgorithm } from "./reference/node-reference.js";
35
37
  export { TlsSinkServer } from "./e2e/sink-server.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE,YAAY,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3F,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,CAGrE;AAGD,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACR,sBAAsB,EACtB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1D,OAAO,EACH,UAAU,EACV,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,mBAAmB,GACtB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAOnF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAO7D,OAAO,EACH,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,uBAAuB,EACvB,QAAQ,EACR,qBAAqB,EACrB,uBAAuB,EACvB,GAAG,EACH,gBAAgB,EAChB,qBAAqB,GACxB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACR,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GACrB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5G,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -30,6 +30,8 @@ export async function loadCaptures() {
30
30
  export { createReferenceProvider, CurlImpersonateProvider, RealBrowserCaptureProvider, } from "./reference/reference.js";
31
31
  // Fingerprint computation (JA3 / JA4) for Cat 4.
32
32
  export { computeJa3, computeJa4, Ja3ParseError, parseClientHello } from "./fingerprint/index.js";
33
+ // Akamai HTTP/2 fingerprint string builder (Cat 4).
34
+ export { buildAkamaiFingerprint, H2_SETTINGS, } from "./fingerprint/index.js";
33
35
  // Node.js reference oracle — deterministic comparison target for the primitive
34
36
  // layers (crypto, dns, zlib, wire format). See src/reference/node-reference.ts.
35
37
  export { nodeCrypto, nodeDns, nodeZlib, nodeHttp, toError, compareBytesOutcome, } from "./reference/node-reference.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAchE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7E,sEAAsE;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAEpD,gEAAgE;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAIpD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAC9B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC;AAC7B,CAAC;AAED,wCAAwC;AACxC,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,GAC7B,MAAM,0BAA0B,CAAC;AASlC,iDAAiD;AACjD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGjG,+EAA+E;AAC/E,gFAAgF;AAChF,OAAO,EACH,UAAU,EACV,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,mBAAmB,GACtB,MAAM,+BAA+B,CAAC;AAGvC,iEAAiE;AACjE,yEAAyE;AACzE,8EAA8E;AAC9E,yEAAyE;AACzE,uDAAuD;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,uEAAuE;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,8EAA8E;AAC9E,2EAA2E;AAC3E,0EAA0E;AAC1E,yEAAyE;AACzE,kFAAkF;AAClF,OAAO,EACH,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,uBAAuB,EACvB,QAAQ,EACR,qBAAqB,EACrB,uBAAuB,EACvB,GAAG,EACH,gBAAgB,EAChB,qBAAqB,GACxB,MAAM,4BAA4B,CAAC;AAOpC,gFAAgF;AAChF,8EAA8E;AAC9E,uDAAuD;AACvD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAchE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE7E,sEAAsE;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAEpD,gEAAgE;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAIpD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAC9B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC;AAC7B,CAAC;AAED,wCAAwC;AACxC,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,GAC7B,MAAM,0BAA0B,CAAC;AASlC,iDAAiD;AACjD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGjG,oDAAoD;AACpD,OAAO,EACH,sBAAsB,EACtB,WAAW,GACd,MAAM,wBAAwB,CAAC;AAOhC,+EAA+E;AAC/E,gFAAgF;AAChF,OAAO,EACH,UAAU,EACV,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,mBAAmB,GACtB,MAAM,+BAA+B,CAAC;AAGvC,iEAAiE;AACjE,yEAAyE;AACzE,8EAA8E;AAC9E,yEAAyE;AACzE,uDAAuD;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,uEAAuE;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,8EAA8E;AAC9E,2EAA2E;AAC3E,0EAA0E;AAC1E,yEAAyE;AACzE,kFAAkF;AAClF,OAAO,EACH,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,uBAAuB,EACvB,QAAQ,EACR,qBAAqB,EACrB,uBAAuB,EACvB,GAAG,EACH,gBAAgB,EAChB,qBAAqB,GACxB,MAAM,4BAA4B,CAAC;AAOpC,gFAAgF;AAChF,8EAA8E;AAC9E,uDAAuD;AACvD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@browsercore/testing",
3
- "version": "0.2.1",
4
- "description": "Protocol verification \u2014 RFC compliance tests, browser golden packet captures, integration tests, and benchmarking.",
3
+ "version": "0.2.3",
4
+ "description": "Protocol verification — RFC compliance tests, browser golden packet captures, integration tests, and benchmarking.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/jverneuer/browsercore-testing.git"