fix broken thumbnail styling; fix firefox range requests

AuthorKonata <konata@posteo.jp>
Date
Commitc1c09d2802b759f910bd8dc32fc05e8c250a7173
Parent1417af9
3 files changed, 21 insertions(+), 5 deletions(-)
▾Mserver/src/api/files.rs
@@ -529,7 +529,8 @@ async fn file_response(
.to_string();
let disp = disposition(if inline { "inline" } else { "attachment" }, name);
// A single `bytes=a-b` range (media seeking). Anything else is served whole.
let (start, end) = match parse_range(range, size) {
let parsed = parse_range(range, size);
let (start, end) = match parsed {
Some(Some(r)) => r,
Some(None) => {
return Response::builder()
@@ -545,7 +546,10 @@ async fn file_response(
}
None => (0, size),
};
let partial = (start, end) != (0, size);
// 206 for every satisfiable `Range`, even one that spans the whole file
// (`bytes=0-`, the first request Firefox makes). Firefox reads a 200 as
// "no range support" and its media cache stops fetching mid-file.
let partial = matches!(parsed, Some(Some(_)));
let body = stream_file(full.to_path_buf(), start, end);
let mut res = Response::builder()
.status(if partial {
▾Mserver/tests/api_files.rs
@@ -191,6 +191,12 @@ async fn download_honours_single_byte_ranges() {
assert_eq!(r.header("content-length").as_deref(), Some("10"));
assert_eq!(r.body, (10..20u8).collect::<Vec<_>>());
// A whole-file range is still a 206 with a `Content-Range` (Firefox).
let r = get("bytes=0-").await;
assert_eq!(r.status, StatusCode::PARTIAL_CONTENT);
assert_eq!(r.header("content-range").as_deref(), Some("bytes 0-63/64"));
assert_eq!(r.body.len(), 64);
// Open end and suffix forms; an end past EOF is clamped.
let r = get("bytes=60-").await;
assert_eq!(r.body, (60..64u8).collect::<Vec<_>>());
▾Mweb/src/views/browser.rs
@@ -1333,9 +1333,10 @@ fn entries_view(
// reactive owner per item (see its
// doc).
{icon_svg(icon, icon_class)}
// An empty `alt` means a 404 renders
// as nothing, leaving the icon. No
// error handler is needed.
// A 404 (no thumbnail for this
// file) removes the element. Left in
// place, a sized broken `<img>` draws
// a border over the icon.
{thumb_src.map(|src| view! {
<img
class="tile-thumb"
@@ -1343,6 +1344,11 @@ fn entries_view(
alt=""
loading="lazy"
decoding="async"
on:error=|ev| {
if let Some(el) = ev.target() {
el.unchecked_into::<web_sys::Element>().remove();
}
}
/>
})}
</div>