Avoid using proxy for pictrs requests (fixes #3489)

This commit is contained in:
Felix Ableitner 2023-10-20 15:07:57 +02:00
parent 6bcb12b14f
commit 9184800582
5 changed files with 38 additions and 52 deletions

View file

@ -8,6 +8,7 @@ use lemmy_utils::{
REQWEST_TIMEOUT, REQWEST_TIMEOUT,
}; };
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use reqwest::{Client, ClientBuilder};
use reqwest_middleware::ClientWithMiddleware; use reqwest_middleware::ClientWithMiddleware;
use serde::Deserialize; use serde::Deserialize;
use tracing::info; use tracing::info;
@ -288,12 +289,18 @@ async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> Resu
} }
} }
pub fn build_user_agent(settings: &Settings) -> String { pub fn client_builder(settings: &Settings) -> ClientBuilder {
format!( let user_agent =
"Lemmy/{}; +{}", format!(
VERSION, "Lemmy/{}; +{}",
settings.get_protocol_and_hostname() VERSION,
) settings.get_protocol_and_hostname()
);
Client::builder()
.user_agent(user_agent.clone())
.timeout(REQWEST_TIMEOUT)
.connect_timeout(REQWEST_TIMEOUT)
} }
#[cfg(test)] #[cfg(test)]
@ -301,12 +308,7 @@ mod tests {
#![allow(clippy::unwrap_used)] #![allow(clippy::unwrap_used)]
#![allow(clippy::indexing_slicing)] #![allow(clippy::indexing_slicing)]
use crate::request::{ use crate::request::{client_builder, fetch_site_metadata, html_to_site_metadata, SiteMetadata};
build_user_agent,
fetch_site_metadata,
html_to_site_metadata,
SiteMetadata,
};
use lemmy_utils::settings::SETTINGS; use lemmy_utils::settings::SETTINGS;
use url::Url; use url::Url;
@ -314,9 +316,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_site_metadata() { async fn test_site_metadata() {
let settings = &SETTINGS.clone(); let settings = &SETTINGS.clone();
let client = reqwest::Client::builder() let client = client_builder(settings).build()
.user_agent(build_user_agent(settings))
.build()
.unwrap() .unwrap()
.into(); .into();
let sample_url = Url::parse("https://gitlab.com/IzzyOnDroid/repo/-/wikis/FAQ").unwrap(); let sample_url = Url::parse("https://gitlab.com/IzzyOnDroid/repo/-/wikis/FAQ").unwrap();

View file

@ -59,12 +59,13 @@ pub(crate) mod tests {
use activitypub_federation::config::{Data, FederationConfig}; use activitypub_federation::config::{Data, FederationConfig};
use anyhow::anyhow; use anyhow::anyhow;
use lemmy_api_common::{context::LemmyContext, request::build_user_agent}; use lemmy_api_common::{context::LemmyContext};
use lemmy_db_schema::{source::secret::Secret, utils::build_db_pool_for_tests}; use lemmy_db_schema::{source::secret::Secret, utils::build_db_pool_for_tests};
use lemmy_utils::{rate_limit::RateLimitCell, settings::SETTINGS}; use lemmy_utils::{rate_limit::RateLimitCell, settings::SETTINGS};
use reqwest::{Client, Request, Response}; use reqwest::{Request, Response};
use reqwest_middleware::{ClientBuilder, Middleware, Next}; use reqwest_middleware::{ClientBuilder, Middleware, Next};
use task_local_extensions::Extensions; use task_local_extensions::Extensions;
use lemmy_api_common::request::client_builder;
struct BlockedMiddleware; struct BlockedMiddleware;
@ -86,9 +87,7 @@ pub(crate) mod tests {
// call this to run migrations // call this to run migrations
let pool = build_db_pool_for_tests().await; let pool = build_db_pool_for_tests().await;
let settings = SETTINGS.clone(); let client = client_builder(&SETTINGS)
let client = Client::builder()
.user_agent(build_user_agent(&settings))
.build() .build()
.unwrap(); .unwrap();

View file

@ -55,7 +55,7 @@ services:
lemmy-ui: lemmy-ui:
# use "image" to pull down an already compiled lemmy-ui. make sure to comment out "build". # use "image" to pull down an already compiled lemmy-ui. make sure to comment out "build".
image: dessalines/lemmy-ui:0.18.4 image: dessalines/lemmy-ui:0.19.0-rc.3
# platform: linux/x86_64 # no arm64 support. uncomment platform if using m1. # platform: linux/x86_64 # no arm64 support. uncomment platform if using m1.
# use "build" to build your local lemmy ui image for development. make sure to comment out "image". # use "build" to build your local lemmy ui image for development. make sure to comment out "image".
# run: docker compose up --build # run: docker compose up --build

View file

@ -45,9 +45,9 @@ if [ "$ARCH" = 'arm64' ]; then
fi fi
echo "$LOG_PREFIX Initializing images in the background. Please be patient if compiling from source..." echo "$LOG_PREFIX Initializing images in the background. Please be patient if compiling from source..."
docker compose up -d --build docker compose up --build
else else
sudo docker compose up -d --build sudo docker compose up --build
fi fi
echo "$LOG_PREFIX Complete! You can now access the UI at http://localhost:1236." echo "$LOG_PREFIX Complete! You can now access the UI at http://localhost:1236."

View file

@ -28,7 +28,6 @@ use clap::{ArgAction, Parser};
use lemmy_api_common::{ use lemmy_api_common::{
context::LemmyContext, context::LemmyContext,
lemmy_db_views::structs::SiteView, lemmy_db_views::structs::SiteView,
request::build_user_agent,
send_activity::{ActivityChannel, MATCH_OUTGOING_ACTIVITIES}, send_activity::{ActivityChannel, MATCH_OUTGOING_ACTIVITIES},
utils::{ utils::{
check_private_instance_and_federation_enabled, check_private_instance_and_federation_enabled,
@ -52,11 +51,10 @@ use lemmy_utils::{
response::jsonify_plain_text_errors, response::jsonify_plain_text_errors,
settings::{structs::Settings, SETTINGS}, settings::{structs::Settings, SETTINGS},
}; };
use reqwest::Client;
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware}; use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
use reqwest_tracing::TracingMiddleware; use reqwest_tracing::TracingMiddleware;
use serde_json::json; use serde_json::json;
use std::{env, ops::Deref, time::Duration}; use std::{env, ops::Deref};
use tokio::signal::unix::SignalKind; use tokio::signal::unix::SignalKind;
use tracing::subscriber::set_global_default; use tracing::subscriber::set_global_default;
use tracing_actix_web::TracingLogger; use tracing_actix_web::TracingLogger;
@ -70,6 +68,7 @@ use {
prometheus::default_registry, prometheus::default_registry,
prometheus_metrics::serve_prometheus, prometheus_metrics::serve_prometheus,
}; };
use lemmy_api_common::request::client_builder;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command( #[command(
@ -112,13 +111,9 @@ pub struct CmdArgs {
#[arg(long, default_value_t = 1)] #[arg(long, default_value_t = 1)]
federate_process_count: i32, federate_process_count: i32,
} }
/// Max timeout for http requests
pub(crate) const REQWEST_TIMEOUT: Duration = Duration::from_secs(10);
/// Placing the main function in lib.rs allows other crates to import it and embed Lemmy /// Placing the main function in lib.rs allows other crates to import it and embed Lemmy
pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> { pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> {
let settings = SETTINGS.to_owned();
// return error 503 while running db migrations and startup tasks // return error 503 while running db migrations and startup tasks
let mut startup_server_handle = None; let mut startup_server_handle = None;
if args.http_server { if args.http_server {
@ -126,14 +121,14 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> {
} }
// Run the DB migrations // Run the DB migrations
let db_url = get_database_url(Some(&settings)); let db_url = get_database_url(Some(&SETTINGS));
run_migrations(&db_url); run_migrations(&db_url);
// Set up the connection pool // Set up the connection pool
let pool = build_db_pool(&settings).await?; let pool = build_db_pool(&SETTINGS).await?;
// Run the Code-required migrations // Run the Code-required migrations
run_advanced_migrations(&mut (&pool).into(), &settings).await?; run_advanced_migrations(&mut (&pool).into(), &SETTINGS).await?;
// Initialize the secrets // Initialize the secrets
let secret = Secret::init(&mut (&pool).into()) let secret = Secret::init(&mut (&pool).into())
@ -148,7 +143,7 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> {
let federation_enabled = local_site.federation_enabled; let federation_enabled = local_site.federation_enabled;
if federation_enabled { if federation_enabled {
println!("federation enabled, host is {}", &settings.hostname); println!("federation enabled, host is {}", &SETTINGS.hostname);
} }
check_private_instance_and_federation_enabled(&local_site)?; check_private_instance_and_federation_enabled(&local_site)?;
@ -160,25 +155,12 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> {
println!( println!(
"Starting http server at {}:{}", "Starting http server at {}:{}",
settings.bind, settings.port SETTINGS.bind, SETTINGS.port
); );
let user_agent = build_user_agent(&settings); let client = ClientBuilder::new(client_builder(&SETTINGS).build()?)
let reqwest_client = Client::builder()
.user_agent(user_agent.clone())
.timeout(REQWEST_TIMEOUT)
.connect_timeout(REQWEST_TIMEOUT)
.build()?;
let client = ClientBuilder::new(reqwest_client.clone())
.with(TracingMiddleware::default()) .with(TracingMiddleware::default())
.build(); .build();
// Pictrs cannot use the retry middleware
let pictrs_client = ClientBuilder::new(reqwest_client.clone())
.with(TracingMiddleware::default())
.build();
let context = LemmyContext::create( let context = LemmyContext::create(
pool.clone(), pool.clone(),
client.clone(), client.clone(),
@ -192,10 +174,10 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> {
} }
#[cfg(feature = "prometheus-metrics")] #[cfg(feature = "prometheus-metrics")]
serve_prometheus(settings.prometheus.as_ref(), context.clone()); serve_prometheus(SETTINGS.prometheus.as_ref(), context.clone());
let federation_config = FederationConfig::builder() let federation_config = FederationConfig::builder()
.domain(settings.hostname.clone()) .domain(SETTINGS.hostname.clone())
.app_data(context.clone()) .app_data(context.clone())
.client(client.clone()) .client(client.clone())
.http_fetch_limit(FEDERATION_HTTP_FETCH_LIMIT) .http_fetch_limit(FEDERATION_HTTP_FETCH_LIMIT)
@ -217,9 +199,14 @@ pub async fn start_lemmy_server(args: CmdArgs) -> Result<(), LemmyError> {
if let Some(startup_server_handle) = startup_server_handle { if let Some(startup_server_handle) = startup_server_handle {
startup_server_handle.stop(true).await; startup_server_handle.stop(true).await;
} }
// Pictrs cannot use proxy
let pictrs_client = ClientBuilder::new(client_builder(&SETTINGS).no_proxy().build()?)
.with(TracingMiddleware::default())
.build();
Some(create_http_server( Some(create_http_server(
federation_config.clone(), federation_config.clone(),
settings.clone(), SETTINGS.clone(),
federation_enabled, federation_enabled,
pictrs_client, pictrs_client,
)?) )?)