summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormash-graz <mash-graz@users.noreply.github.com>2024-03-10 23:46:05 +0100
committerGitHub <noreply@github.com>2024-03-10 22:46:05 +0000
commit16dbbfa64a5d2905580535c52c1db51d1cf5b89f (patch)
tree5cf86fd3955309a86149322dd2664d15b33c31ea
parent0e644503690f23ced5c13c5d3e59592ce1858018 (diff)
fix(node:http) Export `validateHeaderName` and `validateHeaderValue` functions (#22616)
Modify `_http_outgoing.ts` to support the extended signature of `validateHeaderName()` used since node v19.5.0/v18.14.0 by adding the `label` parameter. (see: https://nodejs.org/api/http.html#httpvalidateheadernamename-label) Making both validation functions accessible as public exports of `node:http` Fixes: #22614
-rw-r--r--ext/node/polyfills/_http_outgoing.ts32
-rw-r--r--ext/node/polyfills/http.ts5
-rw-r--r--tests/node_compat/config.jsonc1
-rw-r--r--tests/node_compat/test/parallel/test-http-header-validators.js69
-rw-r--r--tools/node_compat/TODO.md3
5 files changed, 94 insertions, 16 deletions
diff --git a/ext/node/polyfills/_http_outgoing.ts b/ext/node/polyfills/_http_outgoing.ts
index 0cfc070e6..35526a303 100644
--- a/ext/node/polyfills/_http_outgoing.ts
+++ b/ext/node/polyfills/_http_outgoing.ts
@@ -820,21 +820,25 @@ Object.defineProperty(OutgoingMessage.prototype, "_headerNames", {
),
});
-export const validateHeaderName = hideStackFrames((name) => {
- if (typeof name !== "string" || !name || !checkIsHttpToken(name)) {
- throw new ERR_INVALID_HTTP_TOKEN("Header name", name);
- }
-});
+export const validateHeaderName = hideStackFrames(
+ (name: string, label?: string): void => {
+ if (typeof name !== "string" || !name || !checkIsHttpToken(name)) {
+ throw new ERR_INVALID_HTTP_TOKEN(label || "Header name", name);
+ }
+ },
+);
-export const validateHeaderValue = hideStackFrames((name, value) => {
- if (value === undefined) {
- throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
- }
- if (checkInvalidHeaderChar(value)) {
- debug('Header "%s" contains invalid characters', name);
- throw new ERR_INVALID_CHAR("header content", name);
- }
-});
+export const validateHeaderValue = hideStackFrames(
+ (name: string, value: string): void => {
+ if (value === undefined) {
+ throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
+ }
+ if (checkInvalidHeaderChar(value)) {
+ debug('Header "%s" contains invalid characters', name);
+ throw new ERR_INVALID_CHAR("header content", name);
+ }
+ },
+);
export function parseUniqueHeadersOption(headers) {
if (!Array.isArray(headers)) {
diff --git a/ext/node/polyfills/http.ts b/ext/node/polyfills/http.ts
index bcbf6674f..933a8dbcd 100644
--- a/ext/node/polyfills/http.ts
+++ b/ext/node/polyfills/http.ts
@@ -38,6 +38,7 @@ import {
OutgoingMessage,
parseUniqueHeadersOption,
validateHeaderName,
+ validateHeaderValue,
} from "ext:deno_node/_http_outgoing.ts";
import { ok as assert } from "node:assert";
import { kOutHeaders } from "ext:deno_node/internal/http.ts";
@@ -1824,6 +1825,8 @@ export {
METHODS,
OutgoingMessage,
STATUS_CODES,
+ validateHeaderName,
+ validateHeaderValue,
};
export default {
Agent,
@@ -1840,4 +1843,6 @@ export default {
ServerResponse,
request,
get,
+ validateHeaderName,
+ validateHeaderValue,
};
diff --git a/tests/node_compat/config.jsonc b/tests/node_compat/config.jsonc
index d84cc4dd2..3fde8be5a 100644
--- a/tests/node_compat/config.jsonc
+++ b/tests/node_compat/config.jsonc
@@ -365,6 +365,7 @@
// TODO(lev): ClientRequest.socket is not polyfilled so this test keeps
// failing
//"test-http-client-set-timeout.js",
+ "test-http-header-validators.js",
"test-http-localaddress.js",
// TODO(bartlomieju): temporarily disabled while we iterate on the HTTP client
// "test-http-outgoing-buffer.js",
diff --git a/tests/node_compat/test/parallel/test-http-header-validators.js b/tests/node_compat/test/parallel/test-http-header-validators.js
new file mode 100644
index 000000000..2b2f82339
--- /dev/null
+++ b/tests/node_compat/test/parallel/test-http-header-validators.js
@@ -0,0 +1,69 @@
+// deno-fmt-ignore-file
+// deno-lint-ignore-file
+
+// Copyright Joyent and Node contributors. All rights reserved. MIT license.
+// Taken from Node 18.12.1
+// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually.
+
+'use strict';
+require('../common');
+const assert = require('assert');
+const { validateHeaderName, validateHeaderValue } = require('http');
+
+// Expected static methods
+isFunc(validateHeaderName, 'validateHeaderName');
+isFunc(validateHeaderValue, 'validateHeaderValue');
+
+// Expected to be useful as static methods
+console.log('validateHeaderName');
+// - when used with valid header names - should not throw
+[
+ 'user-agent',
+ 'USER-AGENT',
+ 'User-Agent',
+ 'x-forwarded-for',
+].forEach((name) => {
+ console.log('does not throw for "%s"', name);
+ validateHeaderName(name);
+});
+
+// - when used with invalid header names:
+[
+ 'איקס-פורוורד-פור',
+ 'x-forwarded-fםr',
+].forEach((name) => {
+ console.log('throws for: "%s"', name.slice(0, 50));
+ assert.throws(
+ () => validateHeaderName(name),
+ { code: 'ERR_INVALID_HTTP_TOKEN' }
+ );
+});
+
+console.log('validateHeaderValue');
+// - when used with valid header values - should not throw
+[
+ ['x-valid', 1],
+ ['x-valid', '1'],
+ ['x-valid', 'string'],
+].forEach(([name, value]) => {
+ console.log('does not throw for "%s"', name);
+ validateHeaderValue(name, value);
+});
+
+// - when used with invalid header values:
+[
+ // [header, value, expectedCode]
+ ['x-undefined', undefined, 'ERR_HTTP_INVALID_HEADER_VALUE'],
+ ['x-bad-char', 'לא תקין', 'ERR_INVALID_CHAR'],
+].forEach(([name, value, code]) => {
+ console.log('throws %s for: "%s: %s"', code, name, value);
+ assert.throws(
+ () => validateHeaderValue(name, value),
+ { code }
+ );
+});
+
+// Misc.
+function isFunc(v, ttl) {
+ assert.ok(v.constructor === Function, `${ttl} is expected to be a function`);
+}
diff --git a/tools/node_compat/TODO.md b/tools/node_compat/TODO.md
index eb288c65e..d47ba9d9d 100644
--- a/tools/node_compat/TODO.md
+++ b/tools/node_compat/TODO.md
@@ -3,7 +3,7 @@
NOTE: This file should not be manually edited. Please edit `tests/node_compat/config.json` and run `deno task setup` in `tools/node_compat` dir instead.
-Total: 2999
+Total: 2998
- [abort/test-abort-backtrace.js](https://github.com/nodejs/node/tree/v18.12.1/test/abort/test-abort-backtrace.js)
- [abort/test-abort-fatal-error.js](https://github.com/nodejs/node/tree/v18.12.1/test/abort/test-abort-fatal-error.js)
@@ -1052,7 +1052,6 @@ Total: 2999
- [parallel/test-http-header-overflow.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-overflow.js)
- [parallel/test-http-header-owstext.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-owstext.js)
- [parallel/test-http-header-read.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-read.js)
-- [parallel/test-http-header-validators.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-header-validators.js)
- [parallel/test-http-hex-write.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-hex-write.js)
- [parallel/test-http-highwatermark.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-highwatermark.js)
- [parallel/test-http-host-header-ipv6-fail.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-host-header-ipv6-fail.js)