mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
Fail a content provider that makes no progress
write_content_with_progress() advances its offset only by what the provider writes, so a provider that reported success without writing anything and without calling done() was handed the same offset and length again on the next pass. With the peer still connected it spun there, re-entering the provider as fast as the loop could run. make_file_body()'s provider was one way to reach this and was fixed in #2566, but any user-supplied provider can do the same. Treat a pass that makes no progress as a short body, which is how done() called early is already handled.
This commit is contained in:
1 parent
f2b338ae2e
commit
c58061ea81
2 files changed
+48
No files matched your search
@@ -8401,6 +8401,8 @@ inline bool write_content_with_progress(Stream &strm,
|
||||
data_sink.done = [&]() { finished = true; };
|
||||
|
||||
while (offset < end_offset && !finished && !is_shutting_down()) {
|
||||
auto last_offset = offset;
|
||||
|
||||
if (!strm.wait_writable() || !strm.is_peer_alive()) {
|
||||
error = Error::Write;
|
||||
return false;
|
||||
@@ -8411,6 +8413,15 @@ inline bool write_content_with_progress(Stream &strm,
|
||||
error = Error::Write;
|
||||
return false;
|
||||
}
|
||||
|
||||
// A provider that reports success without writing anything and without
|
||||
// reporting itself done gets handed the same offset and length again on
|
||||
// the next pass, so it would spin here for as long as the peer stays
|
||||
// connected. Treat making no progress as a short body, like done() early.
|
||||
if (!finished && offset == last_offset) {
|
||||
error = Error::Write;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset < end_offset) { // done() called early, or is_shutting_down()
|
||||
|
||||
Reference in new issue
Block a user