Remove a race condition from the WebSocket upgrade #217
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
An upgrade to WebSocket invokes three handlers in an order. First, the
shouldUpgrade
handler supplied by the user is run to decide if an upgrademust go through. This handler also supplies additional headers to be sent in
the response. Next, after the WebSocket upgrader is done upgrading the
pipeline, the
completionHandler
is called. We remove Kitura-NIO'sHTTPRequestHandler
here. Next, theupgradePipelineHandler
is invoked. Thishandler allows us to add all the WebSocket related
ChannelHandler
s.For an undocumented reason, we saved the
ChannelHandlerContext
received bythe
completionHandler
in theHTTPServer
and later used it upgrade thepipeline in
upgradePipelineHandler
. This can easily lead to a race conditionwhere we saved the
ChannelHandlerContext
for a connection, into theHTTPServer
but before it could be used inupgradePipelineHandler
, it wasoverwritten by the upgrade happening on another connection. Consequently, we
never upgraded the pipeline of the former connection. This could lead to
different kinds of failures.
The
upgradePipelineHandler
hasChannel
as one of its parameters. Hencethere is no need to store the
ChannelHandlerContext
for use in this closure.Consequently, we have to use a
Channel
to initialize anHTTPServerRequest
,which, in turn, is modified to accept a
Channel
instead of aChannelHandlerContext
.