-
Notifications
You must be signed in to change notification settings - Fork 633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pipeline handler: fix error state tracking #595
Conversation
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) { | ||
switch self.unwrapInboundIn(data) { | ||
case .head: | ||
ctx.eventLoop.execute { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment to explain why this is dispatched on the loop here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed
XCTFail("no body expected") | ||
case .end: | ||
ctx.eventLoop.execute { | ||
ctx.writeAndFlush(self.wrapOutboundOut(.end(nil)), promise: nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment to explain why this is dispatched on the loop here?
a8014ee
to
26df093
Compare
@swift-nio-bot test this please |
@@ -43,6 +43,8 @@ extension HTTPServerPipelineHandlerTest { | |||
("testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndBeforeResponseEnd", testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndBeforeResponseEnd), | |||
("testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndAfterResponseEnd", testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndAfterResponseEnd), | |||
("testQuiescingAfterHavingReceivedOneRequestButBeforeResponseWasSentWithMoreRequestsInTheBuffer", testQuiescingAfterHavingReceivedOneRequestButBeforeResponseWasSentWithMoreRequestsInTheBuffer), | |||
("testParserErrorOnly", testParserErrorOnly), | |||
("testLegitRequestFollowedByParserErrorArrivingWhilstReponseOutstanding", testLegitRequestFollowedByParserErrorArrivingWhilstReponseOutstanding), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reponse
-> Response
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixing
Thanks @weissi for fixing this! |
Motivation: @pushkarnk hit an interesting edge case that we previously mishandled and crashed. All these conditions need to be true 1. Whilst have an ongoing request (ie. outstanding response), ... 2. ... a `HTTPParserError` arrives (which we correctly queue) 3. Later the outstanding response is completed and then ... 4. ... the `HTTPServerProtocolErrorHandler` sends a .badRequest response We previously crashed. The reason we crashed is that the `HTTPServerPipelineHandler` obviously tracks state and then asserts that no response is sent for a wrong request. It does have an affordance to allow a .badRequest response for a request it couldn't parse. However this state tracking wasn't done if the error itself was enqueued for later delivery. Thanks very much @pushkarnk for the report! Modifications: instead of delivering the error directly use the `deliverOneError` function which transitions the state correctly. Result: fewer crashes & hopefully happy Pushkar
26df093
to
8508e00
Compare
Motivation: @pushkarnk hit an interesting edge case that we previously mishandled and crashed. All these conditions need to be true 1. Whilst have an ongoing request (ie. outstanding response), ... 2. ... a `HTTPParserError` arrives (which we correctly queue) 3. Later the outstanding response is completed and then ... 4. ... the `HTTPServerProtocolErrorHandler` sends a .badRequest response We previously crashed. The reason we crashed is that the `HTTPServerPipelineHandler` obviously tracks state and then asserts that no response is sent for a wrong request. It does have an affordance to allow a .badRequest response for a request it couldn't parse. However this state tracking wasn't done if the error itself was enqueued for later delivery. Thanks very much @pushkarnk for the report! Modifications: instead of delivering the error directly use the `deliverOneError` function which transitions the state correctly. Result: fewer crashes & hopefully happy Pushkar Motivation: Explain here the context, and why you're making that change. What is the problem you're trying to solve. Modifications: Describe the modifications you've done. Result: After your change, what will change.
Motivation:
@pushkarnk hit an interesting edge case that we previously mishandled
and crashed. All these conditions need to be true
HTTPParserError
arrives (which we correctly queue)HTTPServerProtocolErrorHandler
sends a .badRequest responseWe previously crashed. The reason we crashed is that the
HTTPServerPipelineHandler
obviously tracks state and then asserts thatno response is sent for a wrong request. It does have an affordance to
allow a .badRequest response for a request it couldn't parse. However
this state tracking wasn't done if the error itself was enqueued for
later delivery.
Thanks very much @pushkarnk for the report!
Modifications:
instead of delivering the error directly use the
deliverOneError
function which transitions the state correctly.
Result:
fewer crashes & hopefully happy Pushkar