diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 5723611cd12f6d..d3953f5b6ec616 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -38,8 +38,6 @@ const { owner_symbol } = require('internal/async_hooks').symbols; const { convertToValidSignal } = require('internal/util'); const { isArrayBufferView } = require('internal/util/types'); const spawn_sync = internalBinding('spawn_sync'); -const { HTTPParser } = internalBinding('http_parser'); -const { freeParser } = require('_http_common'); const { kStateSymbol } = require('internal/dgram'); const { @@ -57,6 +55,10 @@ const { SocketListSend, SocketListReceive } = SocketList; // Lazy loaded for startup performance. let StringDecoder; +// Lazy loaded for startup performance and to allow monkey patching of +// internalBinding('http_parser').HTTPParser. +let freeParser; +let HTTPParser; const MAX_HANDLE_RETRANSMISSIONS = 3; @@ -121,6 +123,12 @@ const handleConversion = { handle.onread = nop; socket._handle = null; socket.setTimeout(0); + + if (freeParser === undefined) + freeParser = require('_http_common').freeParser; + if (HTTPParser === undefined) + HTTPParser = internalBinding('http_parser').HTTPParser; + // In case of an HTTP connection socket, release the associated // resources if (socket.parser && socket.parser instanceof HTTPParser) { diff --git a/test/parallel/test-http-parser-lazy-loaded.js b/test/parallel/test-http-parser-lazy-loaded.js new file mode 100644 index 00000000000000..c1eb29fb163d00 --- /dev/null +++ b/test/parallel/test-http-parser-lazy-loaded.js @@ -0,0 +1,37 @@ +// Flags: --expose-internals + +'use strict'; + +const { internalBinding } = require('internal/test/binding'); + +// Monkey patch before requiring anything +class DummyParser { + constructor(type) { + this.test_type = type; + } +} +DummyParser.REQUEST = Symbol(); +internalBinding('http_parser').HTTPParser = DummyParser; + +const common = require('../common'); +const assert = require('assert'); +const { spawn } = require('child_process'); +const { parsers } = require('_http_common'); + +// Test _http_common was not loaded before monkey patching +const parser = parsers.alloc(); +assert.strictEqual(parser instanceof DummyParser, true); +assert.strictEqual(parser.test_type, DummyParser.REQUEST); + +if (process.argv[2] !== 'child') { + // Also test in a child process with IPC (specific case of https://github.com/nodejs/node/issues/23716) + const child = spawn(process.execPath, [ + '--expose-internals', __filename, 'child' + ], { + stdio: ['inherit', 'inherit', 'inherit', 'ipc'] + }); + child.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); +}