This commit is contained in:
Simon
2026-03-22 15:56:25 +00:00
parent 52f108da8e
commit fbe04fc752
12 changed files with 4960 additions and 26 deletions

3
.gitignore vendored
View File

@@ -3,7 +3,7 @@
# will have compiled files and executables # will have compiled files and executables
debug/ debug/
target/ target/
.testing/ .*/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
@@ -17,4 +17,3 @@ Cargo.lock
*.db *.db
migrations/.keep migrations/.keep
.vscode

View File

@@ -36,6 +36,7 @@ dashmap = "6.1.0"
lru = "0.16.3" lru = "0.16.3"
rand = "0.10.0" rand = "0.10.0"
chrono = "0.4.44" chrono = "0.4.44"
md5 = "0.8.0"
[lints.rust] [lints.rust]
unexpected_cfgs = "allow" unexpected_cfgs = "allow"

View File

@@ -29,6 +29,11 @@ const PROVIDERS: &[ProviderDef] = &[
module: "pornhub", module: "pornhub",
ty: "PornhubProvider", ty: "PornhubProvider",
}, },
ProviderDef {
id: "pornhd3x",
module: "pornhd3x",
ty: "Pornhd3xProvider",
},
ProviderDef { ProviderDef {
id: "spankbang", id: "spankbang",
module: "spankbang", module: "spankbang",
@@ -84,6 +89,11 @@ const PROVIDERS: &[ProviderDef] = &[
module: "yesporn", module: "yesporn",
ty: "YespornProvider", ty: "YespornProvider",
}, },
ProviderDef {
id: "arabpornxxx",
module: "arabpornxxx",
ty: "ArabpornxxxProvider",
},
ProviderDef { ProviderDef {
id: "sxyprn", id: "sxyprn",
module: "sxyprn", module: "sxyprn",
@@ -109,6 +119,11 @@ const PROVIDERS: &[ProviderDef] = &[
module: "porn4fans", module: "porn4fans",
ty: "Porn4fansProvider", ty: "Porn4fansProvider",
}, },
ProviderDef {
id: "pornmz",
module: "pornmz",
ty: "PornmzProvider",
},
ProviderDef { ProviderDef {
id: "porndish", id: "porndish",
module: "porndish", module: "porndish",
@@ -214,6 +229,11 @@ const PROVIDERS: &[ProviderDef] = &[
module: "hsex", module: "hsex",
ty: "HsexProvider", ty: "HsexProvider",
}, },
ProviderDef {
id: "sextb",
module: "sextb",
ty: "SextbProvider",
},
ProviderDef { ProviderDef {
id: "hentaihaven", id: "hentaihaven",
module: "hentaihaven", module: "hentaihaven",
@@ -236,9 +256,7 @@ fn main() {
.map(|provider| format!("\"{}\"", provider.id)) .map(|provider| format!("\"{}\"", provider.id))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "); .join(", ");
println!( println!("cargo:rustc-check-cfg=cfg(hottub_provider, values({provider_cfg_values}))");
"cargo:rustc-check-cfg=cfg(hottub_provider, values({provider_cfg_values}))"
);
let selected = env::var("HOT_TUB_PROVIDER") let selected = env::var("HOT_TUB_PROVIDER")
.or_else(|_| env::var("HOTTUB_PROVIDER")) .or_else(|_| env::var("HOTTUB_PROVIDER"))

View File

@@ -59,10 +59,7 @@ async fn main() -> std::io::Result<()> {
let mut requester = util::requester::Requester::new(); let mut requester = util::requester::Requester::new();
let proxy_enabled = env::var("PROXY").unwrap_or("0".to_string()) != "0".to_string(); let proxy_enabled = env::var("PROXY").unwrap_or("0".to_string()) != "0".to_string();
requester.set_proxy(proxy_enabled); requester.set_proxy(proxy_enabled);
crate::flow_debug!( crate::flow_debug!("requester initialized proxy_enabled={}", proxy_enabled);
"requester initialized proxy_enabled={}",
proxy_enabled
);
let cache: util::cache::VideoCache = crate::util::cache::VideoCache::new() let cache: util::cache::VideoCache = crate::util::cache::VideoCache::new()
.max_size(100_000) .max_size(100_000)

1171
src/providers/arabpornxxx.rs Normal file

File diff suppressed because it is too large Load Diff

1298
src/providers/pornhd3x.rs Normal file

File diff suppressed because it is too large Load Diff

1241
src/providers/pornmz.rs Normal file

File diff suppressed because it is too large Load Diff

1210
src/providers/sextb.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -14,8 +14,7 @@ const FIREFOX_USER_AGENT: &str =
"Mozilla/5.0 (X11; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0"; "Mozilla/5.0 (X11; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0";
const HTML_ACCEPT: &str = const HTML_ACCEPT: &str =
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"; "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8";
const IMAGE_ACCEPT: &str = const IMAGE_ACCEPT: &str = "image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5";
"image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5";
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct NoodlemagazineProxy {} pub struct NoodlemagazineProxy {}
@@ -321,11 +320,7 @@ pub async fn get_image(
if needs_warmup { if needs_warmup {
let _ = requester let _ = requester
.get_with_headers( .get_with_headers(image_url.as_str(), headers.clone(), Some(Version::HTTP_11))
image_url.as_str(),
headers.clone(),
Some(Version::HTTP_11),
)
.await; .await;
headers = NoodlemagazineProxy::image_headers(&requester, image_url.as_str()); headers = NoodlemagazineProxy::image_headers(&requester, image_url.as_str());
upstream = requester upstream = requester

View File

@@ -51,7 +51,10 @@ impl PimpbunnyProxy {
fn html_headers_with_referer(referer: &str) -> Vec<(String, String)> { fn html_headers_with_referer(referer: &str) -> Vec<(String, String)> {
vec![ vec![
("Referer".to_string(), referer.to_string()), ("Referer".to_string(), referer.to_string()),
("User-Agent".to_string(), Self::FIREFOX_USER_AGENT.to_string()), (
"User-Agent".to_string(),
Self::FIREFOX_USER_AGENT.to_string(),
),
("Accept".to_string(), Self::HTML_ACCEPT.to_string()), ("Accept".to_string(), Self::HTML_ACCEPT.to_string()),
("Accept-Language".to_string(), "en-US,en;q=0.9".to_string()), ("Accept-Language".to_string(), "en-US,en;q=0.9".to_string()),
] ]
@@ -80,7 +83,8 @@ impl PimpbunnyProxy {
} }
fn extract_json_ld_video(text: &str) -> Option<Value> { fn extract_json_ld_video(text: &str) -> Option<Value> {
let script_regex = Regex::new(r#"(?s)<script[^>]+application/ld\+json[^>]*>(.*?)</script>"#).ok()?; let script_regex =
Regex::new(r#"(?s)<script[^>]+application/ld\+json[^>]*>(.*?)</script>"#).ok()?;
for captures in script_regex.captures_iter(text) { for captures in script_regex.captures_iter(text) {
let raw = captures.get(1).map(|value| value.as_str().trim())?; let raw = captures.get(1).map(|value| value.as_str().trim())?;
@@ -228,7 +232,8 @@ mod tests {
</script> </script>
"#; "#;
let json_ld = PimpbunnyProxy::extract_json_ld_video(html).expect("video object should parse"); let json_ld =
PimpbunnyProxy::extract_json_ld_video(html).expect("video object should parse");
assert_eq!( assert_eq!(
PimpbunnyProxy::extract_stream_url(&json_ld).as_deref(), PimpbunnyProxy::extract_stream_url(&json_ld).as_deref(),
Some("https://cdn.example/graph.mp4") Some("https://cdn.example/graph.mp4")

View File

@@ -12,8 +12,7 @@ const FIREFOX_USER_AGENT: &str =
"Mozilla/5.0 (X11; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0"; "Mozilla/5.0 (X11; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0";
const HTML_ACCEPT: &str = const HTML_ACCEPT: &str =
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"; "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8";
const IMAGE_ACCEPT: &str = const IMAGE_ACCEPT: &str = "image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5";
"image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5";
fn root_referer() -> &'static str { fn root_referer() -> &'static str {
"https://pimpbunny.com/" "https://pimpbunny.com/"
@@ -157,7 +156,9 @@ mod tests {
#[test] #[test]
fn rejects_non_thumb_or_non_pimpbunny_urls() { fn rejects_non_thumb_or_non_pimpbunny_urls() {
assert!(!is_allowed_thumb_url("http://pimpbunny.com/contents/videos_screenshots/x.jpg")); assert!(!is_allowed_thumb_url(
"http://pimpbunny.com/contents/videos_screenshots/x.jpg"
));
assert!(!is_allowed_thumb_url( assert!(!is_allowed_thumb_url(
"https://pimpbunny.com/videos/example-video/" "https://pimpbunny.com/videos/example-video/"
)); ));

View File

@@ -563,10 +563,8 @@ mod tests {
let b = Requester::new(); let b = Requester::new();
let origin = "https://shared-cookie-requester-test.invalid/"; let origin = "https://shared-cookie-requester-test.invalid/";
a.cookie_jar.add_cookie_str( a.cookie_jar
"shared_cookie=1; Path=/; SameSite=Lax", .add_cookie_str("shared_cookie=1; Path=/; SameSite=Lax", origin);
origin,
);
let cookie_header = b let cookie_header = b
.cookie_header_for_url("https://shared-cookie-requester-test.invalid/path") .cookie_header_for_url("https://shared-cookie-requester-test.invalid/path")