actix-web
actix-web copied to clipboard
fix: set error to Payload before dispatcher disconnect
PR Type
Fix
PR Checklist
- [x] Tests for the changes have been added / updated.
- [x] ~Documentation comments have been added / updated.~
- [x] A changelog entry has been made for the appropriate packages.
- [x] Format code with the latest stable rustfmt.
- [x] (Team) Label with affected crates and semver status.
Overview
Now actix-web decode body with Content-Length like that:
- PayloadDeocder: Use Framed in an unconventional way which maintains data length left and returns
Ok(Some(Bytes))even when data is not sufficient. ReturnsPayloadItem::ChunkorPayloadItem::Eof. - Codec: Convert
PayloadItemtoMessage::Chunk(Some(Bytes))orMessage::Chunk(None). - poll_request: Handling Message, for
Message::Chunk(Some(..)), callfeed_data; forMessage::Chunk(None), callfeed_eof. - poll: call poll_request.
However, when connection closed, we have to tell Payload. So here( https://github.com/actix/actix-web/blob/ce3af777a0/actix-http/src/h1/dispatcher.rs#L1139 ) actix-web call feed_eof. But since the content length infomation is only inside the decoder, and the outside can only sense it by waiting the Stream ends. And here the stream ends in advance when connection closed.
If the payload sender exists, it means there's still data to receive, so we can just set error here before waking the receiver.
Close #3067
I'm apprehensive to accept PRs like this without a test case that fails before the patch.
Here is the case I think: https://github.com/actix/actix-web/issues/3067
This bug also caused an accident in our product environment.
I added a test case to prove the fix. Before the patch it fails. Also the changelog is updated.
Note: This test might be a bit verbose as I'm not familiar with some of the actix built-in utils.
This issue may cause server writing wrong data to db in the case of unstable network. Do you think we should publish a new version for it? Theoretically all users could be affected by this.
ping @robjtede Can you review it?