From 45d8f1bbc813e924678bcb355bffd25034693b38 Mon Sep 17 00:00:00 2001 From: Matthew Esposito Date: Fri, 29 Dec 2023 19:28:41 -0500 Subject: [PATCH] Better handle redirects with new OAuth endpoints --- src/client.rs | 21 +++++++++++++++++++-- src/config.rs | 2 +- src/main.rs | 5 ++++- src/subreddit.rs | 1 + 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/client.rs b/src/client.rs index f98176a..20a7ec1 100644 --- a/src/client.rs +++ b/src/client.rs @@ -17,6 +17,7 @@ use crate::dbg_msg; use crate::instance_info::INSTANCE_INFO; use crate::oauth::{token_daemon, Oauth}; use crate::server::RequestExt; +use crate::utils::format_url; const REDDIT_URL_BASE: &str = "https://oauth.reddit.com"; @@ -56,7 +57,16 @@ pub async fn canonical_path(path: String) -> Result, String> { // If Reddit responds with a 301, then the path is redirected. 301 => match res.headers().get(header::LOCATION) { - Some(val) => Ok(Some(val.to_str().unwrap().to_string())), + Some(val) => { + let original = val.to_str().unwrap(); + // The reason why we now have to format_url, is because the new OAuth + // endpoints seem to return full paths, instead of relative paths. + // So we need to strip the .json suffix from the original path, and + // also remove all Reddit domain parts with format_url. + // Otherwise, it will literally redirect to Reddit.com. + let uri = format_url(original.strip_suffix(".json").unwrap_or(original)); + Ok(Some(uri)) + } None => Ok(None), }, @@ -347,6 +357,13 @@ async fn test_localization_popular() { #[tokio::test(flavor = "multi_thread", worker_threads = 8)] async fn test_obfuscated_share_link() { let share_link = "/r/rust/s/kPgq8WNHRK".into(); - let canonical_link = "https://www.reddit.com/r/rust/comments/18t5968/why_use_tuple_struct_over_standard_struct/kfbqlbc?share_id=N0wD38nOLSUMMNnWpDRO3&utm_content=2&utm_medium=android_app&utm_name=androidcss&utm_source=share&utm_term=1".into(); + let canonical_link = "/r/rust/comments/18t5968/why_use_tuple_struct_over_standard_struct/kfbqlbc?share_id=N0wD38nOLSUMMNnWpDRO3&utm_content=2&utm_medium=android_app&utm_name=androidcss&utm_source=share&utm_term=1".into(); assert_eq!(canonical_path(share_link).await, Ok(Some(canonical_link))); } + +#[tokio::test(flavor = "multi_thread", worker_threads = 8)] +async fn test_share_link_strip_json() { + let link = "/17krzvz".into(); + let canonical_link = "/r/nfl/comments/17krzvz/rapoport_sources_former_no_2_overall_pick/".into(); + assert_eq!(canonical_path(link).await, Ok(Some(canonical_link))); +} diff --git a/src/config.rs b/src/config.rs index 44466ec..e398d9f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -267,4 +267,4 @@ fn test_pushshift() { write("redlib.toml", config_to_write).unwrap(); assert!(get_setting("REDLIB_PUSHSHIFT_FRONTEND").is_some()); assert_eq!(get_setting("REDLIB_PUSHSHIFT_FRONTEND"), Some("https://api.pushshift.io".into())); -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index ff6c9ec..6c53dc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -335,7 +335,10 @@ async fn main() { match req.param("id").as_deref() { // Share link Some(id) if (8..12).contains(&id.len()) => match canonical_path(format!("/r/{}/s/{}", sub, id)).await { - Ok(Some(path)) => Ok(redirect(path.split('?').next().unwrap_or_default().to_string())), + Ok(Some(path)) => { + // Remove share parameters here. + Ok(redirect(path.split('?').next().unwrap_or_default().to_string())) + } Ok(None) => error(req, "Post ID is invalid. It may point to a post on a community that has been banned.").await, Err(e) => error(req, e).await, }, diff --git a/src/subreddit.rs b/src/subreddit.rs index 30499f0..1130c0b 100644 --- a/src/subreddit.rs +++ b/src/subreddit.rs @@ -6,6 +6,7 @@ use crate::{client::json, server::ResponseExt, RequestExt}; use askama::Template; use cookie::Cookie; use hyper::{Body, Request, Response}; + use time::{Duration, OffsetDateTime}; // STRUCTS