You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is an interesting bug/limitation we've stumbled upon recently in the node.js's http server implementation.
We had the 'upgrade' event listener defined in our code to properly map web sockets, although this lead to an issue with HTTP/2 h2c upgrade requests.
Basically, the current logic to emit the 'upgrade' event only considers the presence of the Upgrade header for a particular request without verifying other values. Such approach causes the event to be also emitted for HTTP/2 upgrade requests, which have similar syntax to websocket upgrades, just the value of the Upgrade header differs.
In our case the presence of the upgrade event listener was always causing h2c upgrade requests to be unexpectedly rejected, while the expected behaviour would be to just downgrade the connection to HTTP/1.1.
A workaround to that was to remove the upgrade listener and add a http middleware instead, although this creates another bug where the server.requestTimeout is applied to web sockets created by such middleware. After the timeout is fired websocket connection is killed forcefully and there is no way to customize this behaviour.
What is the feature you are proposing to solve the problem?
I expect there is a possibility to either be able to explicitly provide to which types of upgrade request the upgrade event must be triggered (e.g. only web socket upgrades)
OR
there is a possibility to continue handling the request as if no upgrade event has been defined (similarly to calling next() in a middleware handler), so I could default to HTTP/1.1 if I detect it's a h2c request type after checking the request headers (or any other non-websocket upgrade request)
OR
there is a possibility to remove requestTimeout from the particular socket if we upgrade it to a websocket in a middleware rather than via the upgrade event
What alternatives have you considered?
Unfortunately I am out of other options for now.
The text was updated successfully, but these errors were encountered:
mykola-mokhnach
changed the title
http 'upgrade' event must only be generated for websocket upgrades
Improve HTTP server 'upgrade' event generation logic
Feb 14, 2025
What is the problem this feature will solve?
There is an interesting bug/limitation we've stumbled upon recently in the node.js's http server implementation.
We had the 'upgrade' event listener defined in our code to properly map web sockets, although this lead to an issue with HTTP/2 h2c upgrade requests.
Basically, the current logic to emit the 'upgrade' event only considers the presence of the
Upgrade
header for a particular request without verifying other values. Such approach causes the event to be also emitted for HTTP/2 upgrade requests, which have similar syntax to websocket upgrades, just the value of theUpgrade
header differs.In our case the presence of the
upgrade
event listener was always causing h2c upgrade requests to be unexpectedly rejected, while the expected behaviour would be to just downgrade the connection to HTTP/1.1.A workaround to that was to remove the
upgrade
listener and add a http middleware instead, although this creates another bug where the server.requestTimeout is applied to web sockets created by such middleware. After the timeout is fired websocket connection is killed forcefully and there is no way to customize this behaviour.See the issue appium/appium#20760 for more details and code examples
What is the feature you are proposing to solve the problem?
I expect there is a possibility to either be able to explicitly provide to which types of upgrade request the
upgrade
event must be triggered (e.g. only web socket upgrades)OR
there is a possibility to continue handling the request as if no
upgrade
event has been defined (similarly to callingnext()
in a middleware handler), so I could default to HTTP/1.1 if I detect it's a h2c request type after checking the request headers (or any other non-websocket upgrade request)OR
there is a possibility to remove
requestTimeout
from the particular socket if we upgrade it to a websocket in a middleware rather than via theupgrade
eventWhat alternatives have you considered?
Unfortunately I am out of other options for now.
The text was updated successfully, but these errors were encountered: