Skip to content

Commit

Permalink
Move into subfolders
Browse files Browse the repository at this point in the history
  • Loading branch information
Nutomic committed Dec 12, 2024
1 parent 56ab67f commit 05843fb
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 69 deletions.
68 changes: 7 additions & 61 deletions crates/routes/src/images.rs → crates/routes/src/images/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ use actix_web::{
body::{BodyStream, BoxBody},
http::{
header::{HeaderName, ACCEPT_ENCODING, HOST},
Method,
StatusCode,
},
web::*,
HttpRequest,
HttpResponse,
Responder,
};
use futures::stream::{Stream, StreamExt};
use http::HeaderValue;
use lemmy_api_common::{context::LemmyContext, request::PictrsResponse};
use lemmy_db_schema::source::{
images::{LocalImage, LocalImageForm, RemoteImage},
Expand All @@ -24,6 +21,9 @@ use reqwest_middleware::RequestBuilder;
use serde::Deserialize;
use std::time::Duration;
use url::Url;
use utils::{convert_header, convert_method, convert_status, make_send};

mod utils;

trait ProcessUrl {
/// If thumbnail or format is given, this uses the pictrs process endpoint.
Expand Down Expand Up @@ -223,7 +223,10 @@ pub async fn delete_image(
Ok(HttpResponse::build(convert_status(res.status())).body(BodyStream::new(res.bytes_stream())))
}

pub async fn pictrs_healthz(req: HttpRequest, context: Data<LemmyContext>) -> LemmyResult<HttpResponse> {
pub async fn pictrs_healthz(
req: HttpRequest,
context: Data<LemmyContext>,
) -> LemmyResult<HttpResponse> {
let pictrs_config = context.settings().pictrs_config()?;
let url = format!("{}healthz", pictrs_config.url);

Expand Down Expand Up @@ -264,60 +267,3 @@ pub async fn image_proxy(
Ok(Either::Right(image(processed_url, req, &context).await?))
}
}

fn make_send<S>(mut stream: S) -> impl Stream<Item = S::Item> + Send + Unpin + 'static
where
S: Stream + Unpin + 'static,
S::Item: Send,
{
// NOTE: the 8 here is arbitrary
let (tx, rx) = tokio::sync::mpsc::channel(8);

// NOTE: spawning stream into a new task can potentially hit this bug:
// - https://github.com/actix/actix-web/issues/1679
//
// Since 4.0.0-beta.2 this issue is incredibly less frequent. I have not personally reproduced it.
// That said, it is still technically possible to encounter.
actix_web::rt::spawn(async move {
while let Some(res) = stream.next().await {
if tx.send(res).await.is_err() {
break;
}
}
});

SendStream { rx }
}

struct SendStream<T> {
rx: tokio::sync::mpsc::Receiver<T>,
}

impl<T> Stream for SendStream<T>
where
T: Send,
{
type Item = T;

fn poll_next(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
std::pin::Pin::new(&mut self.rx).poll_recv(cx)
}
}

// TODO: remove these conversions after actix-web upgrades to http 1.0
#[allow(clippy::expect_used)]
fn convert_status(status: http::StatusCode) -> StatusCode {
StatusCode::from_u16(status.as_u16()).expect("status can be converted")
}

#[allow(clippy::expect_used)]
fn convert_method(method: &Method) -> http::Method {
http::Method::from_bytes(method.as_str().as_bytes()).expect("method can be converted")
}

fn convert_header<'a>(name: &'a http::HeaderName, value: &'a HeaderValue) -> (&'a str, &'a [u8]) {
(name.as_str(), value.as_bytes())
}
63 changes: 63 additions & 0 deletions crates/routes/src/images/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use actix_web::http::{Method, StatusCode};
use futures::stream::{Stream, StreamExt};
use http::HeaderValue;

pub(super) fn make_send<S>(mut stream: S) -> impl Stream<Item = S::Item> + Send + Unpin + 'static
where
S: Stream + Unpin + 'static,
S::Item: Send,
{
// NOTE: the 8 here is arbitrary
let (tx, rx) = tokio::sync::mpsc::channel(8);

// NOTE: spawning stream into a new task can potentially hit this bug:
// - https://github.com/actix/actix-web/issues/1679
//
// Since 4.0.0-beta.2 this issue is incredibly less frequent. I have not personally reproduced it.
// That said, it is still technically possible to encounter.
actix_web::rt::spawn(async move {
while let Some(res) = stream.next().await {
if tx.send(res).await.is_err() {
break;
}
}
});

SendStream { rx }
}

pub(super) struct SendStream<T> {
rx: tokio::sync::mpsc::Receiver<T>,
}

impl<T> Stream for SendStream<T>
where
T: Send,
{
type Item = T;

fn poll_next(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
std::pin::Pin::new(&mut self.rx).poll_recv(cx)
}
}

// TODO: remove these conversions after actix-web upgrades to http 1.0
#[allow(clippy::expect_used)]
pub(super) fn convert_status(status: http::StatusCode) -> StatusCode {
StatusCode::from_u16(status.as_u16()).expect("status can be converted")
}

#[allow(clippy::expect_used)]
pub(super) fn convert_method(method: &Method) -> http::Method {
http::Method::from_bytes(method.as_str().as_bytes()).expect("method can be converted")
}

pub(super) fn convert_header<'a>(
name: &'a http::HeaderName,
value: &'a HeaderValue,
) -> (&'a str, &'a [u8]) {
(name.as_str(), value.as_bytes())
}
12 changes: 6 additions & 6 deletions crates/utils/src/utils/markdown/image_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn markdown_rewrite_image_links(mut src: String) -> (String, Vec<Url>) {
// If link points to remote domain, replace with proxied link
if parsed.domain() != Some(&SETTINGS.hostname) {
let mut proxied = format!(
"{}/api/v4/image_proxy?url={}",
"{}/api/v4/image/proxy?url={}",
SETTINGS.get_protocol_and_hostname(),
encode(url),
);
Expand Down Expand Up @@ -115,7 +115,7 @@ mod tests {
(
"remote image proxied",
"![link](http://example.com/image.jpg)",
"![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)",
"![link](https://lemmy-alpha/api/v4/image/proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)",
),
(
"local image unproxied",
Expand All @@ -125,7 +125,7 @@ mod tests {
(
"multiple image links",
"![link](http://example.com/image1.jpg) ![link](http://example.com/image2.jpg)",
"![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage1.jpg) ![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage2.jpg)",
"![link](https://lemmy-alpha/api/v4/image/proxy?url=http%3A%2F%2Fexample.com%2Fimage1.jpg) ![link](https://lemmy-alpha/api/v4/image/proxy?url=http%3A%2F%2Fexample.com%2Fimage2.jpg)",
),
(
"empty link handled",
Expand All @@ -135,7 +135,7 @@ mod tests {
(
"empty label handled",
"![](http://example.com/image.jpg)",
"![](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
"![](https://lemmy-alpha/api/v4/image/proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
),
(
"invalid image link removed",
Expand All @@ -145,12 +145,12 @@ mod tests {
(
"label with nested markdown handled",
"![a *b* c](http://example.com/image.jpg)",
"![a *b* c](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
"![a *b* c](https://lemmy-alpha/api/v4/image/proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
),
(
"custom emoji support",
r#"![party-blob](https://www.hexbear.net/pictrs/image/83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#,
r#"![party-blob](https://lemmy-alpha/api/v4/image_proxy?url=https%3A%2F%2Fwww.hexbear.net%2Fpictrs%2Fimage%2F83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#
r#"![party-blob](https://lemmy-alpha/api/v4/image/proxy?url=https%3A%2F%2Fwww.hexbear.net%2Fpictrs%2Fimage%2F83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#
)
];

Expand Down
2 changes: 1 addition & 1 deletion src/api_routes_v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ use lemmy_utils::rate_limit::RateLimitCell;

// Deprecated, use api v4 instead.
// When removing api v3, we also need to rewrite all links in database with
// `/api/v3/image_proxy` to use `/api/v4/image_proxy` instead.
// `/api/v3/image_proxy` to use `/api/v4/image/proxy` instead.
pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
cfg
.service(
Expand Down
2 changes: 1 addition & 1 deletion src/api_routes_v4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
cfg.service(
scope("/api/v4")
.wrap(rate_limit.message())
.route("/image_proxy", get().to(image_proxy))
// Site
.service(
scope("/site")
Expand Down Expand Up @@ -401,6 +400,7 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
.wrap(rate_limit.image())
.route(post().to(upload_image)),
)
.route("/proxy", get().to(image_proxy))
.route("/{filename}", get().to(get_full_res_image))
.route("{token}/{filename}", delete().to(delete_image))
.route("/healthz", get().to(pictrs_healthz)),
Expand Down

0 comments on commit 05843fb

Please sign in to comment.