-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
actix-http: h1: stop pipelining when not reading full requests #3721
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
base: master
Are you sure you want to change the base?
actix-http: h1: stop pipelining when not reading full requests #3721
Conversation
The existing pipelining behavior of the h1 dispatcher can cause client timeouts if the entire request body isn't read. It puts the dispatcher into a state where it refuses to read more (payload dropped) but there are still bytes in the buffer from the request body. This solution adds the SHUTDOWN flag in addition to the FINISHED flag when completing a response when both the following are true: 1. There are no messages in `this.messages` 2. There is still a payload in `this.payload` This combination implies two things. First, that we have not parsed a pipelined request after the request we have just responded to. Second, that the current request payload has not been fed an EOF. Because there are no pipelined requests, we know that the current request payload belongs to the request we have just responded to, and because the request payload has not been fed an EOF, we know we never finished reading it. When this occurs, adding the SHUTDOWN flag to the dispatcher triggers a `flush` and a `poll_shutdown` on the IO resource on the next poll.
I've added a test that fails without the change and passes with the change. specifically the line that fails the test is the one that panics if the poll of h1 is not pending. With the change present, calling poll with an unfinished request shuts down the dispatcher. |
Is there anything else you want me to do on this PR? I see you approved it but I don't have permission to merge it :p |
Nothing on top of mind, I just havent checked out the added test yet. |
An alternate solution to #3715
The existing pipelining behavior of the h1 dispatcher can cause client timeouts if the entire request body isn't read. It puts the dispatcher into a state where it refuses to read more (payload dropped) but there are still bytes in the buffer from the request body.
This solution adds the SHUTDOWN flag in addition to the FINISHED flag when completing a response when both the following are true:
this.messages
this.payload
This combination implies two things. First, that we have not parsed a pipelined request after the request we have just responded to. Second, that the current request payload has not been fed an EOF. Because there are no pipelined requests, we know that the current request payload belongs to the request we have just responded to, and because the request payload has not been fed an EOF, we know we never finished reading it.
When this occurs, adding the SHUTDOWN flag to the dispatcher triggers a
flush
and apoll_shutdown
on the IO resource on the next poll.PR Type
Bug Fix
PR Checklist
Overview