noodlemagazine fix
This commit is contained in:
@@ -10,6 +10,7 @@ use crate::videos::{ServerOptions, VideoFormat, VideoItem};
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use error_chain::error_chain;
|
use error_chain::error_chain;
|
||||||
use htmlentity::entity::{ICodedDataTrait, decode};
|
use htmlentity::entity::{ICodedDataTrait, decode};
|
||||||
|
use std::net::IpAddr;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use titlecase::Titlecase;
|
use titlecase::Titlecase;
|
||||||
@@ -197,6 +198,31 @@ impl NoodlemagazineProvider {
|
|||||||
.any(|ext| path.ends_with(ext))
|
.any(|ext| path.ends_with(ext))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_disallowed_thumb_host(host: &str) -> bool {
|
||||||
|
if host.eq_ignore_ascii_case("localhost") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match host.parse::<IpAddr>() {
|
||||||
|
Ok(IpAddr::V4(ip)) => {
|
||||||
|
ip.is_private()
|
||||||
|
|| ip.is_loopback()
|
||||||
|
|| ip.is_link_local()
|
||||||
|
|| ip.is_broadcast()
|
||||||
|
|| ip.is_documentation()
|
||||||
|
|| ip.is_unspecified()
|
||||||
|
}
|
||||||
|
Ok(IpAddr::V6(ip)) => {
|
||||||
|
ip.is_loopback()
|
||||||
|
|| ip.is_unspecified()
|
||||||
|
|| ip.is_multicast()
|
||||||
|
|| ip.is_unique_local()
|
||||||
|
|| ip.is_unicast_link_local()
|
||||||
|
}
|
||||||
|
Err(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_allowed_thumb_url(&self, url: &str) -> bool {
|
fn is_allowed_thumb_url(&self, url: &str) -> bool {
|
||||||
let Some(url) = Url::parse(url).ok() else {
|
let Some(url) = Url::parse(url).ok() else {
|
||||||
return false;
|
return false;
|
||||||
@@ -207,9 +233,8 @@ impl NoodlemagazineProvider {
|
|||||||
let Some(host) = url.host_str() else {
|
let Some(host) = url.host_str() else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let is_noodlemagazine_host = host == "noodlemagazine.com" || host.ends_with(".noodlemagazine.com");
|
|
||||||
|
|
||||||
is_noodlemagazine_host && Self::has_allowed_image_extension(url.path())
|
!Self::is_disallowed_thumb_host(host) && Self::has_allowed_image_extension(url.path())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn proxied_thumb(&self, options: &ServerOptions, thumb: &str) -> String {
|
fn proxied_thumb(&self, options: &ServerOptions, thumb: &str) -> String {
|
||||||
@@ -395,7 +420,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn drops_non_noodlemagazine_or_non_image_thumbs() {
|
fn keeps_https_cdn_thumbs_but_drops_non_images() {
|
||||||
let provider = NoodlemagazineProvider::new();
|
let provider = NoodlemagazineProvider::new();
|
||||||
let options = options();
|
let options = options();
|
||||||
let html = r#"
|
let html = r#"
|
||||||
@@ -422,6 +447,10 @@ mod tests {
|
|||||||
let items = provider.get_video_items_from_html(html.to_string(), &options);
|
let items = provider.get_video_items_from_html(html.to_string(), &options);
|
||||||
|
|
||||||
assert_eq!(items.len(), 2);
|
assert_eq!(items.len(), 2);
|
||||||
assert!(items.iter().all(|item| item.thumb.is_empty()));
|
assert_eq!(
|
||||||
|
items[0].thumb,
|
||||||
|
"https://example.com/proxy/noodlemagazine-thumb/cdn.example/thumb.jpg"
|
||||||
|
);
|
||||||
|
assert!(items[1].thumb.is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use ntex::{
|
|||||||
web::{self, HttpRequest, error},
|
web::{self, HttpRequest, error},
|
||||||
};
|
};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use std::net::IpAddr;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use wreq::Version;
|
use wreq::Version;
|
||||||
|
|
||||||
@@ -110,6 +111,31 @@ impl NoodlemagazineProxy {
|
|||||||
.any(|ext| path.ends_with(ext))
|
.any(|ext| path.ends_with(ext))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_disallowed_thumb_host(host: &str) -> bool {
|
||||||
|
if host.eq_ignore_ascii_case("localhost") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match host.parse::<IpAddr>() {
|
||||||
|
Ok(IpAddr::V4(ip)) => {
|
||||||
|
ip.is_private()
|
||||||
|
|| ip.is_loopback()
|
||||||
|
|| ip.is_link_local()
|
||||||
|
|| ip.is_broadcast()
|
||||||
|
|| ip.is_documentation()
|
||||||
|
|| ip.is_unspecified()
|
||||||
|
}
|
||||||
|
Ok(IpAddr::V6(ip)) => {
|
||||||
|
ip.is_loopback()
|
||||||
|
|| ip.is_unspecified()
|
||||||
|
|| ip.is_multicast()
|
||||||
|
|| ip.is_unique_local()
|
||||||
|
|| ip.is_unicast_link_local()
|
||||||
|
}
|
||||||
|
Err(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_allowed_thumb_url(url: &str) -> bool {
|
fn is_allowed_thumb_url(url: &str) -> bool {
|
||||||
let Some(url) = Url::parse(url).ok() else {
|
let Some(url) = Url::parse(url).ok() else {
|
||||||
return false;
|
return false;
|
||||||
@@ -121,8 +147,7 @@ impl NoodlemagazineProxy {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
(host == "noodlemagazine.com" || host.ends_with(".noodlemagazine.com"))
|
!Self::is_disallowed_thumb_host(host) && Self::has_allowed_image_extension(url.path())
|
||||||
&& Self::has_allowed_image_extension(url.path())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_binary_image_content_type(content_type: &str) -> bool {
|
fn is_binary_image_content_type(content_type: &str) -> bool {
|
||||||
@@ -388,18 +413,18 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn allows_only_noodlemagazine_image_thumbs() {
|
fn allows_https_image_thumbs_but_rejects_local_or_non_images() {
|
||||||
assert!(NoodlemagazineProxy::is_allowed_thumb_url(
|
assert!(NoodlemagazineProxy::is_allowed_thumb_url(
|
||||||
"https://noodlemagazine.com/thumbs/example.webp"
|
"https://noodlemagazine.com/thumbs/example.webp"
|
||||||
));
|
));
|
||||||
assert!(NoodlemagazineProxy::is_allowed_thumb_url(
|
assert!(NoodlemagazineProxy::is_allowed_thumb_url(
|
||||||
"https://img.noodlemagazine.com/previews/example.jpg"
|
"https://cdn.example/previews/example.jpg"
|
||||||
));
|
));
|
||||||
assert!(!NoodlemagazineProxy::is_allowed_thumb_url(
|
assert!(!NoodlemagazineProxy::is_allowed_thumb_url(
|
||||||
"https://noodlemagazine.com/watch/-123_456"
|
"https://noodlemagazine.com/watch/-123_456"
|
||||||
));
|
));
|
||||||
assert!(!NoodlemagazineProxy::is_allowed_thumb_url(
|
assert!(!NoodlemagazineProxy::is_allowed_thumb_url(
|
||||||
"https://cdn.example/thumb.jpg"
|
"https://localhost/thumb.jpg"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user