The link preview's video, answered with byte ranges.
Discord, Twitter and iOS fetch a video in pieces (Range: bytes=...) and may refuse one that
cannot be. Workers static assets answer a range with the whole file, so /preview/loop.mp4
is routed to this code first (run_worker_first in wrangler.toml); the file is read through
the ASSETS binding and sliced here. Which bytes is site::range's decision; this file only
sets headers. The PNG stays a plain asset.
The route, and the binding it is read through ([assets] binding in wrangler.toml).
Same as the other assets: the address does not name the content, so a copy is kept only
while its ETag still matches. no-transform for the reason headers::HTML_CACHE has it.
18const CACHE: &str = "public, max-age=0, must-revalidate, no-transform";
The request headers that matter here, as text.
A name for the file's content (FNV-1a, 64 bit): not a secret, only a validator.
Does an If-None-Match / If-Range validator name this ETag? Weak comparison, as
RFC 9110 uses for If-None-Match; If-Range is stricter but a weak tag never matches ours.
The answer for bytes, the whole file. The body is plain bytes so the tests can read it;
the Worker wraps it.
42pub fn respond(method: &Method, asked: &Asked, bytes: Vec<u8>) -> Response<Vec<u8>> { 43 let len = bytes.len() as u64; 44 let tag = etag(&bytes); 45 let base = || Response::builder().header(header::ACCEPT_RANGES, "bytes").header(header::ETAG, &tag).header(header::CACHE_CONTROL, CACHE); 46 47 if asked.if_none_match.is_some_and(|list| names(list, &tag)) { 48 return base().status(StatusCode::NOT_MODIFIED).body(Vec::new()).expect("static headers are valid"); 49 } 50 51 // `If-Range`: the range applies only if the copy the client holds is this one. 52 let range = if asked.if_range.is_some_and(|validator| validator.trim() != tag) { None } else { asked.range }; 53 let (status, start, end) = match select(range, len) { 54 Selection::Whole => (StatusCode::OK, 0, len), 55 Selection::Partial { start, end } => (StatusCode::PARTIAL_CONTENT, start, end + 1), 56 Selection::Unsatisfiable => { 57 return base() 58 .status(StatusCode::RANGE_NOT_SATISFIABLE) 59 .header(header::CONTENT_RANGE, format!("bytes */{len}")) 60 .header(header::CONTENT_LENGTH, 0) 61 .body(Vec::new()) 62 .expect("static headers are valid"); 63 } 64 }; 65 66 let mut builder = base().status(status).header(header::CONTENT_TYPE, "video/mp4").header(header::CONTENT_LENGTH, end - start); 67 if status == StatusCode::PARTIAL_CONTENT { 68 builder = builder.header(header::CONTENT_RANGE, format!("bytes {start}-{}/{len}", end - 1)); 69 } 70 let body = if method == Method::HEAD { Vec::new() } else { bytes[start as usize..end as usize].to_vec() }; 71 builder.body(body).expect("static headers are valid") 72}
74#[cfg(test)] 75mod tests { 76 use super::*; 77 78 fn file() -> Vec<u8> { 79 (0..=255u8).cycle().take(1000).collect() 80 } 81 82 fn body(response: Response<Vec<u8>>) -> Vec<u8> { 83 response.into_body() 84 } 85 86 fn header_of<'a>(response: &'a Response<Vec<u8>>, name: header::HeaderName) -> &'a str { 87 response.headers()[name].to_str().unwrap() 88 } 89 90 fn ranged(range: &str) -> Asked<'_> { 91 Asked { range: Some(range), ..Asked::default() } 92 } 93 94 #[test] 95 fn no_range_is_the_whole_file_that_says_it_takes_ranges() { 96 let response = respond(&Method::GET, &Asked::default(), file()); 97 assert_eq!(response.status(), 200); 98 assert_eq!(header_of(&response, header::ACCEPT_RANGES), "bytes"); 99 assert_eq!(header_of(&response, header::CONTENT_TYPE), "video/mp4"); 100 assert_eq!(header_of(&response, header::CONTENT_LENGTH), "1000"); 101 assert!(response.headers().get(header::CONTENT_RANGE).is_none()); 102 assert_eq!(body(response), file()); 103 } 104 105 #[test] 106 fn a_range_is_a_206_with_exactly_those_bytes() { 107 for (asked, from, to) in [("bytes=0-99", 0, 99), ("bytes=0-", 0, 999), ("bytes=900-", 900, 999), ("bytes=-10", 990, 999), ("bytes=5-5000", 5, 999)] { 108 let response = respond(&Method::GET, &ranged(asked), file()); 109 assert_eq!(response.status(), 206, "{asked}"); 110 assert_eq!(header_of(&response, header::CONTENT_RANGE), format!("bytes {from}-{to}/1000")); 111 assert_eq!(header_of(&response, header::CONTENT_LENGTH), (to - from + 1).to_string()); 112 assert_eq!(header_of(&response, header::ACCEPT_RANGES), "bytes"); 113 assert_eq!(header_of(&response, header::CONTENT_TYPE), "video/mp4"); 114 assert_eq!(body(response), file()[from..=to], "{asked}"); 115 } 116 } 117 118 #[test] 119 fn a_range_past_the_end_is_a_416_that_says_how_long_the_file_is() { 120 let response = respond(&Method::GET, &ranged("bytes=1000-"), file()); 121 assert_eq!(response.status(), 416); 122 assert_eq!(header_of(&response, header::CONTENT_RANGE), "bytes */1000"); 123 assert_eq!(header_of(&response, header::ACCEPT_RANGES), "bytes"); 124 assert!(body(response).is_empty()); 125 } 126 127 #[test] 128 fn a_range_that_is_not_understood_is_the_whole_file() { 129 for asked in ["bytes=0-1,5-6", "bytes=9-2", "items=0-5", "garbage", "bytes=-"] { 130 let response = respond(&Method::GET, &ranged(asked), file()); 131 assert_eq!(response.status(), 200, "{asked}"); 132 assert_eq!(header_of(&response, header::ACCEPT_RANGES), "bytes"); 133 assert_eq!(body(response).len(), 1000); 134 } 135 } 136 137 #[test] 138 fn head_has_the_headers_of_a_get_and_no_body() { 139 let get = respond(&Method::GET, &ranged("bytes=10-19"), file()); 140 let head = respond(&Method::HEAD, &ranged("bytes=10-19"), file()); 141 assert_eq!(head.status(), 206); 142 for name in [header::CONTENT_LENGTH, header::CONTENT_RANGE, header::CONTENT_TYPE, header::ETAG, header::ACCEPT_RANGES, header::CACHE_CONTROL] { 143 assert_eq!(head.headers()[&name], get.headers()[&name], "{name}"); 144 } 145 assert_eq!(header_of(&head, header::CONTENT_LENGTH), "10"); 146 assert!(body(head).is_empty()); 147 148 let whole = respond(&Method::HEAD, &Asked::default(), file()); 149 assert_eq!(whole.status(), 200); 150 assert_eq!(header_of(&whole, header::CONTENT_LENGTH), "1000"); 151 } 152 153 #[test] 154 fn an_empty_file_is_served_and_satisfies_no_range() { 155 assert_eq!(respond(&Method::GET, &Asked::default(), vec![]).status(), 200); 156 let response = respond(&Method::GET, &ranged("bytes=0-"), vec![]); 157 assert_eq!(response.status(), 416); 158 assert_eq!(header_of(&response, header::CONTENT_RANGE), "bytes */0"); 159 } 160 161 #[test] 162 fn the_validator_follows_the_content_and_keeps_the_cache_honest() { 163 assert_eq!(etag(&file()), etag(&file())); 164 assert_ne!(etag(&file()), etag(&file()[1..])); 165 let response = respond(&Method::GET, &Asked::default(), file()); 166 assert_eq!(header_of(&response, header::ETAG), etag(&file())); 167 let cache = header_of(&response, header::CACHE_CONTROL); 168 assert!(cache.contains("no-transform") && cache.contains("must-revalidate")); 169 } 170 171 #[test] 172 fn an_unchanged_copy_is_a_304() { 173 let tag = etag(&file()); 174 for list in [tag.clone(), format!("W/{tag}"), format!("\"other\", {tag}"), "*".to_owned()] { 175 let asked = Asked { if_none_match: Some(&list), ..Asked::default() }; 176 assert_eq!(respond(&Method::GET, &asked, file()).status(), 304, "{list}"); 177 } 178 let asked = Asked { if_none_match: Some("\"other\""), ..Asked::default() }; 179 assert_eq!(respond(&Method::GET, &asked, file()).status(), 200); 180 } 181 182 #[test] 183 fn if_range_applies_the_range_only_to_the_copy_it_names() { 184 let tag = etag(&file()); 185 let same = Asked { range: Some("bytes=0-9"), if_range: Some(&tag), ..Asked::default() }; 186 assert_eq!(respond(&Method::GET, &same, file()).status(), 206); 187 let stale = Asked { range: Some("bytes=0-9"), if_range: Some("\"old\""), ..Asked::default() }; 188 assert_eq!(respond(&Method::GET, &stale, file()).status(), 200); 189 } 190}