http2: remove support for priority signaling

Signed-off-by: Matteo Collina <hello@matteocollina.com>
Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
Refs: https://datatracker.ietf.org/doc/html/rfc9113#section-5.3.1
PR-URL: https://github.com/nodejs/node/pull/58293
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
Matteo Collina 2025-06-03 11:09:40 +02:00 committed by GitHub
parent 22685b8aaf
commit a63126409a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 81 additions and 84 deletions

View File

@ -3963,15 +3963,17 @@ an internal nodejs implementation rather than a public facing API, use `node:str
<!-- YAML <!-- YAML
changes: changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58293
description: End-of-Life.
- version: REPLACEME - version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58313 pr-url: https://github.com/nodejs/node/pull/58313
description: Documentation-only deprecation. description: Documentation-only deprecation.
--> -->
Type: Documentation-only Type: End-of-Life
The support for priority signaling has been deprecated in the [RFC 9113][], and The support for priority signaling has been removed following its deprecation in the [RFC 9113][].
will be removed in future versions of Node.js.
### DEP0195: Instantiating `node:http` classes without `new` ### DEP0195: Instantiating `node:http` classes without `new`

View File

@ -1072,6 +1072,10 @@ The `'origin'` event is only emitted when using a secure TLS connection.
<!-- YAML <!-- YAML
added: v8.4.0 added: v8.4.0
changes: changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58293
description: The `weight` option is now ignored, setting it will trigger a
runtime warning.
- version: REPLACEME - version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58313 pr-url: https://github.com/nodejs/node/pull/58313
description: Following the deprecation of priority signaling as of RFC 1993, description: Following the deprecation of priority signaling as of RFC 1993,
@ -1090,10 +1094,6 @@ changes:
**Default:** `false`. **Default:** `false`.
* `parent` {number} Specifies the numeric identifier of a stream the newly * `parent` {number} Specifies the numeric identifier of a stream the newly
created stream is dependent on. created stream is dependent on.
* `weight` {number} Specifies the relative dependency of a stream in relation
to other streams with the same `parent`. The value is a number between `1`
and `256` (inclusive). This has been **deprecated** in [RFC 9113][], and
support for it will be removed in future versions of Node.js.
* `waitForTrailers` {boolean} When `true`, the `Http2Stream` will emit the * `waitForTrailers` {boolean} When `true`, the `Http2Stream` will emit the
`'wantTrailers'` event after the final `DATA` frame has been sent. `'wantTrailers'` event after the final `DATA` frame has been sent.
* `signal` {AbortSignal} An AbortSignal that may be used to abort an ongoing * `signal` {AbortSignal} An AbortSignal that may be used to abort an ongoing
@ -1464,25 +1464,17 @@ numeric stream identifier.
<!-- YAML <!-- YAML
added: v8.4.0 added: v8.4.0
deprecated: REPLACEME deprecated: REPLACEME
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58293
description: This method no longer sets the priority of the stream. Using it
now triggers a runtime warning.
--> -->
> Stability: 0 - Deprecated: support for priority signaling has been deprecated > Stability: 0 - Deprecated: support for priority signaling has been deprecated
> in the [RFC 9113][] and is no longer supported in Node.js. > in the [RFC 9113][] and is no longer supported in Node.js.
* `options` {Object} Empty method, only there to maintain some backward compatibility.
* `exclusive` {boolean} When `true` and `parent` identifies a parent Stream,
this stream is made the sole direct dependency of the parent, with
all other existing dependents made a dependent of this stream. **Default:**
`false`.
* `parent` {number} Specifies the numeric identifier of a stream this stream
is dependent on.
* `weight` {number} Specifies the relative dependency of a stream in relation
to other streams with the same `parent`. The value is a number between `1`
and `256` (inclusive).
* `silent` {boolean} When `true`, changes the priority locally without
sending a `PRIORITY` frame to the connected peer.
Updates the priority for this `Http2Stream` instance.
#### `http2stream.rstCode` #### `http2stream.rstCode`
@ -1579,6 +1571,10 @@ req.setTimeout(5000, () => req.close(NGHTTP2_CANCEL));
<!-- YAML <!-- YAML
added: v8.4.0 added: v8.4.0
changes: changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58293
description: The `state.weight` property is now always set to 16 and
`sumDependencyWeight` is always set to 0.
- version: REPLACEME - version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58313 pr-url: https://github.com/nodejs/node/pull/58313
description: Following the deprecation of priority signaling as of RFC 1993, description: Following the deprecation of priority signaling as of RFC 1993,
@ -1596,13 +1592,8 @@ Provides miscellaneous information about the current state of the
* `localClose` {number} `1` if this `Http2Stream` has been closed locally. * `localClose` {number} `1` if this `Http2Stream` has been closed locally.
* `remoteClose` {number} `1` if this `Http2Stream` has been closed * `remoteClose` {number} `1` if this `Http2Stream` has been closed
remotely. remotely.
* `sumDependencyWeight` {number} The sum weight of all `Http2Stream` * `sumDependencyWeight` {number} Legacy property, always set to `0`.
instances that depend on this `Http2Stream` as specified using * `weight` {number} Legacy property, always set to `16`.
`PRIORITY` frames. This has been **deprecated** in [RFC 9113][], and
support for it will be removed in future versions of Node.js.
* `weight` {number} The priority weight of this `Http2Stream`. This has been
**deprecated** in [RFC 9113][], and support for it will be removed in future
versions of Node.js.
A current state of this `Http2Stream`. A current state of this `Http2Stream`.

View File

@ -30,6 +30,8 @@ const {
customInspectSymbol: kInspect, customInspectSymbol: kInspect,
kEmptyObject, kEmptyObject,
promisify, promisify,
deprecate,
deprecateProperty,
} = require('internal/util'); } = require('internal/util');
assertCrypto(); assertCrypto();
@ -747,6 +749,11 @@ function onGoawayData(code, lastStreamID, buf) {
} }
} }
// TODO(aduh95): remove this in future semver-major
const deprecateWeight = deprecateProperty('weight',
'Priority signaling has been deprecated as of RFC 1993.',
'DEP0194');
// When a ClientHttp2Session is first created, the socket may not yet be // When a ClientHttp2Session is first created, the socket may not yet be
// connected. If request() is called during this time, the actual request // connected. If request() is called during this time, the actual request
// will be deferred until the socket is ready to go. // will be deferred until the socket is ready to go.
@ -775,12 +782,14 @@ function requestOnConnect(headersList, headersParam, options) {
if (options.waitForTrailers) if (options.waitForTrailers)
streamOptions |= STREAM_OPTION_GET_TRAILERS; streamOptions |= STREAM_OPTION_GET_TRAILERS;
deprecateWeight(options);
// `ret` will be either the reserved stream ID (if positive) // `ret` will be either the reserved stream ID (if positive)
// or an error code (if negative) // or an error code (if negative)
const ret = session[kHandle].request(headersList, const ret = session[kHandle].request(headersList,
streamOptions, streamOptions,
options.parent | 0, options.parent | 0,
options.weight | 0, NGHTTP2_DEFAULT_WEIGHT,
!!options.exclusive); !!options.exclusive);
// In an error condition, one of three possible response codes will be // In an error condition, one of three possible response codes will be
@ -825,11 +834,7 @@ function requestOnConnect(headersList, headersParam, options) {
// //
// Also sets the default priority options if they are not set. // Also sets the default priority options if they are not set.
const setAndValidatePriorityOptions = hideStackFrames((options) => { const setAndValidatePriorityOptions = hideStackFrames((options) => {
if (options.weight === undefined) { deprecateWeight(options);
options.weight = NGHTTP2_DEFAULT_WEIGHT;
} else {
validateNumber.withoutStackTrace(options.weight, 'options.weight');
}
if (options.parent === undefined) { if (options.parent === undefined) {
options.parent = 0; options.parent = 0;
@ -885,25 +890,6 @@ function submitSettings(settings, callback) {
} }
} }
// Submits a PRIORITY frame to be sent to the remote peer
// Note: If the silent option is true, the change will be made
// locally with no PRIORITY frame sent.
function submitPriority(options) {
if (this.destroyed)
return;
this[kUpdateTimer]();
// If the parent is the id, do nothing because a
// stream cannot be made to depend on itself.
if (options.parent === this[kID])
return;
this[kHandle].priority(options.parent | 0,
options.weight | 0,
!!options.exclusive,
!!options.silent);
}
// Submit a GOAWAY frame to be sent to the remote peer. // Submit a GOAWAY frame to be sent to the remote peer.
// If the lastStreamID is set to <= 0, then the lastProcStreamID will // If the lastStreamID is set to <= 0, then the lastProcStreamID will
// be used. The opaqueData must either be a typed array or undefined // be used. The opaqueData must either be a typed array or undefined
@ -2313,25 +2299,6 @@ class Http2Stream extends Duplex {
} }
} }
priority(options) {
if (this.destroyed)
throw new ERR_HTTP2_INVALID_STREAM();
assertIsObject(options, 'options');
options = { ...options };
setAndValidatePriorityOptions(options);
const priorityFn = submitPriority.bind(this, options);
// If the handle has not yet been assigned, queue up the priority
// frame to be sent as soon as the ready event is emitted.
if (this.pending) {
this.once('ready', priorityFn);
return;
}
priorityFn();
}
sendTrailers(headers) { sendTrailers(headers) {
if (this.destroyed || this.closed) if (this.destroyed || this.closed)
throw new ERR_HTTP2_INVALID_STREAM(); throw new ERR_HTTP2_INVALID_STREAM();
@ -2504,6 +2471,12 @@ class Http2Stream extends Duplex {
} }
} }
// TODO(aduh95): remove this in future semver-major
Http2Stream.prototype.priority = deprecate(function priority(options) {
if (this.destroyed)
throw new ERR_HTTP2_INVALID_STREAM();
}, 'http2Stream.priority is longer supported after priority signalling was deprecated in RFC 1993', 'DEP0194');
function callTimeout(self, session) { function callTimeout(self, session) {
// If the session is destroyed, this should never actually be invoked, // If the session is destroyed, this should never actually be invoked,
// but just in case... // but just in case...

View File

@ -135,6 +135,17 @@ function isPendingDeprecation() {
!getOptionValue('--no-deprecation'); !getOptionValue('--no-deprecation');
} }
function deprecateProperty(key, msg, code, isPendingDeprecation) {
const emitDeprecationWarning = getDeprecationWarningEmitter(
code, msg, undefined, false, isPendingDeprecation,
);
return (options) => {
if (key in options) {
emitDeprecationWarning();
}
};
}
// Internal deprecator for pending --pending-deprecation. This can be invoked // Internal deprecator for pending --pending-deprecation. This can be invoked
// at snapshot building time as the warning permission is only queried at // at snapshot building time as the warning permission is only queried at
// run time. // run time.
@ -947,6 +958,7 @@ module.exports = {
defineReplaceableLazyAttribute, defineReplaceableLazyAttribute,
deprecate, deprecate,
deprecateInstantiation, deprecateInstantiation,
deprecateProperty,
emitExperimentalWarning, emitExperimentalWarning,
encodingsMap, encodingsMap,
exposeInterface, exposeInterface,

View File

@ -5,6 +5,11 @@ if (!common.hasCrypto)
common.skip('missing crypto'); common.skip('missing crypto');
const h2 = require('http2'); const h2 = require('http2');
common.expectWarning(
'DeprecationWarning',
'http2Stream.priority is longer supported after priority signalling was deprecated in RFC 1993',
'DEP0194');
const server = h2.createServer(); const server = h2.createServer();
// We use the lower-level API here // We use the lower-level API here

View File

@ -11,7 +11,6 @@ const http2 = require('http2');
const optionsToTest = { const optionsToTest = {
endStream: 'boolean', endStream: 'boolean',
weight: 'number',
parent: 'number', parent: 'number',
exclusive: 'boolean', exclusive: 'boolean',
silent: 'boolean' silent: 'boolean'

View File

@ -6,10 +6,16 @@ if (!common.hasCrypto)
const assert = require('assert'); const assert = require('assert');
const http2 = require('http2'); const http2 = require('http2');
common.expectWarning(
'DeprecationWarning',
'Priority signaling has been deprecated as of RFC 1993.',
'DEP0194');
const checkWeight = (actual, expect) => { const checkWeight = (actual, expect) => {
const server = http2.createServer(); const server = http2.createServer();
server.on('stream', common.mustCall((stream, headers, flags) => { server.on('stream', common.mustCall((stream, headers, flags) => {
assert.strictEqual(stream.state.weight, expect); assert.strictEqual(stream.state.sumDependencyWeight, 0);
assert.strictEqual(stream.state.weight, 16);
stream.respond(); stream.respond();
stream.end('test'); stream.end('test');
})); }));

View File

@ -7,6 +7,11 @@ const assert = require('assert');
const http2 = require('http2'); const http2 = require('http2');
const Countdown = require('../common/countdown'); const Countdown = require('../common/countdown');
common.expectWarning(
'DeprecationWarning',
'http2Stream.priority is longer supported after priority signalling was deprecated in RFC 1993',
'DEP0194');
const server = http2.createServer(); const server = http2.createServer();
const largeBuffer = Buffer.alloc(1e4); const largeBuffer = Buffer.alloc(1e4);

View File

@ -3,21 +3,18 @@
const common = require('../common'); const common = require('../common');
if (!common.hasCrypto) if (!common.hasCrypto)
common.skip('missing crypto'); common.skip('missing crypto');
const assert = require('assert');
const h2 = require('http2'); const h2 = require('http2');
common.expectWarning(
'DeprecationWarning',
'http2Stream.priority is longer supported after priority signalling was deprecated in RFC 1993',
'DEP0194');
const server = h2.createServer(); const server = h2.createServer();
// We use the lower-level API here // We use the lower-level API here
server.on('stream', common.mustCall(onStream)); server.on('stream', common.mustCall(onStream));
function onPriority(stream, parent, weight, exclusive) {
assert.strictEqual(stream, 1);
assert.strictEqual(parent, 0);
assert.strictEqual(weight, 1);
assert.strictEqual(exclusive, false);
}
function onStream(stream, headers, flags) { function onStream(stream, headers, flags) {
stream.priority({ stream.priority({
parent: 0, parent: 0,
@ -33,7 +30,7 @@ function onStream(stream, headers, flags) {
server.listen(0); server.listen(0);
server.on('priority', common.mustCall(onPriority)); server.on('priority', common.mustNotCall());
server.on('listening', common.mustCall(() => { server.on('listening', common.mustCall(() => {
@ -48,7 +45,9 @@ server.on('listening', common.mustCall(() => {
}); });
}); });
req.on('priority', common.mustCall(onPriority)); // The priority event is not supported anymore by nghttp2
// since 1.65.0.
req.on('priority', common.mustNotCall());
req.on('response', common.mustCall()); req.on('response', common.mustCall());
req.resume(); req.resume();

View File

@ -6,6 +6,11 @@ if (!common.hasCrypto)
const assert = require('assert'); const assert = require('assert');
const h2 = require('http2'); const h2 = require('http2');
common.expectWarning(
'DeprecationWarning',
'http2Stream.priority is longer supported after priority signalling was deprecated in RFC 1993',
'DEP0194');
const server = h2.createServer(); const server = h2.createServer();
server.on('stream', common.mustCall((stream) => { server.on('stream', common.mustCall((stream) => {