Individually proxy videos

This commit is contained in:
spikecodes 2021-02-18 10:04:59 -08:00
parent 2f4deb221a
commit 58127b17d8
No known key found for this signature in database
GPG key ID: 004CECFF9B463BCB
5 changed files with 67 additions and 54 deletions

View file

@ -146,6 +146,8 @@ async fn main() -> tide::Result<()> {
// Proxy media through Libreddit
app.at("/proxy/*url/").get(proxy::handler);
app.at("/vid/:id/:size/").get(proxy::video);
app.at("/img/:id/").get(proxy::image);
// Browse user profile
app.at("/u/:name/").get(user::profile);

View file

@ -165,7 +165,7 @@ async fn parse_comments(json: &serde_json::Value, post_link: &str, post_author:
};
let parent_kind_and_id = val(&comment, "parent_id");
let parent_info = parent_kind_and_id.split("_").collect::<Vec<&str>>();
let parent_info = parent_kind_and_id.split('_').collect::<Vec<&str>>();
let id = val(&comment, "id");
let highlighted = id == highlighted_comment;

View file

@ -17,7 +17,6 @@ pub async fn handler(req: Request<()>) -> tide::Result {
"external-preview.redd.it",
// MEDIA
"i.redd.it",
"v.redd.it",
];
let decoded = decode(req.param("url").unwrap_or_default()).map(|bytes| String::from_utf8(bytes).unwrap_or_default());
@ -26,19 +25,7 @@ pub async fn handler(req: Request<()>) -> tide::Result {
Ok(media) => match Url::parse(media.as_str()) {
Ok(url) => {
if domains.contains(&url.domain().unwrap_or_default()) {
let http = surf::get(url).await.unwrap();
let content_length = http.header("Content-Length").map(|v| v.to_string()).unwrap_or_default();
let content_type = http.content_type().map(|m| m.to_string()).unwrap_or_default();
Ok(
Response::builder(http.status())
.body(Body::from_reader(http, None))
.header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
.header("Content-Length", content_length)
.header("Content-Type", content_type)
.build(),
)
request(url.to_string()).await
} else {
Err(tide::Error::from_str(403, "Resource must be from Reddit"))
}
@ -48,3 +35,32 @@ pub async fn handler(req: Request<()>) -> tide::Result {
Err(_) => Err(tide::Error::from_str(400, "Can't decode base64")),
}
}
pub async fn video(req: Request<()>) -> tide::Result {
let id = req.param("id").unwrap_or_default();
let size = req.param("size").unwrap_or("720.mp4");
let url = format!("https://v.redd.it/{}/DASH_{}", id, size);
request(url).await
}
pub async fn image(req: Request<()>) -> tide::Result {
let id = req.param("id").unwrap_or_default();
let url = format!("https://i.redd.it/{}", id);
request(url).await
}
async fn request(url: String) -> tide::Result {
let http = surf::get(url).await.unwrap();
let content_length = http.header("Content-Length").map(|v| v.to_string()).unwrap_or_default();
let content_type = http.content_type().map(|m| m.to_string()).unwrap_or_default();
Ok(
Response::builder(http.status())
.body(Body::from_reader(http, None))
.header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
.header("Content-Length", content_length)
.header("Content-Type", content_type)
.build(),
)
}

View file

@ -186,13 +186,28 @@ pub fn format_url(url: &str) -> String {
if url.is_empty() || url == "self" || url == "default" || url == "nsfw" || url == "spoiler" {
String::new()
} else {
format!("/proxy/{}/", encode(url).as_str())
let domain = Url::parse(url).map(|f| f.domain().unwrap_or_default().to_owned()).unwrap_or_default();
match domain.as_str() {
"v.redd.it" => {
let re = Regex::new(r"https://v\.redd\.it/(.*)/DASH_([0-9]{2,4}(\.mp4|$))").unwrap();
match re.captures(url) {
Some(caps) => format!("/vid/{}/{}", &caps[1], &caps[2]),
None => {
dbg!(url);
String::new()
}
}
}
_ => format!("/proxy/{}/", encode(url).as_str()),
}
}
}
// Rewrite Reddit links to Libreddit in body of text
pub fn rewrite_urls(text: &str) -> String {
let re = Regex::new(r#"href="(https://|http://|)(www.|old.|np.|)(reddit).(com)/"#).unwrap();
let re = Regex::new(r#"href="(https|http|)://(www.|old.|np.|)(reddit).(com)/"#).unwrap();
re.replace_all(text, r#"href="/"#).to_string()
}
@ -208,12 +223,12 @@ pub fn format_num(num: i64) -> String {
}
pub async fn media(data: &Value) -> (String, Media, Vec<GalleryMedia>) {
let post_type: &str;
let post_type;
let mut gallery = Vec::new();
// If post is a video, return the video
let url = if data["preview"]["reddit_video_preview"]["fallback_url"].is_string() {
// Return video preview
// Return reddit video
post_type = "video";
format_url(data["preview"]["reddit_video_preview"]["fallback_url"].as_str().unwrap_or_default())
} else if data["secure_media"]["reddit_video"]["fallback_url"].is_string() {