2021-01-03 17:50:23 +13:00
|
|
|
use actix_web::{client::Client, error, web, Error, HttpResponse, Result};
|
|
|
|
use url::Url;
|
2020-11-30 15:50:29 +13:00
|
|
|
|
2020-12-01 17:33:55 +13:00
|
|
|
use base64::decode;
|
2020-11-23 17:22:51 +13:00
|
|
|
|
2021-01-03 17:50:23 +13:00
|
|
|
pub async fn handler(web::Path(b64): web::Path<String>) -> Result<HttpResponse> {
|
|
|
|
let domains = vec![
|
2021-01-04 07:22:41 +13:00
|
|
|
// THUMBNAILS
|
2021-01-03 17:50:23 +13:00
|
|
|
"a.thumbs.redditmedia.com",
|
|
|
|
"b.thumbs.redditmedia.com",
|
2021-01-04 07:22:41 +13:00
|
|
|
// ICONS
|
|
|
|
"styles.redditmedia.com",
|
2021-01-04 15:23:57 +13:00
|
|
|
"www.redditstatic.com",
|
2021-01-04 07:22:41 +13:00
|
|
|
// PREVIEWS
|
2021-01-03 17:50:23 +13:00
|
|
|
"preview.redd.it",
|
|
|
|
"external-preview.redd.it",
|
2021-01-04 07:22:41 +13:00
|
|
|
// MEDIA
|
2021-01-03 17:50:23 +13:00
|
|
|
"i.redd.it",
|
|
|
|
"v.redd.it",
|
|
|
|
];
|
2020-11-30 15:50:29 +13:00
|
|
|
|
2021-01-03 17:50:23 +13:00
|
|
|
match decode(b64) {
|
|
|
|
Ok(bytes) => {
|
|
|
|
let media = String::from_utf8(bytes).unwrap();
|
2020-12-01 17:33:55 +13:00
|
|
|
|
2021-01-03 17:50:23 +13:00
|
|
|
match Url::parse(media.as_str()) {
|
|
|
|
Ok(url) => {
|
|
|
|
let domain = url.domain().unwrap_or_default();
|
2020-11-30 15:50:29 +13:00
|
|
|
|
2021-01-03 17:50:23 +13:00
|
|
|
if domains.contains(&domain) {
|
|
|
|
Client::default()
|
|
|
|
.get(media.replace("&", "&"))
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
.map_err(Error::from)
|
|
|
|
.map(|res| HttpResponse::build(res.status()).streaming(res))
|
|
|
|
} else {
|
|
|
|
Err(error::ErrorForbidden("Resource must be from Reddit"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(_) => Err(error::ErrorBadRequest("Can't parse encoded base64 URL")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(_) => Err(error::ErrorBadRequest("Can't decode base64 URL")),
|
2020-11-24 13:57:37 +13:00
|
|
|
}
|
2020-11-30 15:50:29 +13:00
|
|
|
}
|