http: add shouldUpgradeCallback to let servers control HTTP upgrades · nodejs/node@7aec53b · GitHub
Skip to content

Commit 7aec53b

Browse files
pimterrytargos
authored andcommitted
http: add shouldUpgradeCallback to let servers control HTTP upgrades
Previously, you could either add no 'upgrade' event handler, in which case all upgrades were ignored, or add an 'upgrade' handler and all upgrade attempts would effectively succeed and skip normal request handling. This change adds a new shouldUpgradeCallback option to HTTP servers, which receives the request details and returns a boolean that controls whether the request should be upgraded. PR-URL: #59824 Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent 87bbaa2 commit 7aec53b

3 files changed

Lines changed: 210 additions & 5 deletions

File tree

doc/api/http.md

Lines changed: 29 additions & 2 deletions

lib/_http_server.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ const {
9090
validateBoolean,
9191
validateLinkHeaderValue,
9292
validateObject,
93+
validateFunction,
9394
} = require('internal/validators');
9495
const Buffer = require('buffer').Buffer;
9596
const { setInterval, clearInterval } = require('timers');
@@ -520,6 +521,16 @@ function storeHTTPOptions(options) {
520521
} else {
521522
this.rejectNonStandardBodyWrites = false;
522523
}
524+
525+
const shouldUpgradeCallback = options.shouldUpgradeCallback;
526+
if (shouldUpgradeCallback !== undefined) {
527+
validateFunction(shouldUpgradeCallback, 'options.shouldUpgradeCallback');
528+
this.shouldUpgradeCallback = shouldUpgradeCallback;
529+
} else {
530+
this.shouldUpgradeCallback = function() {
531+
return this.listenerCount('upgrade') > 0;
532+
};
533+
}
523534
}
524535

525536
function setupConnectionsTracking() {
@@ -955,15 +966,15 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
955966
parser = null;
956967

957968
const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
958-
if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) {
969+
if (server.listenerCount(eventName) > 0) {
959970
debug('SERVER have listener for %s', eventName);
960971
const bodyHead = d.slice(ret, d.length);
961972

962973
socket.readableFlowing = null;
963974

964975
server.emit(eventName, req, socket, bodyHead);
965976
} else {
966-
// Got CONNECT method, but have no handler.
977+
// Got upgrade or CONNECT method, but have no handler.
967978
socket.destroy();
968979
}
969980
} else if (parser.incoming && parser.incoming.method === 'PRI') {
@@ -1062,7 +1073,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
10621073

10631074
if (req.upgrade) {
10641075
req.upgrade = req.method === 'CONNECT' ||
1065-
server.listenerCount('upgrade') > 0;
1076+
!!server.shouldUpgradeCallback(req);
10661077
if (req.upgrade)
10671078
return 2;
10681079
}
Lines changed: 167 additions & 0 deletions

0 commit comments

Comments
 (0)