@@ -880,7 +880,7 @@ async fn download_entry(
880880
881881 // Now we do all the allowed tries at downloading the file.
882882 let mut try_num = 0u8 ;
883- let ( size, sha1) = ' outer : loop {
883+ let ( size, sha1) = ' success : loop {
884884
885885 let mut size = 0usize ;
886886 let mut sha1 = Sha1 :: new ( ) ;
@@ -889,16 +889,40 @@ async fn download_entry(
889889 // We specify if this error should be retried.
890890 let ( retry, mut err) = loop {
891891
892+ // Read chunk by chunk, any error break the loop and fallthrough, retrying if
893+ // this is timeout or decode error.
892894 let chunk = match res. chunk ( ) . await {
893895 Ok ( chunk) => chunk,
894896 Err ( e) => break ( e. is_timeout ( ) || e. is_decode ( ) , EntryErrorKind :: new_reqwest ( e) ) ,
895897 } ;
896898
899+ // If chunk is none, it means that we finished reading, the file is complete
900+ // and so we check size and sha-1, on mismatch we don't retry!
897901 let Some ( chunk) = chunk else {
898- // We finished copying all chunks, return the size and sha1!
899- break ' outer ( size, sha1) ;
902+
903+ let Ok ( size) = u32:: try_from ( size) else {
904+ break ( false , EntryErrorKind :: InvalidSize ) ;
905+ } ;
906+
907+ let sha1 = sha1. finalize ( ) ;
908+
909+ if let Some ( expected_size) = entry. expected_size {
910+ if expected_size != size {
911+ break ( false , EntryErrorKind :: InvalidSize ) ;
912+ }
913+ }
914+
915+ if let Some ( expected_sha1) = & entry. expected_sha1 {
916+ if expected_sha1 != sha1. as_slice ( ) {
917+ break ( false , EntryErrorKind :: InvalidSha1 ) ;
918+ }
919+ }
920+
921+ break ' success ( size, sha1) ;
922+
900923 } ;
901924
925+ // Adding the size delta and transmit it to the progress handler.
902926 let delta = chunk. len ( ) ;
903927 size += delta;
904928
@@ -959,27 +983,16 @@ async fn download_entry(
959983 // Remove the file, because we are not guaranteed that it's complete.
960984 // Ignore the error in case it fails, we just want to return the original error.
961985 let _ = fs:: remove_file ( & * entry. core . file ) . await ;
986+
987+ // Also remove the cache file if the file is cached.
988+ if let Some ( cache_file) = cache_file. as_deref ( ) {
989+ let _ = fs:: remove_file ( cache_file) . await ;
990+ }
962991
963992 return Err ( err) ;
964993
965994 } ;
966995
967- // Now check required size and SHA-1.
968- let size = u32:: try_from ( size) . map_err ( |_| EntryErrorKind :: InvalidSize ) ?;
969- let sha1 = sha1. finalize ( ) ;
970-
971- if let Some ( expected_size) = entry. expected_size {
972- if expected_size != size {
973- return Err ( EntryErrorKind :: InvalidSize ) ;
974- }
975- }
976-
977- if let Some ( expected_sha1) = & entry. expected_sha1 {
978- if expected_sha1 != sha1. as_slice ( ) {
979- return Err ( EntryErrorKind :: InvalidSha1 ) ;
980- }
981- }
982-
983996 // If we have a cache file, write it.
984997 if let Some ( cache_file) = cache_file. as_deref ( ) {
985998
@@ -1014,6 +1027,7 @@ async fn download_entry(
10141027
10151028 file. flush ( ) . await . map_err ( EntryErrorKind :: new_io) ?;
10161029
1030+ // At the end, handle the keep open option!
10171031 let handle;
10181032 if entry. keep_open {
10191033 let mut file = file. into_std ( ) . await ;
0 commit comments