Fixing proxied images for federated posts. (#4737)

* Fixing proxied images for federated posts.

- Also added test.
- Fixes #4736

* Address PR comments.
This commit is contained in:
Dessalines 2024-05-23 11:11:25 -04:00 committed by GitHub
parent b2c1a14234
commit 6a6108ac55
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 81 additions and 46 deletions

View file

@ -67,8 +67,8 @@ members = [
[workspace.lints.clippy] [workspace.lints.clippy]
cast_lossless = "deny" cast_lossless = "deny"
complexity = "deny" complexity = { level = "deny", priority = -1 }
correctness = "deny" correctness = { level = "deny", priority = -1 }
dbg_macro = "deny" dbg_macro = "deny"
explicit_into_iter_loop = "deny" explicit_into_iter_loop = "deny"
explicit_iter_loop = "deny" explicit_iter_loop = "deny"
@ -79,10 +79,10 @@ inefficient_to_string = "deny"
items-after-statements = "deny" items-after-statements = "deny"
manual_string_new = "deny" manual_string_new = "deny"
needless_collect = "deny" needless_collect = "deny"
perf = "deny" perf = { level = "deny", priority = -1 }
redundant_closure_for_method_calls = "deny" redundant_closure_for_method_calls = "deny"
style = "deny" style = { level = "deny", priority = -1 }
suspicious = "deny" suspicious = { level = "deny", priority = -1 }
uninlined_format_args = "allow" uninlined_format_args = "allow"
unused_self = "deny" unused_self = "deny"
unwrap_used = "deny" unwrap_used = "deny"

View file

@ -31,6 +31,7 @@ import {
waitUntil, waitUntil,
createPostWithThumbnail, createPostWithThumbnail,
sampleImage, sampleImage,
sampleSite,
} from "./shared"; } from "./shared";
const downloadFileSync = require("download-file-sync"); const downloadFileSync = require("download-file-sync");
@ -172,54 +173,94 @@ test("Purge post, linked image removed", async () => {
expect(content2).toBe(""); expect(content2).toBe("");
}); });
test("Images in remote post are proxied if setting enabled", async () => { test("Images in remote image post are proxied if setting enabled", async () => {
let user = await registerUser(beta, betaUrl);
let community = await createCommunity(gamma); let community = await createCommunity(gamma);
let postRes = await createPost(
const upload_form: UploadImage = {
image: Buffer.from("test"),
};
const upload = await user.uploadImage(upload_form);
let post = await createPost(
gamma, gamma,
community.community_view.community.id, community.community_view.community.id,
upload.url, sampleImage,
`![](${sampleImage})`, `![](${sampleImage})`,
); );
expect(post.post_view.post).toBeDefined(); const post = postRes.post_view.post;
expect(post).toBeDefined();
// remote image gets proxied after upload // remote image gets proxied after upload
expect( expect(
post.post_view.post.thumbnail_url?.startsWith( post.thumbnail_url?.startsWith(
"http://lemmy-gamma:8561/api/v3/image_proxy?url", "http://lemmy-gamma:8561/api/v3/image_proxy?url",
), ),
).toBeTruthy(); ).toBeTruthy();
expect( expect(
post.post_view.post.body?.startsWith( post.body?.startsWith("![](http://lemmy-gamma:8561/api/v3/image_proxy?url"),
"![](http://lemmy-gamma:8561/api/v3/image_proxy?url",
),
).toBeTruthy(); ).toBeTruthy();
let epsilonPost = await resolvePost(epsilon, post.post_view.post); // Make sure that it ends with jpg, to be sure its an image
expect(epsilonPost.post).toBeDefined(); expect(post.thumbnail_url?.endsWith(".jpg")).toBeTruthy();
let epsilonPostRes = await resolvePost(epsilon, postRes.post_view.post);
expect(epsilonPostRes.post).toBeDefined();
// Fetch the post again, the metadata should be backgrounded now // Fetch the post again, the metadata should be backgrounded now
// Wait for the metadata to get fetched, since this is backgrounded now // Wait for the metadata to get fetched, since this is backgrounded now
let epsilonPost2 = await waitUntil( let epsilonPostRes2 = await waitUntil(
() => getPost(epsilon, epsilonPost.post!.post.id), () => getPost(epsilon, epsilonPostRes.post!.post.id),
p => p.post_view.post.thumbnail_url != undefined, p => p.post_view.post.thumbnail_url != undefined,
); );
const epsilonPost = epsilonPostRes2.post_view.post;
expect( expect(
epsilonPost2.post_view.post.thumbnail_url?.startsWith( epsilonPost.thumbnail_url?.startsWith(
"http://lemmy-epsilon:8581/api/v3/image_proxy?url", "http://lemmy-epsilon:8581/api/v3/image_proxy?url",
), ),
).toBeTruthy(); ).toBeTruthy();
expect( expect(
epsilonPost2.post_view.post.body?.startsWith( epsilonPost.body?.startsWith(
"![](http://lemmy-epsilon:8581/api/v3/image_proxy?url", "![](http://lemmy-epsilon:8581/api/v3/image_proxy?url",
), ),
).toBeTruthy(); ).toBeTruthy();
// Make sure that it ends with jpg, to be sure its an image
expect(epsilonPost.thumbnail_url?.endsWith(".jpg")).toBeTruthy();
});
test("Thumbnail of remote image link is proxied if setting enabled", async () => {
let community = await createCommunity(gamma);
let postRes = await createPost(
gamma,
community.community_view.community.id,
// The sample site metadata thumbnail ends in png
sampleSite,
);
const post = postRes.post_view.post;
expect(post).toBeDefined();
// remote image gets proxied after upload
expect(
post.thumbnail_url?.startsWith(
"http://lemmy-gamma:8561/api/v3/image_proxy?url",
),
).toBeTruthy();
// Make sure that it ends with png, to be sure its an image
expect(post.thumbnail_url?.endsWith(".png")).toBeTruthy();
let epsilonPostRes = await resolvePost(epsilon, postRes.post_view.post);
expect(epsilonPostRes.post).toBeDefined();
let epsilonPostRes2 = await waitUntil(
() => getPost(epsilon, epsilonPostRes.post!.post.id),
p => p.post_view.post.thumbnail_url != undefined,
);
const epsilonPost = epsilonPostRes2.post_view.post;
expect(
epsilonPost.thumbnail_url?.startsWith(
"http://lemmy-epsilon:8581/api/v3/image_proxy?url",
),
).toBeTruthy();
// Make sure that it ends with png, to be sure its an image
expect(epsilonPost.thumbnail_url?.endsWith(".png")).toBeTruthy();
}); });
test("No image proxying if setting is disabled", async () => { test("No image proxying if setting is disabled", async () => {

View file

@ -83,21 +83,22 @@ export const fetchFunction = fetch;
export const imageFetchLimit = 50; export const imageFetchLimit = 50;
export const sampleImage = export const sampleImage =
"https://i.pinimg.com/originals/df/5f/5b/df5f5b1b174a2b4b6026cc6c8f9395c1.jpg"; "https://i.pinimg.com/originals/df/5f/5b/df5f5b1b174a2b4b6026cc6c8f9395c1.jpg";
export const sampleSite = "https://yahoo.com";
export let alphaUrl = "http://127.0.0.1:8541"; export const alphaUrl = "http://127.0.0.1:8541";
export let betaUrl = "http://127.0.0.1:8551"; export const betaUrl = "http://127.0.0.1:8551";
export let gammaUrl = "http://127.0.0.1:8561"; export const gammaUrl = "http://127.0.0.1:8561";
export let deltaUrl = "http://127.0.0.1:8571"; export const deltaUrl = "http://127.0.0.1:8571";
export let epsilonUrl = "http://127.0.0.1:8581"; export const epsilonUrl = "http://127.0.0.1:8581";
export let alpha = new LemmyHttp(alphaUrl, { fetchFunction }); export const alpha = new LemmyHttp(alphaUrl, { fetchFunction });
export let alphaImage = new LemmyHttp(alphaUrl); export const alphaImage = new LemmyHttp(alphaUrl);
export let beta = new LemmyHttp(betaUrl, { fetchFunction }); export const beta = new LemmyHttp(betaUrl, { fetchFunction });
export let gamma = new LemmyHttp(gammaUrl, { fetchFunction }); export const gamma = new LemmyHttp(gammaUrl, { fetchFunction });
export let delta = new LemmyHttp(deltaUrl, { fetchFunction }); export const delta = new LemmyHttp(deltaUrl, { fetchFunction });
export let epsilon = new LemmyHttp(epsilonUrl, { fetchFunction }); export const epsilon = new LemmyHttp(epsilonUrl, { fetchFunction });
export let betaAllowedInstances = [ export const betaAllowedInstances = [
"lemmy-alpha", "lemmy-alpha",
"lemmy-gamma", "lemmy-gamma",
"lemmy-delta", "lemmy-delta",

View file

@ -25,12 +25,7 @@ use html2text::{from_read_with_decorator, render::text_renderer::TrivialDecorato
use lemmy_api_common::{ use lemmy_api_common::{
context::LemmyContext, context::LemmyContext,
request::generate_post_link_metadata, request::generate_post_link_metadata,
utils::{ utils::{get_url_blocklist, local_site_opt_to_slur_regex, process_markdown_opt},
get_url_blocklist,
local_site_opt_to_slur_regex,
process_markdown_opt,
proxy_image_link_opt_apub,
},
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
source::{ source::{
@ -228,8 +223,6 @@ impl Object for ApubPost {
let alt_text = first_attachment.cloned().and_then(Attachment::alt_text); let alt_text = first_attachment.cloned().and_then(Attachment::alt_text);
let url = proxy_image_link_opt_apub(url, context).await?;
let slur_regex = &local_site_opt_to_slur_regex(&local_site); let slur_regex = &local_site_opt_to_slur_regex(&local_site);
let url_blocklist = get_url_blocklist(context).await?; let url_blocklist = get_url_blocklist(context).await?;

View file

@ -79,5 +79,5 @@ fn handle_error(span: Span, status_code: StatusCode, response_error: &dyn Respon
} }
}); });
span.record("exception.message", &tracing::field::display(display_error)); span.record("exception.message", tracing::field::display(display_error));
} }