Skip to content

Commit 62d2d25

Browse files
authored
fix: remove dependency on node's _http_common module (#114)
* fix: remove dependency on node's `_http_common` module The checks is `isInvalidHeader` method are now backported from node's source. Both methods were just a regexp checks, so it was trivial to use the very same logic as in node. The implementation changed a bit, `checkInvalidHeaderChar` is now implemented via regexp check, and the `validateHeader` method was split into `validateHeaderName` and `validateHeaderValue`. Both regexps are taken from the latest code from master. Also verified the exiting test in node, but they seem to be aligned with the existing test suite (added only one additional assertion for `undefined`). Closes #50 * refactor: do not export internal helper methods
1 parent 77aa1f3 commit 62d2d25

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/tools.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { _checkIsHttpToken, _checkInvalidHeaderChar } from '_http_common'; // eslint-disable-line
2-
31
const HOST_HEADER_REGEX = /^((([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9]))(:([0-9]+))?$/;
42

53
/**
@@ -42,15 +40,35 @@ const HOP_BY_HOP_HEADERS_REGEX = new RegExp(`^(${HOP_BY_HOP_HEADERS.join('|')})$
4240

4341
export const isHopByHopHeader = (header) => HOP_BY_HOP_HEADERS_REGEX.test(header);
4442

43+
const TOKEN_REGEX = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
44+
45+
/**
46+
* Verifies that the given val is a valid HTTP token per the rules defined in RFC 7230
47+
* @see https://tools.ietf.org/html/rfc7230#section-3.2.6
48+
* @see https://github.com/nodejs/node/blob/8cf5ae07e9e80747c19e0fc04fad48423707f62c/lib/_http_common.js#L222
49+
*/
50+
const isHttpToken = (val) => TOKEN_REGEX.test(val);
51+
52+
const HEADER_CHAR_REGEX = /[^\t\x20-\x7e\x80-\xff]/;
53+
54+
/**
55+
* True if val contains an invalid field-vchar
56+
* field-value = *( field-content / obs-fold )
57+
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
58+
* field-vchar = VCHAR / obs-text
59+
* @see https://github.com/nodejs/node/blob/8cf5ae07e9e80747c19e0fc04fad48423707f62c/lib/_http_common.js#L233
60+
*/
61+
const isInvalidHeaderChar = (val) => HEADER_CHAR_REGEX.test(val);
62+
4563
// This code is based on Node.js' validateHeader() function from _http_outgoing.js module
4664
// (see https://github.com/nodejs/node/blob/189d29f39e6de9ccf10682bfd1341819b4a2291f/lib/_http_outgoing.js#L485)
4765
export const isInvalidHeader = (name, value) => {
4866
// NOTE: These are internal Node.js functions, they might stop working in the future!
4967
return typeof name !== 'string'
5068
|| !name
51-
|| !_checkIsHttpToken(name)
69+
|| !isHttpToken(name)
5270
|| value === undefined
53-
|| _checkInvalidHeaderChar(value);
71+
|| isInvalidHeaderChar(value);
5472
};
5573

5674
const bulletproofDecodeURIComponent = (encodedURIComponent) => {

test/tools.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ describe('tools.isInvalidHeader()', () => {
261261
it('works', () => {
262262
expect(isInvalidHeader('With space', 'a')).to.eql(true);
263263
expect(isInvalidHeader('', 'a')).to.eql(true);
264+
expect(isInvalidHeader(undefined, 'a')).to.eql(true);
264265
expect(isInvalidHeader(null, 'a')).to.eql(true);
265266
expect(isInvalidHeader(1234, 'a')).to.eql(true);
266267
expect(isInvalidHeader('\n', 'a')).to.eql(true);

0 commit comments

Comments
 (0)