Skip to content
File

Blob: src/node/internal/internal_http.ts

typescript64 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4// Copyright Joyent and Node contributors. All rights reserved. MIT license.
5 
6import {
7 ERR_INVALID_HTTP_TOKEN,
8 ERR_INVALID_CHAR,
9 ERR_HTTP_INVALID_HEADER_VALUE,
10} from 'node-internal:internal_errors';
11 
12const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
13/**
14 * Verifies that the given val is a valid HTTP token
15 * per the rules defined in RFC 7230
16 * See https://tools.ietf.org/html/rfc7230#section-3.2.6
17 */
18export function _checkIsHttpToken(val: string): boolean {
19 return tokenRegExp.test(val);
20}
21 
22const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
23/**
24 * True if val contains an invalid field-vchar
25 * field-value = *( field-content / obs-fold )
26 * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
27 * field-vchar = VCHAR / obs-text
28 */
29export function _checkInvalidHeaderChar(
30 val: number | string | ReadonlyArray<string>
31): boolean {
32 if (Array.isArray(val)) {
33 return val.some((v: string) => headerCharRegex.test(v));
34 }
35 return headerCharRegex.test(`${val}`);
36}
37 
38export function validateHeaderName(
39 name: string,
40 label: string = 'Header name'
41): void {
42 if (typeof name !== 'string' || !name || !_checkIsHttpToken(name)) {
43 throw new ERR_INVALID_HTTP_TOKEN(label, name);
44 }
45}
46 
47export function validateHeaderValue(
48 name: string,
49 value: number | string | ReadonlyArray<string> | undefined
50): asserts value is string {
51 if (value === undefined) {
52 throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
53 }
54 if (_checkInvalidHeaderChar(value)) {
55 throw new ERR_INVALID_CHAR('header content', name);
56 }
57}
58 
59export function utcDate(): string {
60 return new Date().toUTCString();
61}
62 
63export const chunkExpression = /(?:^|\W)chunked(?:$|\W)/i;