diff --git a/src/main.rs b/src/main.rs index a1f72fd..53ae973 100644 --- a/src/main.rs +++ b/src/main.rs @@ -176,6 +176,8 @@ async fn main() -> tide::Result<()> { app.at("/img/:id/").get(proxy::image); app.at("/thumb/:point/:id/").get(proxy::thumbnail); app.at("/emoji/:id/:name/").get(proxy::emoji); + app.at("/preview/:location/:id/:query/").get(proxy::preview); + app.at("/style/*path/").get(proxy::style); // Browse user profile app.at("/u/:name/").get(user::profile); diff --git a/src/proxy.rs b/src/proxy.rs index c1deee9..14f8c9f 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -4,14 +4,9 @@ use tide::{Request, Response}; pub async fn handler(req: Request<()>) -> tide::Result { let domains = vec![ - // EMOJI - "emoji.redditmedia.com", // ICONS "styles.redditmedia.com", "www.redditstatic.com", - // PREVIEWS - "preview.redd.it", - "external-preview.redd.it", ]; let decoded = decode(req.param("url").unwrap_or_default()).map(|bytes| String::from_utf8(bytes).unwrap_or_default()); @@ -58,6 +53,23 @@ pub async fn emoji(req: Request<()>) -> tide::Result { request(url).await } +pub async fn preview(req: Request<()>) -> tide::Result { + let id = req.param("id").unwrap_or_default(); + let query = req.param("query").unwrap_or_default(); + let prefix = match req.param("location").unwrap_or_default() { + "ext" => "external-", + _ => "" + }; + let url = format!("https://{}preview.redd.it/{}?{}", prefix, id, query); + request(url).await +} + +pub async fn style(req: Request<()>) -> tide::Result { + let path = req.param("path").unwrap_or_default(); + let url = format!("https://styles.redditmedia.com/{}", path); + request(url).await +} + async fn request(url: String) -> tide::Result { let http = surf::get(url).await.unwrap(); diff --git a/src/utils.rs b/src/utils.rs index 2e83841..bfb9e1e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -186,7 +186,8 @@ pub fn format_url(url: &str) -> String { if url.is_empty() || url == "self" || url == "default" || url == "nsfw" || url == "spoiler" { String::new() } else { - let domain = Url::parse(url).map(|f| f.domain().unwrap_or_default().to_owned()).unwrap_or_default(); + let parsed = Url::parse(url).unwrap(); + let domain = parsed.domain().unwrap_or_default(); let capture = |regex: &str, format: &str, levels: i16| { Regex::new(regex) @@ -194,19 +195,22 @@ pub fn format_url(url: &str) -> String { Some(caps) => match levels { 1 => [format, &caps[1], "/"].join(""), 2 => [format, &caps[1], "/", &caps[2], "/"].join(""), - _ => String::new() + _ => String::new(), }, None => String::new(), }) .unwrap_or_default() }; - match domain.as_str() { + match domain { "v.redd.it" => capture(r"https://v\.redd\.it/(.*)/DASH_([0-9]{2,4}(\.mp4|$))", "/vid/", 2), "i.redd.it" => capture(r"https://i\.redd\.it/(.*)", "/img/", 1), "a.thumbs.redditmedia.com" => capture(r"https://a\.thumbs\.redditmedia\.com/(.*)", "/thumb/a/", 1), "b.thumbs.redditmedia.com" => capture(r"https://b\.thumbs\.redditmedia\.com/(.*)", "/thumb/b/", 1), "emoji.redditmedia.com" => capture(r"https://emoji\.redditmedia\.com/(.*)/(.*)", "/emoji/", 2), + "preview.redd.it" => capture(r"https://preview\.redd\.it/(.*)\?(.*)", "/preview/int/", 2), + "external-preview.redd.it" => capture(r"https://external\-preview\.redd\.it/(.*)\?(.*)", "/preview/ext/", 2), + // "styles.redditmedia.com" => capture(r"https://styles\.redditmedia\.com/(.*)", "/style/", 1), _ => format!("/proxy/{}/", encode(url).as_str()), } }