stop chunk iteration on match len < chunk condition (some servers may close the connection immediately); hold memory_input_stream in the error returned

This commit is contained in:
yggverse 2025-02-09 00:42:57 +02:00
parent d4f076f074
commit 62f53304aa
3 changed files with 23 additions and 17 deletions

View file

@ -53,19 +53,27 @@ pub fn for_memory_input_stream_async(
Some(&cancellable.clone()),
move |result| match result {
Ok(bytes) => {
total += bytes.len();
on_chunk(bytes.len(), total);
let len = bytes.len(); // calculate once
if total > limit {
return on_complete(Err(Error::BytesTotal(total, limit)));
}
if bytes.len() == 0 {
return on_complete(Ok((memory_input_stream, total)));
}
total += len;
on_chunk(len, total);
memory_input_stream.add_bytes(&bytes);
// prevent memory overflow on size `limit` reached
// * add last received bytes into the `memory_input_stream` anyway (to prevent data lost),
// it's safe because limited to the `chunk` size
if total > limit {
return on_complete(Err(Error::BytesTotal(memory_input_stream, total, limit)));
}
// is the next iteration required?
if len < chunk // some servers may close the connection after first chunk request (@TODO this condition wants review)
|| len == 0
{
return on_complete(Ok((memory_input_stream, total)));
}
// continue reading..
for_memory_input_stream_async(
memory_input_stream,
@ -76,9 +84,7 @@ pub fn for_memory_input_stream_async(
(on_chunk, on_complete),
)
}
Err(e) => {
on_complete(Err(Error::InputStream(e)));
}
Err(e) => on_complete(Err(Error::InputStream(memory_input_stream, e))),
},
)
}

View file

@ -2,17 +2,17 @@ use std::fmt::{Display, Formatter, Result};
#[derive(Debug)]
pub enum Error {
BytesTotal(usize, usize),
InputStream(glib::Error),
BytesTotal(gio::MemoryInputStream, usize, usize),
InputStream(gio::MemoryInputStream, glib::Error),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::BytesTotal(total, limit) => {
Self::BytesTotal(_, total, limit) => {
write!(f, "Bytes total limit reached: {total} / {limit}")
}
Self::InputStream(e) => {
Self::InputStream(_, e) => {
write!(f, "Input stream error: {e}")
}
}