Node.js: How HTTP Server Inherits Properties from NET Server?
Introduction
Last time, we traced the createServer function all the way from http.js to net.js. Through our exploration, we identified two core Server functions:
- One in
_http_server.js(which we call the HTTP Server function) - The other in
net.js(which we call the NET Server function)
Today, let me walk you through how the HTTP Server inherits instance properties directly from the NET Server.
HTTP Server Function
The HTTP Server function is defined in node/lib/_http_server.js:
function Server(options, requestListener) {
/* ... Omitted logic ... */
net.Server.call(
this,
{
allowHalfOpen: true,
noDelay: options.noDelay ?? true,
keepAlive: options.keepAlive,
keepAliveInitialDelay: options.keepAliveInitialDelay,
highWaterMark: options.highWaterMark
}
);
/* ... Omitted logic ... */
}As shown above, we access the NET Server constructor function from the net module directly inside the HTTP Server constructor.
We are able to use the net module here because it was imported at the top of the file:
const net = require('net');NET Server Function
The NET Server function is defined in node/lib/net.js:
function Server(options, connectionListener) {
/* ... Omitted logic ... */
this.allowHalfOpen = options.allowHalfOpen || false;
this.pauseOnConnect = !!options.pauseOnConnect;
this.noDelay = Boolean(options.noDelay);
this.keepAlive = Boolean(options.keepAlive);
this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
this.highWaterMark = options.highWaterMark ?? getDefaultHighWaterMark();
if (options.blockList) {
if (!module.exports.BlockList.isBlockList(options.blockList)) {
throw new ERR_INVALID_ARG_TYPE('options.blockList', 'net.BlockList', options.blockList);
}
this.blockList = options.blockList;
}
}How net.Server.call(this, ...) Works
Now that we can see both functions, how do they actually connect under the hood? The magic happens right at net.Server.call(...).
Get KAN Uiiu’s stories in your inbox
Join Medium for free to get updates from this writer.
This single line achieves two vital goals simultaneously:
1. Passing Arguments Down to NET Server
Instead of re-implementing TCP configurations in _http_server.js, the HTTP Server prepares a tailored options object (e.g., { allowHalfOpen: true, noDelay: ... }) and passes it down as arguments to the NET Server constructor.
2. Borrowing Constructor for Property Inheritance (Constructor Stealing)
In JavaScript, functions are objects with built-in utility methods inherited from Function.prototype. The .call() method allows us to invoke a function while explicitly specifying its this context.
When net.Server.call(this, options) is executed:
- The
thisSwap: Thethisinsidenet.Serveris forced to point to the newly created HTTP Server instance. - Property Injection: As
net.Serverexecutes line by line (this.allowHalfOpen = ...,this.noDelay = ...), it directly attaches all these TCP-related properties onto the HTTP Server instance.
[ HTTP Server Instance (this) ]
│
▼ <-- Passed into net.Server.call(this, options)
┌─────────────────────────────────────────┐
│ net.Server executes: │
│ this.allowHalfOpen = options.allow... │
│ this.noDelay = options.noDelay │
└─────────────────────────────────────────┘
│
▼
[ HTTP Server Instance now holds all NET Server Properties! ]Key Takeaway
Through
.call(this, options), the HTTP Server passes configurations down to the NET Server while borrowing its constructor to initialize and populate TCP properties on its own instance.I am going to share those detailed options in the NET Server soon. Stay tuned!
Before You Leave
If you found this article helpful or inspiring, please leave a comment or give it a few claps 👏. Also, feel free to follow my HackMD and Medium for more deep dives into Node.js internals later!





