Files
hottub/src/proxies/hanimecdn.rs
2026-03-15 23:47:32 +00:00

88 lines
2.5 KiB
Rust

use ntex::http::header::{CONTENT_LENGTH, CONTENT_TYPE};
use ntex::{
http::Response,
web::{self, HttpRequest, error},
};
use crate::util::requester::Requester;
fn normalize_image_url(endpoint: &str) -> String {
let endpoint = endpoint.trim_start_matches('/');
if endpoint.starts_with("http://") || endpoint.starts_with("https://") {
endpoint.to_string()
} else if endpoint.starts_with("hanime-cdn.com/") || endpoint == "hanime-cdn.com" {
format!("https://{endpoint}")
} else {
format!("https://hanime-cdn.com/{endpoint}")
}
}
pub async fn get_image(
req: HttpRequest,
requester: web::types::State<Requester>,
) -> Result<impl web::Responder, web::Error> {
let endpoint = req.match_info().query("endpoint").to_string();
let image_url = normalize_image_url(&endpoint);
let upstream = match requester
.get_ref()
.clone()
.get_raw_with_headers(
image_url.as_str(),
vec![("Referer".to_string(), "https://hanime.tv/".to_string())],
)
.await
{
Ok(response) => response,
Err(_) => return Ok(web::HttpResponse::NotFound().finish()),
};
let status = upstream.status();
let headers = upstream.headers().clone();
// Read body from upstream
let bytes = upstream.bytes().await.map_err(error::ErrorBadGateway)?;
// Build response and forward headers
let mut resp = Response::build(status);
if let Some(ct) = headers.get(CONTENT_TYPE) {
if let Ok(ct_str) = ct.to_str() {
resp.set_header(CONTENT_TYPE, ct_str);
}
}
if let Some(cl) = headers.get(CONTENT_LENGTH) {
if let Ok(cl_str) = cl.to_str() {
resp.set_header(CONTENT_LENGTH, cl_str);
}
}
// Either zero-copy to ntex Bytes...
// Ok(resp.body(NtexBytes::from(bytes)))
// ...or simple & compatible:
Ok(resp.body(bytes.to_vec()))
}
#[cfg(test)]
mod tests {
use super::normalize_image_url;
#[test]
fn keeps_full_hanime_cdn_host_path_without_duplication() {
assert_eq!(
normalize_image_url("hanime-cdn.com/images/covers/natsu-zuma-2-cv1.png"),
"https://hanime-cdn.com/images/covers/natsu-zuma-2-cv1.png"
);
}
#[test]
fn prefixes_relative_paths_with_hanime_cdn_host() {
assert_eq!(
normalize_image_url("/images/covers/natsu-zuma-2-cv1.png"),
"https://hanime-cdn.com/images/covers/natsu-zuma-2-cv1.png"
);
}
}