Skip to content
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

Merged
merged 1 commit into from
Aug 27, 2018

Conversation

weissi
Copy link
Member

@weissi weissi commented Aug 24, 2018

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

@weissi weissi added the patch-version-bump-only For PRs that when merged will only cause a bump of the patch version, ie. 1.0.x -> 1.0.(x+1) label Aug 24, 2018
@weissi weissi added this to the 1.9.3 milestone Aug 24, 2018
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
switch self.unwrapInboundIn(data) {
case .head:
ctx.eventLoop.execute {
Copy link
Member

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?

Copy link
Member Author

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)
Copy link
Member

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?

@weissi weissi force-pushed the jw-pipeline-crash branch 2 times, most recently from a8014ee to 26df093 Compare August 24, 2018 17:27
@tomerd
Copy link
Member

tomerd commented Aug 24, 2018

@swift-nio-bot test this please

@@ -43,6 +43,8 @@ extension HTTPServerPipelineHandlerTest {
("testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndBeforeResponseEnd", testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndBeforeResponseEnd),
("testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndAfterResponseEnd", testQuiescingAfterRequestAndResponseHeadsButBeforeAnyEndsThenRequestEndAfterResponseEnd),
("testQuiescingAfterHavingReceivedOneRequestButBeforeResponseWasSentWithMoreRequestsInTheBuffer", testQuiescingAfterHavingReceivedOneRequestButBeforeResponseWasSentWithMoreRequestsInTheBuffer),
("testParserErrorOnly", testParserErrorOnly),
("testLegitRequestFollowedByParserErrorArrivingWhilstReponseOutstanding", testLegitRequestFollowedByParserErrorArrivingWhilstReponseOutstanding),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reponse -> Response.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixing

@pushkarnk
Copy link
Contributor

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
@weissi weissi merged commit ce0c6d9 into apple:master Aug 27, 2018
@weissi weissi deleted the jw-pipeline-crash branch August 27, 2018 10:09
weissi added a commit that referenced this pull request Aug 29, 2018
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
patch-version-bump-only For PRs that when merged will only cause a bump of the patch version, ie. 1.0.x -> 1.0.(x+1)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants