vapor: Collecting the request body sometimes hangs
Describe the bug
A route that .collects a request body hangs under certain conditions.
To Reproduce
Download the attached Vapor project hanging-collector.zip and unpack it. Then follow the instructions inreadme.md that’s found in the root of the project. I’ve copied most of the instructions here.
Prepare
- Start the app:
$ swift run Run serve --port 7687
- Upload the sample image:
$ curl -i -T ./sample.jpg -X PUT http://127.0.0.1:7687/hanger
This should work out ok: there’s a copy of sample.jpg in /tmp/pix/hanger.
Reproduce the hang
- Start the app
$ swift run Run serve --port 7687
- GET the image
curl -i http://127.0.0.1:7687/hanger
- PUT the image
$ curl -i -T ./sample.jpg -X PUT http://127.0.0.1:7687/hanger
Often this will be enough. The vapor app has logged the PUT request but curl will now hang, and running lsof -i -nP will show the open connection:
$ lsof -i -nP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
Run 22462 malte 12u IPv4 0xd3a42b18da250499 0t0 TCP 127.0.0.1:7687 (LISTEN)
Run 22462 malte 13u IPv4 0xd3a42b18da24e4d1 0t0 TCP 127.0.0.1:7687->127.0.0.1:55955 (ESTABLISHED)
curl 22503 malte 6u IPv4 0xd3a42b18d947ef69 0t0 TCP 127.0.0.1:55955->127.0.0.1:7687 (ESTABLISHED)
Stopping the app now takes some time. After about 10 seconds the app quits with the following message:
[ ERROR ] Could not stop HTTP server: Abort.500: Server stop took too long.
ERROR: Cannot schedule tasks on an EventLoop that has already shut down. This will be upgraded to a forced crash in future SwiftNIO versions.
The hang is intermittent. I often have to retry from step 1 for the hang to occur. It’s important that the app is restarted!
Expected behavior
The PUT request should never hang.
Environment
- Vapor Framework version: 4.67.1
- Vapor Toolbox version: 18.6.0
- OS version: macOS 12.6.1 (21G217)
$ swift --version
swift-driver version: 1.62.15 Apple Swift version 5.7.1 (swiftlang-5.7.1.135.3 clang-1400.0.29.51)
Target: arm64-apple-macosx12.0
I’m on an M2 MacBook Air running Xcode Version 14.1 (14B47b).
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 18 (18 by maintainers)
Found it, I’ll try to make a patch.
Read handler was being set at the same time a chunk was being added to the buffer. The read handler wasn’t called, because it wasn’t there yet, so a chunk was going to be added to the buffer. But the buffers were empty while setting the handler. So the first chunk got lost.
Yes this was fixed in 4.67.3 - I’ll close this but feel free to reopen if it’s still an issue!