Move redirecting-proxy formats to video.url for verified app clients; document the rule
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
70
src/proxy.rs
70
src/proxy.rs
@@ -20,6 +20,40 @@ use crate::proxies::thaiporntv::ThaipornTvProxy;
|
||||
use crate::proxies::*;
|
||||
use crate::util::requester::Requester;
|
||||
|
||||
/// Proxies that answer with a `302` to the real media instead of streaming it.
|
||||
/// The Hot Tub app cannot follow a redirect inside `formats[].url`, so for app
|
||||
/// clients a format pointing at one of these is moved to `video.url` (see
|
||||
/// `move_redirect_formats_to_url`). Keep in sync with the `proxy2redirect`
|
||||
/// routes below; `redirect_proxy_list_matches_routes` enforces it.
|
||||
pub const REDIRECT_PROXIES: &[&str] = &[
|
||||
"archivebate",
|
||||
"clapdat",
|
||||
"doodstream",
|
||||
"lulustream",
|
||||
"sxyprn",
|
||||
"javtiful",
|
||||
"spankbang",
|
||||
"porndish",
|
||||
"hqporner",
|
||||
"heavyfetish",
|
||||
"vjav",
|
||||
"pornhd3x",
|
||||
"vidara",
|
||||
"pimpbunny",
|
||||
"thaiporntv",
|
||||
"tube8",
|
||||
"supjav",
|
||||
];
|
||||
|
||||
/// True for a `/proxy/<redirect proxy>/...` URL (absolute or host-relative).
|
||||
pub fn is_redirect_proxy_url(url: &str) -> bool {
|
||||
let Some(rest) = url.split_once("/proxy/").map(|(_, rest)| rest) else {
|
||||
return false;
|
||||
};
|
||||
let name = rest.split('/').next().unwrap_or_default();
|
||||
REDIRECT_PROXIES.contains(&name)
|
||||
}
|
||||
|
||||
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(
|
||||
web::resource("/archivebate/{endpoint}*")
|
||||
@@ -239,3 +273,39 @@ fn get_proxy(proxy: &str) -> Option<AnyProxy> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod redirect_proxy_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn recognises_redirect_proxy_urls() {
|
||||
assert!(is_redirect_proxy_url("http://h/proxy/archivebate/archivebate.com/watch/1"));
|
||||
assert!(is_redirect_proxy_url("/proxy/hqporner/x"));
|
||||
assert!(!is_redirect_proxy_url("http://h/proxy/noodlemagazine/x"));
|
||||
assert!(!is_redirect_proxy_url("https://cdn.example/video.mp4"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn redirect_proxy_list_matches_routes() {
|
||||
let source = include_str!("proxy.rs");
|
||||
let config_body = source
|
||||
.split("pub fn config(")
|
||||
.nth(1)
|
||||
.and_then(|rest| rest.split("async fn proxy2redirect(").next())
|
||||
.expect("config body");
|
||||
let mut from_routes: Vec<String> = Vec::new();
|
||||
for block in config_body.split("web::resource(\"/").skip(1) {
|
||||
let name = block.split("/{endpoint}").next().unwrap_or_default();
|
||||
let until_next = block.split("web::resource(").next().unwrap_or(block);
|
||||
if until_next.contains("proxy2redirect") {
|
||||
from_routes.push(name.to_string());
|
||||
}
|
||||
}
|
||||
let mut listed: Vec<String> = REDIRECT_PROXIES.iter().map(|s| s.to_string()).collect();
|
||||
from_routes.sort();
|
||||
from_routes.dedup();
|
||||
listed.sort();
|
||||
assert_eq!(listed, from_routes);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user