diff --git a/server/src/models.rs b/server/src/models.rs index 1bf4ecc..77f1cd0 100644 --- a/server/src/models.rs +++ b/server/src/models.rs @@ -349,15 +349,29 @@ impl ModelStore { etag = etag_of(&response); } - let length: Option = response - .headers() - .get("content-length") - .and_then(|v| v.to_str().ok()?.parse().ok()); - let (mut done, total) = if resumed { - (have, length.map(|l| have + l)) + // On a 206, Content-Length is the length of the *range*, not of + // the file -- it answers a different question than the one a + // progress bar asks, and taken at face value it would fill the bar + // at 72 MB of a 234 MB model. The whole size is the last field of + // Content-Range (`bytes 162000000-234074815/234074816`), which has + // the further merit of not depending on where the range began. + let total: Option = if resumed { + response + .headers() + .get("content-range") + .and_then(|v| v.to_str().ok()) + .and_then(|v| { + v.rsplit_once('/') + .map(|(_, whole)| whole.trim().to_string()) + }) + .and_then(|whole| whole.parse().ok()) } else { - (0, length) + response + .headers() + .get("content-length") + .and_then(|v| v.to_str().ok()?.parse().ok()) }; + let mut done = if resumed { have } else { 0 }; { let mut p = run.progress.lock().unwrap(); p.done = done;