Add optional capability to load media (image and video) directly from reddit on client.

Not that this might have privacy implication of leaking user's ip address to reddit.
But this also means the server load and traffic will reduce.
This commit is contained in:
serenissi 2025-03-24 14:22:32 +05:30
parent cbc3e49923
commit 0f1783153f
6 changed files with 44 additions and 5 deletions

View file

@ -416,7 +416,8 @@ Assign a default value for each instance-specific setting by passing environment
| `PUSHSHIFT_FRONTEND` | String | `undelete.pullpush.io` | Allows the server to set the Pushshift frontend to be used with "removed" links. | | `PUSHSHIFT_FRONTEND` | String | `undelete.pullpush.io` | Allows the server to set the Pushshift frontend to be used with "removed" links. |
| `PORT` | Integer 0-65535 | `8080` | The **internal** port Redlib listens on. | | `PORT` | Integer 0-65535 | `8080` | The **internal** port Redlib listens on. |
| `ENABLE_RSS` | `["on", "off"]` | `off` | Enables RSS feed generation. | | `ENABLE_RSS` | `["on", "off"]` | `off` | Enables RSS feed generation. |
| `FULL_URL` | String | (empty) | Allows for proper URLs (for now, only needed by RSS) | `FULL_URL` | String | (empty) | Allows for proper URLs (for now, only needed by RSS) |
| `TAINTED_MEDIA` | `["on", "off"]` | `off` | ⚠️ Enable images and video load clientside from **reddit**. Trade privacy with server load. |
## Default user settings ## Default user settings
Assign a default value for each user-modifiable setting by passing environment variables to Redlib in the format `REDLIB_DEFAULT_{Y}`. Replace `{Y}` with the setting name (see list below) in capital letters. Assign a default value for each user-modifiable setting by passing environment variables to Redlib in the format `REDLIB_DEFAULT_{Y}`. Replace `{Y}` with the setting name (see list below) in capital letters.

View file

@ -79,6 +79,9 @@
}, },
"REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS": { "REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS": {
"required": false "required": false
},
"REDLIB_TAINTED_MEDIA": {
"required": false
} }
} }
} }

View file

@ -15,3 +15,4 @@ PORT=12345
#REDLIB_DEFAULT_SUBSCRIPTIONS=(sub1+sub2+sub3) #REDLIB_DEFAULT_SUBSCRIPTIONS=(sub1+sub2+sub3)
#REDLIB_DEFAULT_HIDE_AWARDS=off #REDLIB_DEFAULT_HIDE_AWARDS=off
#REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION=off #REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION=off
#REDLIB_TAINTED_MEDIA=off

View file

@ -112,6 +112,9 @@ pub struct Config {
#[serde(rename = "REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS")] #[serde(rename = "REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS")]
pub(crate) default_remove_default_feeds: Option<String>, pub(crate) default_remove_default_feeds: Option<String>,
#[serde(rename = "REDLIB_TAINTED_MEDIA")]
pub(crate) tainted_media: Option<String>,
} }
impl Config { impl Config {
@ -160,6 +163,7 @@ impl Config {
enable_rss: parse("REDLIB_ENABLE_RSS"), enable_rss: parse("REDLIB_ENABLE_RSS"),
full_url: parse("REDLIB_FULL_URL"), full_url: parse("REDLIB_FULL_URL"),
default_remove_default_feeds: parse("REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS"), default_remove_default_feeds: parse("REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS"),
tainted_media: parse("REDLIB_TAINTED_MEDIA"),
} }
} }
} }
@ -190,6 +194,7 @@ fn get_setting_from_config(name: &str, config: &Config) -> Option<String> {
"REDLIB_ENABLE_RSS" => config.enable_rss.clone(), "REDLIB_ENABLE_RSS" => config.enable_rss.clone(),
"REDLIB_FULL_URL" => config.full_url.clone(), "REDLIB_FULL_URL" => config.full_url.clone(),
"REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS" => config.default_remove_default_feeds.clone(), "REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS" => config.default_remove_default_feeds.clone(),
"REDLIB_TAINTED_MEDIA" => config.tainted_media.clone(),
_ => None, _ => None,
} }
} }

View file

@ -211,7 +211,16 @@ async fn main() {
"Referrer-Policy" => "no-referrer", "Referrer-Policy" => "no-referrer",
"X-Content-Type-Options" => "nosniff", "X-Content-Type-Options" => "nosniff",
"X-Frame-Options" => "DENY", "X-Frame-Options" => "DENY",
"Content-Security-Policy" => "default-src 'none'; font-src 'self'; script-src 'self' blob:; manifest-src 'self'; media-src 'self' data: blob: about:; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none'; connect-src 'self'; worker-src blob:;" "Content-Security-Policy" =>
if match config::get_setting("REDLIB_TAINTED_MEDIA") {
Some(val) => val == "on",
None => false,
} {
"default-src 'none'; font-src 'self'; script-src 'self' blob:; manifest-src 'self'; media-src 'self' i.redd.it v.redd.it data: blob: about:; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' i.redd.it data:; form-action 'self'; frame-ancestors 'none'; connect-src 'self' v.redd.it; worker-src blob:;"
}
else {
"default-src 'none'; font-src 'self'; script-src 'self' blob:; manifest-src 'self'; media-src 'self' data: blob: about:; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none'; connect-src 'self'; worker-src blob:;"
}
}; };
if let Some(expire_time) = hsts { if let Some(expire_time) = hsts {

View file

@ -1060,8 +1060,28 @@ pub fn format_url(url: &str) -> String {
"old.reddit.com" => capture(&REGEX_URL_OLD, "/", 1), "old.reddit.com" => capture(&REGEX_URL_OLD, "/", 1),
"np.reddit.com" => capture(&REGEX_URL_NP, "/", 1), "np.reddit.com" => capture(&REGEX_URL_NP, "/", 1),
"reddit.com" => capture(&REGEX_URL_PLAIN, "/", 1), "reddit.com" => capture(&REGEX_URL_PLAIN, "/", 1),
"v.redd.it" => chain!(capture(&REGEX_URL_VIDEOS, "/vid/", 2), capture(&REGEX_URL_VIDEOS_HLS, "/hls/", 2)), "v.redd.it" => {
"i.redd.it" => capture(&REGEX_URL_IMAGES, "/img/", 1), if match config::get_setting("REDLIB_TAINTED_MEDIA") {
Some(val) => val == "on",
None => false,
} {
url.to_string()
}
else {
chain!(capture(&REGEX_URL_VIDEOS, "/vid/", 2), capture(&REGEX_URL_VIDEOS_HLS, "/hls/", 2))
}
},
"i.redd.it" => {
if match config::get_setting("REDLIB_TAINTED_MEDIA") {
Some(val) => val == "on",
None => false,
} {
url.to_string()
}
else {
capture(&REGEX_URL_IMAGES, "/img/", 1)
}
},
"a.thumbs.redditmedia.com" => capture(&REGEX_URL_THUMBS_A, "/thumb/a/", 1), "a.thumbs.redditmedia.com" => capture(&REGEX_URL_THUMBS_A, "/thumb/a/", 1),
"b.thumbs.redditmedia.com" => capture(&REGEX_URL_THUMBS_B, "/thumb/b/", 1), "b.thumbs.redditmedia.com" => capture(&REGEX_URL_THUMBS_B, "/thumb/b/", 1),
"emoji.redditmedia.com" => capture(&REGEX_URL_EMOJI, "/emoji/", 2), "emoji.redditmedia.com" => capture(&REGEX_URL_EMOJI, "/emoji/", 2),