WebServer: bail out of an upload whose peer disconnected

Same root cause as the websocket spin this branch fixes, different symptom, so it
belongs with the InputSink EOF change rather than apart from it.

ReadBinaryUntilTerminator() returns 0 both when nothing has arrived yet and when
the peer is gone, and the multipart loop only exits on finding its terminator - so
a cancelled browser upload left a handler thread spinning forever. That also hangs
web server shutdown, since it joins its handler threads.

Now that InputSink reports EOF, ask it.

(Moved here from misc-correctness-fixes, which will be rebased on top of this.)
This commit is contained in:
Henrik Rydgård committed 2026-08-31 01:02:46 +02:00
1 parent abd91da5eb
commit 949f773220
1 file changed
+10
+10
View File
@@ -651,6 +651,16 @@ static MultiPartResult HandleMultipartPart(const http::ServerRequest &request, s
}
progress.AddBytes(readBytes);
bytesTransferred += readBytes;
if (readBytes == 0 && !terminatorFound && (request.In()->AtEnd() || request.In()->HasError())) {
// Peer went away mid-upload (a cancelled browser upload, say). Without this the loop
// spins forever, which also blocks web server shutdown since it joins its threads.
ERROR_LOG(Log::HTTP, "Connection closed during upload of '%s'", filename.c_str());
if (fp) {
fclose(fp);
File::Delete(destPath);
}
return MultiPartResult::RequestError;
}
if (terminatorFound) {
INFO_LOG(Log::HTTP, "Found terminator, skipping and proceeding.");
break;