Skip to content

Http11Processor's keep alive state and input buffer's swallow state must be synchronized#550

Merged
markt-asf merged 4 commits into
apache:mainfrom
malaysf:main
Sep 12, 2022
Merged

Http11Processor's keep alive state and input buffer's swallow state must be synchronized#550
markt-asf merged 4 commits into
apache:mainfrom
malaysf:main

Conversation

@malaysf

@malaysf malaysf commented Sep 2, 2022

Copy link
Copy Markdown
Contributor

Fixing a bug where a connection would be kept alive without swallowing the input from the request stream.

When a request comes in with a 100 Continue expectation, and the server immediately responds with a 200 status without reading the request body at all, the next request on the connection will fail because Tomcat cannot parse the HTTP verb. The first request left Http11Processor in a state where it kept the connection alive but did not discard the request body, thus reading the next request began at the wrong place in the stream.

The new unit test replicates the issue and is addressed by the code changes to keep the keepAlive and input buffer swallow state in sync with each other.

…g the input from the request stream.

When a request comes in with a 100 Continue expectation, and the server immediately responds with a 200 status without reading the request body at all, the next request on the connection will fail because Tomcat cannot parse the HTTP verb.

The new unit test replicates the issue and is addressed by the code changes to keep the keepAlive and input buffer swallow state in sync with each other.
@rmaucher

rmaucher commented Sep 5, 2022

Copy link
Copy Markdown
Contributor

A request with an expectation is not supposed to be performed the same way as an identical request without it. So you have to be careful and I don't think your patch is correct.
Looking at the code in Http11Processor.ack, it looks to me that it should work so I don't really understand yet.

@malaysf

malaysf commented Sep 6, 2022

Copy link
Copy Markdown
Contributor Author

The TestSwallowAbortedUploads test fails so I need to look into that.

We ran into this issue in production and were able to reproduce with curl or postman requests to an API that returns 200 without ever reading the request body.

I don't think that the core logic is wrong in Http11Processor.ack, in this situation ack is never called since the request body input stream is never read from, which triggers the ack.

When a request is started, Http11Processor.prepareExpectation sets inputBuffer.setSwallowInput(false); but keepAlive is still set to true. If keepAlive is true, then the inputBuffer's swallow state must be set to true as well to ensure that the request stream is advanced to the beginning of the next request, regardless of whether the servlet consumed all the bytes.

@markt-asf

Copy link
Copy Markdown
Contributor

I think you can just remove the inputBuffer.setSwallowInput(false) in Http11Processor.prepareExpectation(). If that is correct, I think there is at least one other call that can also be removed.

@malaysf

malaysf commented Sep 6, 2022

Copy link
Copy Markdown
Contributor Author

@markt-asf That does work and is a much simpler solution! It also doesn't break TestSwallowAbortedUploads (which I now understand why).

I will update my PR with that change. What is the other call that you think could be removed?

@markt-asf

Copy link
Copy Markdown
Contributor

I suspect the call in Http11Processor.ack() can also be removed.

@malaysf

malaysf commented Sep 7, 2022

Copy link
Copy Markdown
Contributor Author

Are you referring to the call to inputBuffer.setSwallowInput(true); in Http11Processor.ack? That does appear to be unnecessary now.

@markt-asf

Copy link
Copy Markdown
Contributor

Are you referring to the call to inputBuffer.setSwallowInput(true); in Http11Processor.ack? That does appear to be unnecessary now.

Yes. That was the one.

@malaysf

malaysf commented Sep 9, 2022

Copy link
Copy Markdown
Contributor Author

I've included that change too. Please let me know if there's anything else that should be done. Thanks!

@markt-asf
markt-asf merged commit 7eae543 into apache:main Sep 12, 2022
markt-asf pushed a commit that referenced this pull request Sep 12, 2022
…k or reading request body. (#550)

* Fixing a bug where a connection would be kept alive without swallowing the input from the request stream.

When a request comes in with a 100 Continue expectation, and the server immediately responds with a 200 status without reading the request body at all, the next request on the connection will fail because Tomcat cannot parse the HTTP verb.

The new unit test replicates the issue and is addressed by removing the unnecessary changes to the swallowInput field of the Http11InputBuffer.
markt-asf pushed a commit that referenced this pull request Sep 12, 2022
…k or reading request body. (#550)

* Fixing a bug where a connection would be kept alive without swallowing the input from the request stream.

When a request comes in with a 100 Continue expectation, and the server immediately responds with a 200 status without reading the request body at all, the next request on the connection will fail because Tomcat cannot parse the HTTP verb.

The new unit test replicates the issue and is addressed by removing the unnecessary changes to the swallowInput field of the Http11InputBuffer.
markt-asf pushed a commit that referenced this pull request Sep 12, 2022
…k or reading request body. (#550)

* Fixing a bug where a connection would be kept alive without swallowing the input from the request stream.

When a request comes in with a 100 Continue expectation, and the server immediately responds with a 200 status without reading the request body at all, the next request on the connection will fail because Tomcat cannot parse the HTTP verb.

The new unit test replicates the issue and is addressed by removing the unnecessary changes to the swallowInput field of the Http11InputBuffer.
@malaysf

malaysf commented Sep 12, 2022

Copy link
Copy Markdown
Contributor Author

@markt-asf Thanks for reviewing and merging. Could this please also be included in 9.0.x?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants