Fix silent corruption error

- When the server terminates a connection before the download is
  complete, the error wasn't noticed
- Fixed error where the tokio receiver was dropped before all
  transmitters. This caused a panic when transmitters tried to send
  status udates.
- Fixed error message still containing file path
This commit is contained in:
Daniel M 2021-04-02 13:18:12 +02:00
parent a6e408a5e1
commit a933c57396
3 changed files with 14 additions and 5 deletions

View File

@ -208,6 +208,10 @@ pub async fn download_feedback_chunks(url: &str, into_file: &str, rep: DlReporte
ofile.write_all(&buff).await?; ofile.write_all(&buff).await?;
} }
if curr_progress != content_length {
return Err(DlError::HttpNoData.into());
}
// Ensure that IO is completed // Ensure that IO is completed
//ofile.flush().await?; //ofile.flush().await?;
@ -291,7 +295,7 @@ pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter
let mut t_last = t_start.clone(); let mut t_last = t_start.clone();
joiners.push(tokio::task::spawn(async move { let manager_handle = tokio::task::spawn(async move {
let rep = rep_task; let rep = rep_task;
//let mut dl_speeds = vec![0.0_f32; conn_count as usize]; //let mut dl_speeds = vec![0.0_f32; conn_count as usize];
@ -357,8 +361,7 @@ pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter
} }
} }
Ok(()) });
}));
let mut joiners: FuturesUnordered<_> = joiners.into_iter().collect(); let mut joiners: FuturesUnordered<_> = joiners.into_iter().collect();
@ -374,12 +377,16 @@ pub async fn download_feedback_multi(url: &str, into_file: &str, rep: DlReporter
handle.abort(); handle.abort();
} }
manager_handle.abort();
tokio::fs::remove_file(&into_file).await?; tokio::fs::remove_file(&into_file).await?;
return Err(e.into()); return Err(e.into());
} }
} }
manager_handle.await?;
// Remove the additional byte at the file end // Remove the additional byte at the file end
let ofile = tokio::fs::OpenOptions::new() let ofile = tokio::fs::OpenOptions::new()
.create(false) .create(false)

View File

@ -9,6 +9,7 @@ pub type ResBE<T> = Result<T, Box<dyn Error>>;
pub enum DlError { pub enum DlError {
BadHttpStatus, BadHttpStatus,
ContentLengthUnknown, ContentLengthUnknown,
HttpNoData,
Other(String) Other(String)
} }
@ -20,6 +21,7 @@ impl Display for DlError {
match self { match self {
DlError::BadHttpStatus => write!(f, "Bad http response status"), DlError::BadHttpStatus => write!(f, "Bad http response status"),
DlError::ContentLengthUnknown => write!(f, "Content-Length is unknown"), DlError::ContentLengthUnknown => write!(f, "Content-Length is unknown"),
DlError::HttpNoData => write!(f, "Http server sent no more data"),
DlError::Other(s) => write!(f, "Unknown download error: '{}'", s) DlError::Other(s) => write!(f, "Unknown download error: '{}'", s)
} }
} }

View File

@ -266,7 +266,7 @@ async fn download_multiple(urls: Vec<String>, outdir: &str, file_count: i32, con
if conn_count == 1 { if conn_count == 1 {
if let Err(_e) = download::download_feedback(&url, &into_file, rep.clone(), Some(filesize)).await { if let Err(_e) = download::download_feedback(&url, &into_file, rep.clone(), Some(filesize)).await {
rep.send(DlStatus::DoneErr { rep.send(DlStatus::DoneErr {
filename: into_file.to_string() filename: file_name.to_string()
}); });
} }
} else { } else {
@ -280,7 +280,7 @@ async fn download_multiple(urls: Vec<String>, outdir: &str, file_count: i32, con
if let Err(_e) = download::download_feedback_multi(&url, &into_file, rep.clone(), conn_count, Some(filesize)).await { if let Err(_e) = download::download_feedback_multi(&url, &into_file, rep.clone(), conn_count, Some(filesize)).await {
rep.send(DlStatus::DoneErr { rep.send(DlStatus::DoneErr {
filename: into_file.to_string() filename: file_name.to_string()
}); });
} }
}; };