Fix noodlemagazine thumb proxy; check.py verifies proxied urls
The thumb proxy dropped the preview query string, rejected extensionless getVideoPreview paths and warmed up through the slow fallback chain on every image. check.py now verifies that a proxied video.url resolves instead of failing it outright. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
@@ -105,9 +105,11 @@ impl NoodlemagazineProxy {
|
||||
|
||||
fn has_allowed_image_extension(path: &str) -> bool {
|
||||
let path = path.to_ascii_lowercase();
|
||||
[".jpg", ".jpeg", ".png", ".webp", ".avif", ".gif"]
|
||||
.iter()
|
||||
.any(|ext| path.ends_with(ext))
|
||||
// `.../i.mycdn.me/getVideoPreview?id=..` previews have no extension.
|
||||
path.ends_with("/getvideopreview")
|
||||
|| [".jpg", ".jpeg", ".png", ".webp", ".avif", ".gif"]
|
||||
.iter()
|
||||
.any(|ext| path.ends_with(ext))
|
||||
}
|
||||
|
||||
fn is_disallowed_thumb_host(host: &str) -> bool {
|
||||
@@ -292,20 +294,23 @@ pub async fn get_image(
|
||||
requester: web::types::State<Requester>,
|
||||
) -> Result<impl web::Responder, web::Error> {
|
||||
let endpoint = req.match_info().query("endpoint").to_string();
|
||||
let image_url = NoodlemagazineProxy::normalize_image_url(&endpoint);
|
||||
let mut image_url = NoodlemagazineProxy::normalize_image_url(&endpoint);
|
||||
// The preview's own query (`id`, `idx`, `type`, `tkn`, `fn`) arrives as the
|
||||
// request query string, not as part of the matched path.
|
||||
let query = req.query_string();
|
||||
if !query.is_empty() && !image_url.contains('?') {
|
||||
image_url.push('?');
|
||||
image_url.push_str(query);
|
||||
}
|
||||
|
||||
if !NoodlemagazineProxy::is_allowed_thumb_url(&image_url) {
|
||||
return Ok(web::HttpResponse::BadRequest().finish());
|
||||
}
|
||||
|
||||
// No site warm-up first: the image CDN answers directly (~0.1s). Warming
|
||||
// via noodlemagazine.com cost 10-30s through the requester's fallbacks;
|
||||
// the retry below still warms up when the first fetch fails.
|
||||
let mut requester = requester.get_ref().clone();
|
||||
let _ = requester
|
||||
.get_with_headers(
|
||||
NoodlemagazineProxy::root_referer(),
|
||||
NoodlemagazineProxy::root_html_headers(),
|
||||
Some(Version::HTTP_11),
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut headers = NoodlemagazineProxy::image_headers(&requester, image_url.as_str());
|
||||
let mut upstream = requester
|
||||
@@ -409,6 +414,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn allows_https_image_thumbs_but_rejects_local_or_non_images() {
|
||||
assert!(NoodlemagazineProxy::is_allowed_thumb_url(
|
||||
"https://img.pvvstream.pro/preview/a/-1_2/240/i.mycdn.me/getVideoPreview?id=1&idx=0&type=39&tkn=x"
|
||||
));
|
||||
assert!(NoodlemagazineProxy::is_allowed_thumb_url(
|
||||
"https://noodlemagazine.com/thumbs/example.webp"
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user