Commit 296584b7af7 for nodejs

commit 296584b7af70b99f016a115958be3608d3506cd2
Author: James M Snell <jasnell@gmail.com>
Date:   Sun Sep 27 02:23:34 2026 +0000

    benchmark: add http header validator benchmark

    Compare http.isValidHeaderName() and http.isValidHeaderValue() with
    http.validateHeaderName() and http.validateHeaderValue() wrapped in
    try/catch, for valid and invalid input, and for both 'strict' and
    'relaxed' header value validation.

    Signed-off-by: James M Snell <jasnell@gmail.com>
    PR-URL: https://github.com/nodejs/node/pull/66334
    Reviewed-By: Filip Skokan <panva.ip@gmail.com>
    Reviewed-By: Tim Perry <pimterry@gmail.com>
    Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>

diff --git a/benchmark/http/is_valid_header.js b/benchmark/http/is_valid_header.js
new file mode 100644
index 00000000000..cefe5c1f87c
--- /dev/null
+++ b/benchmark/http/is_valid_header.js
@@ -0,0 +1,120 @@
+'use strict';
+
+// Compares the non-throwing header validators (http.isValidHeaderName() and
+// http.isValidHeaderValue()) with the throwing ones (http.validateHeaderName()
+// and http.validateHeaderValue()) used inside try/catch.
+
+const common = require('../common.js');
+const assert = require('assert');
+const {
+  isValidHeaderName,
+  isValidHeaderValue,
+  validateHeaderName,
+  validateHeaderValue,
+} = require('http');
+
+const inputs = {
+  name: {
+    valid: [
+      'ETag', 'date', 'Vary', 'server', 'Expires', 'location', 'Connection',
+      'content-type', 'Cache-Control', 'content-length', 'x-frame-options',
+      'Transfer-Encoding', 'x-request-id',
+    ],
+    invalid: [
+      '', ':', 'bad header', 'x-forwarded-fםr', '中文呢', '((((())))',
+      ':alternate-protocol', 'alternate-protocol:', 'x\r\ninjected',
+    ],
+  },
+  value: {
+    valid: [
+      'W/"2-d4cbb29"', 'OK', 'Express', 'application/json',
+      'application/json; charset=utf-8', 'sessionid=; Path=/',
+      'text/html; charset=utf-8', '10', 'max-age=0, no-cache', 'gzip, br',
+    ],
+    // Invalid under both 'strict' and 'relaxed' validation.
+    invalid: [
+      'a\r\nb', 'value\n', 'cr\r', 'nul\0byte', 'לא תקין', 'emoji \u{1F600}',
+      'x'.repeat(64) + '\r\n',
+    ],
+  },
+};
+
+const bench = common.createBenchmark(main, {
+  method: [
+    'isValidHeaderName',
+    'validateHeaderName',
+    'isValidHeaderValue',
+    'validateHeaderValue',
+  ],
+  input: ['valid', 'invalid'],
+  httpValidation: ['strict', 'relaxed'],
+  n: [1e6],
+}, {
+  // httpValidation only applies to isValidHeaderValue().
+  combinationFilter: (p) =>
+    p.httpValidation === 'strict' || p.method === 'isValidHeaderValue',
+});
+
+function main({ n, method, input, httpValidation }) {
+  let valid = 0;
+
+  switch (method) {
+    case 'isValidHeaderName': {
+      const list = inputs.name[input];
+      const len = list.length;
+      bench.start();
+      for (let i = 0; i < n; i++) {
+        if (isValidHeaderName(list[i % len])) valid++;
+      }
+      bench.end(n);
+      break;
+    }
+    case 'validateHeaderName': {
+      const list = inputs.name[input];
+      const len = list.length;
+      bench.start();
+      for (let i = 0; i < n; i++) {
+        try {
+          validateHeaderName(list[i % len]);
+          valid++;
+        } catch {
+          // Invalid name.
+        }
+      }
+      bench.end(n);
+      break;
+    }
+    case 'isValidHeaderValue': {
+      const list = inputs.value[input];
+      const len = list.length;
+      const options = httpValidation === 'strict' ? undefined : { httpValidation };
+      bench.start();
+      for (let i = 0; i < n; i++) {
+        if (isValidHeaderValue(list[i % len], options)) valid++;
+      }
+      bench.end(n);
+      break;
+    }
+    case 'validateHeaderValue': {
+      const list = inputs.value[input];
+      const len = list.length;
+      bench.start();
+      for (let i = 0; i < n; i++) {
+        try {
+          validateHeaderValue('x-header', list[i % len]);
+          valid++;
+        } catch {
+          // Invalid value.
+        }
+      }
+      bench.end(n);
+      break;
+    }
+    default:
+      throw new Error(`Unexpected method: ${method}`);
+  }
+
+  // Consume the result so the loop cannot be optimized away, and make sure
+  // the inputs are what they claim to be.
+  assert.strictEqual(valid, input === 'valid' ? n : 0);
+}