Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -4281,18 +4281,21 @@ The support for priority signaling has been removed following its deprecation in

<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/64853
description: Runtime deprecation.
- version:
- v24.2.0
- v22.17.0
pr-url: https://github.com/nodejs/node/pull/58518
description: Documentation-only deprecation.
-->

Type: Documentation-only
Type: Runtime

Instantiating classes without the `new` qualifier exported by the `node:http` module is deprecated.
It is recommended to use the `new` qualifier instead. This applies to all http classes, such as
`OutgoingMessage`, `IncomingMessage`, `ServerResponse` and `ClientRequest`.
`OutgoingMessage`, `IncomingMessage`, `ServerResponse`, `ClientRequest`, `Server`, and `Agent`.

An automated migration is available ([source](https://github.com/nodejs/userland-migrations/tree/main/recipes/http-classes-with-new)):

Expand Down
6 changes: 4 additions & 2 deletions lib/_http_agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const {
const { AsyncResource } = require('async_hooks');
const { async_id_symbol } = require('internal/async_hooks').symbols;
const {
deprecateInstantiation,
getLazy,
kEmptyObject,
once,
Expand Down Expand Up @@ -88,8 +89,9 @@ function freeSocketErrorListener(err) {
}

function Agent(options) {
if (!(this instanceof Agent))
return new Agent(options);
if (!(this instanceof Agent)) {
return deprecateInstantiation(Agent, 'DEP0195', options);
}

EventEmitter.call(this);

Expand Down
5 changes: 5 additions & 0 deletions lib/_http_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const {
const net = require('net');
const assert = require('internal/assert');
const {
deprecateInstantiation,
kEmptyObject,
once,
} = require('internal/util');
Expand Down Expand Up @@ -190,6 +191,10 @@ function rewriteForProxiedHttp(req, reqOptions) {
};

function ClientRequest(input, options, cb) {
if (!(this instanceof ClientRequest)) {
return deprecateInstantiation(ClientRequest, 'DEP0195', input, options, cb);
}

OutgoingMessage.call(this);

if (typeof input === 'string') {
Expand Down
7 changes: 7 additions & 0 deletions lib/_http_incoming.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const {
} = primordials;

const { Readable, finished } = require('stream');
const {
deprecateInstantiation,
} = require('internal/util');

const { AbortController } = require('internal/abort_controller');

Expand All @@ -51,6 +54,10 @@ function readStop(socket) {

/* Abstract base class for ServerRequest and ClientResponse. */
function IncomingMessage(socket) {
if (!(this instanceof IncomingMessage)) {
return deprecateInstantiation(IncomingMessage, 'DEP0195', socket);
}

let streamOptions;

if (socket) {
Expand Down
9 changes: 8 additions & 1 deletion lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ const {
hideStackFrames,
} = require('internal/errors');
const { validateString } = require('internal/validators');
const { assignFunctionName } = require('internal/util');
const {
assignFunctionName,
deprecateInstantiation,
} = require('internal/util');
const { isUint8Array } = require('internal/util/types');

let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
Expand Down Expand Up @@ -104,6 +107,10 @@ function isContentDispositionField(s) {
}

function OutgoingMessage(options) {
if (!(this instanceof OutgoingMessage)) {
return deprecateInstantiation(OutgoingMessage, 'DEP0195', options);
}

Stream.call(this);

// Queue that holds all currently pending data, until the response will be
Expand Down
9 changes: 8 additions & 1 deletion lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const {
} = require('internal/errors');
const {
assignFunctionName,
deprecateInstantiation,
kEmptyObject,
promisify,
} = require('internal/util');
Expand Down Expand Up @@ -202,6 +203,10 @@ class HTTPServerAsyncResource {
}

function ServerResponse(req, options) {
if (!(this instanceof ServerResponse)) {
return deprecateInstantiation(ServerResponse, 'DEP0195', req, options);
}

OutgoingMessage.call(this, options);

if (req.method === 'HEAD') this._hasBody = false;
Expand Down Expand Up @@ -627,7 +632,9 @@ function httpServerPreClose(server) {
}

function Server(options, requestListener) {
if (!(this instanceof Server)) return new Server(options, requestListener);
if (!(this instanceof Server)) {
return deprecateInstantiation(Server, 'DEP0195', options, requestListener);
}

if (typeof options === 'function') {
requestListener = options;
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-cluster-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ function forEach(obj, fn) {


if (cluster.isWorker) {
require('http').Server(common.mustNotCall()).listen(0, '127.0.0.1');
const http = require('http');
new http.Server(common.mustNotCall()).listen(0, '127.0.0.1');
} else if (cluster.isPrimary) {

const checks = {
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-cluster-primary-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const totalWorkers = 2;
// Cluster setup
if (cluster.isWorker) {
const http = require('http');
http.Server(() => {}).listen(0, '127.0.0.1');
new http.Server(() => {}).listen(0, '127.0.0.1');
} else if (process.argv[2] === 'cluster') {
// Send PID to testcase process
let forkNum = 0;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-cluster-primary-kill.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ if (cluster.isWorker) {

// Keep the worker alive
const http = require('http');
http.Server().listen(0, '127.0.0.1');
new http.Server().listen(0, '127.0.0.1');

} else if (process.argv[2] === 'cluster') {

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-cluster-rr-domain-listen.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ if (cluster.isWorker) {
d.run(() => {});

const http = require('http');
http.Server(() => {}).listen(0, '127.0.0.1');
new http.Server(() => {}).listen(0, '127.0.0.1');

} else if (cluster.isPrimary) {

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-cluster-worker-disconnect.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const cluster = require('cluster');

if (cluster.isWorker) {
const http = require('http');
http.Server(() => {
new http.Server(() => {

}).listen(0, '127.0.0.1');

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-cluster-worker-exit.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const EXIT_CODE = 42;

if (cluster.isWorker) {
const http = require('http');
const server = http.Server(() => { });
const server = new http.Server(() => { });

server.once('listening', common.mustCall(() => {
process.exit(EXIT_CODE);
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-cluster-worker-kill-signal.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const cluster = require('cluster');
if (cluster.isWorker) {
// Make the worker run something
const http = require('http');
const server = http.Server(() => { });
const server = new http.Server(() => { });

server.once('listening', common.mustCall());
server.listen(0, '127.0.0.1');
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-cluster-worker-kill.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const cluster = require('cluster');

if (cluster.isWorker) {
const http = require('http');
const server = http.Server(() => { });
const server = new http.Server(() => { });

server.once('listening', common.mustCall());
server.listen(0, '127.0.0.1');
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-abort-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const common = require('../common');
const http = require('http');

let serverRes;
const server = http.Server(common.mustCall((req, res) => {
const server = new http.Server(common.mustCall((req, res) => {
serverRes = res;
res.writeHead(200);
res.write('Part of my res.');
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const http = require('http');

const N = 4;
const M = 4;
const server = http.Server(common.mustCall(function(req, res) {
const server = new http.Server(common.mustCall(function(req, res) {
res.writeHead(200);
res.end('hello world\n');
}, (N * M))); // N * M = good requests (the errors will not be counted)
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-buffer-sanity.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ for (let i = 0; i < buffer.length; i++) {
buffer[i] = i % 256;
}

const server = http.Server(common.mustCallAtLeast(function(req, res) {
const server = new http.Server(common.mustCallAtLeast(function(req, res) {
server.close();

let i = 0;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-client-abort.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const N = 8;

const countdown = new Countdown(N, () => server.close());

const server = http.Server(common.mustCall((req, res) => {
const server = new http.Server(common.mustCall((req, res) => {
res.writeHead(200);
res.write('Working on it...');
req.on('aborted', common.mustCall(() => countdown.dec()));
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-http-client-aborted-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const http = require('http');

{
let serverRes;
const server = http.Server(function(req, res) {
const server = new http.Server(function(req, res) {
res.write('Part of my res.');
serverRes = res;
});
Expand All @@ -27,7 +27,7 @@ const http = require('http');
{
// Don't crash of no 'error' handler.
let serverRes;
const server = http.Server(function(req, res) {
const server = new http.Server(function(req, res) {
res.write('Part of my res.');
serverRes = res;
});
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-client-agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ let name;
const max = 3;
const agent = new http.Agent();

const server = http.Server(common.mustCall((req, res) => {
const server = new http.Server(common.mustCall((req, res) => {
if (req.url === '/0') {
setTimeout(common.mustCall(() => {
res.writeHead(200);
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-client-override-global-agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const common = require('../common');
const assert = require('assert');
const http = require('http');

const server = http.Server(common.mustCall((req, res) => {
const server = new http.Server(common.mustCall((req, res) => {
res.writeHead(200);
res.end('Hello, World!');
}));
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-client-spurious-aborted.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Countdown = require('../common/countdown');
const N = 2;
let abortRequest = true;

const server = http.Server(common.mustCall((req, res) => {
const server = new http.Server(common.mustCall((req, res) => {
const headers = { 'Content-Type': 'text/plain', 'Connection': 'close' };
headers['Content-Length'] = 50;
const socket = res.socket;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-default-encoding.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const http = require('http');
const expected = 'This is a unicode text: سلام';
let result = '';

const server = http.Server((req, res) => {
const server = new http.Server((req, res) => {
req.setEncoding('utf8');
req.on('data', (chunk) => {
result += chunk;
Expand Down
68 changes: 68 additions & 0 deletions test/parallel/test-http-dep0195.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const http = require('http');

// DEP0195: Instantiating node:http classes without `new` is runtime-deprecated.
// Deprecation codes warn once per process, so only the first call emits a warning.

common.expectWarning(
'DeprecationWarning',
"Instantiating Agent without the 'new' keyword has been deprecated.",
'DEP0195',
);

{
const agent = http.Agent();
assert.ok(agent instanceof http.Agent);
agent.destroy();
}

// Remaining classes still construct without `new` (same deprecation code; no
// additional warnings are emitted).
{
const server = http.Server();
assert.ok(server instanceof http.Server);
server.close();
}

{
const msg = http.OutgoingMessage();
assert.ok(msg instanceof http.OutgoingMessage);
}

{
const msg = http.IncomingMessage();
assert.ok(msg instanceof http.IncomingMessage);
}

{
const req = new http.IncomingMessage();
const res = http.ServerResponse(req);
assert.ok(res instanceof http.ServerResponse);
}

{
// ClientRequest begins a real request; provide a fake socket so nothing is
// dialed on the network.
const { Socket } = require('net');
const agent = new http.Agent();
agent.createConnection = common.mustCall((options, cb) => {
const socket = new Socket();
// Never connect; destroy immediately after construction completes.
process.nextTick(() => {
socket.destroy();
if (typeof cb === 'function') cb(new Error('stop'));
});
return socket;
});
const req = http.ClientRequest({
host: '127.0.0.1',
port: 1,
agent,
});
assert.ok(req instanceof http.ClientRequest);
req.on('error', common.mustCall());
req.destroy();
}
2 changes: 1 addition & 1 deletion test/parallel/test-http-get-pipeline-problem.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const responseCountdown = new Countdown(total, common.mustCall(() => {
server.close();
}));

const server = http.Server(function(req, res) {
const server = new http.Server(function(req, res) {
setTimeout(function() {
res.writeHead(200, {
'content-type': 'image/jpeg',
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-keepalive-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ server.listen(0, function() {
makeRequest(expectRequests);
});

const agent = http.Agent({ keepAlive: true });
const agent = new http.Agent({ keepAlive: true });


let clientSocket = null;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-keepalive-free.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ for (const method of ['abort', 'destroy']) {
res.end(req.url);
}));
server.listen(0, common.mustCall(() => {
const agent = http.Agent({ keepAlive: true });
const agent = new http.Agent({ keepAlive: true });

const req = http
.request({
Expand Down
Loading
Loading