Add federation.onion_proxy_url configuration parameter
This commit is contained in:
parent
94a5f3a3cd
commit
50f31e96fc
7 changed files with 55 additions and 14 deletions
|
@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Support audio attachments.
|
||||
- Added CLI command for viewing unreachable actors.
|
||||
- Implemented NodeInfo 2.1.
|
||||
- Added `federation.onion_proxy_url` configuration parameter (enables proxy for requests to `.onion` domains).
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ retention:
|
|||
#federation:
|
||||
# # Proxy for outgoing requests
|
||||
# #proxy_url: 'socks5h://127.0.0.1:9050'
|
||||
# # Proxy for outgoing requests to .onion targets
|
||||
# #onion_proxy_url: 'socks5h://127.0.0.1:9050'
|
||||
|
||||
# List of blocked domains
|
||||
#blocked_instances: []
|
||||
|
|
|
@ -99,6 +99,7 @@ impl Config {
|
|||
_url: self.try_instance_url().unwrap(),
|
||||
actor_key: self.instance_rsa_key.clone().unwrap(),
|
||||
proxy_url: self.federation.proxy_url.clone(),
|
||||
onion_proxy_url: self.federation.onion_proxy_url.clone(),
|
||||
is_private: matches!(self.environment, Environment::Development),
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +132,7 @@ pub struct Instance {
|
|||
pub actor_key: RsaPrivateKey,
|
||||
// Proxy for outgoing requests
|
||||
pub proxy_url: Option<String>,
|
||||
pub onion_proxy_url: Option<String>,
|
||||
// Private instance won't send signed HTTP requests
|
||||
pub is_private: bool,
|
||||
}
|
||||
|
@ -161,6 +163,7 @@ impl Instance {
|
|||
_url: Url::parse(url).unwrap(),
|
||||
actor_key: generate_weak_rsa_key().unwrap(),
|
||||
proxy_url: None,
|
||||
onion_proxy_url: None,
|
||||
is_private: true,
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +182,7 @@ mod tests {
|
|||
_url: instance_url,
|
||||
actor_key: instance_rsa_key,
|
||||
proxy_url: None,
|
||||
onion_proxy_url: None,
|
||||
is_private: true,
|
||||
};
|
||||
|
||||
|
@ -198,6 +202,7 @@ mod tests {
|
|||
_url: instance_url,
|
||||
actor_key: instance_rsa_key,
|
||||
proxy_url: None,
|
||||
onion_proxy_url: None,
|
||||
is_private: true,
|
||||
};
|
||||
|
||||
|
|
|
@ -3,4 +3,5 @@ use serde::Deserialize;
|
|||
#[derive(Clone, Default, Deserialize)]
|
||||
pub struct FederationConfig {
|
||||
pub proxy_url: Option<String>,
|
||||
pub onion_proxy_url: Option<String>,
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@ use serde::{Deserialize, Serialize};
|
|||
use serde_json::Value;
|
||||
|
||||
use mitra_config::Instance;
|
||||
use mitra_utils::crypto_rsa::deserialize_private_key;
|
||||
use mitra_utils::{
|
||||
crypto_rsa::deserialize_private_key,
|
||||
urls::get_hostname,
|
||||
};
|
||||
|
||||
use crate::database::{
|
||||
DatabaseClient,
|
||||
|
@ -47,18 +50,28 @@ pub enum DelivererError {
|
|||
#[error("activity serialization error")]
|
||||
SerializationError(#[from] serde_json::Error),
|
||||
|
||||
#[error("inavlid URL")]
|
||||
UrlError(#[from] url::ParseError),
|
||||
|
||||
#[error(transparent)]
|
||||
RequestError(#[from] reqwest::Error),
|
||||
|
||||
#[error("http error {0:?}")]
|
||||
HttpError(reqwest::StatusCode),
|
||||
|
||||
#[error(transparent)]
|
||||
DatabaseError(#[from] DatabaseError),
|
||||
}
|
||||
|
||||
fn build_client(instance: &Instance) -> reqwest::Result<Client> {
|
||||
build_federation_client(instance, DELIVERER_TIMEOUT)
|
||||
fn build_client(
|
||||
instance: &Instance,
|
||||
request_uri: &str,
|
||||
) -> Result<Client, DelivererError> {
|
||||
let hostname = get_hostname(request_uri)?;
|
||||
let is_onion = hostname.ends_with(".onion");
|
||||
let client = build_federation_client(
|
||||
instance,
|
||||
is_onion,
|
||||
DELIVERER_TIMEOUT,
|
||||
)?;
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
async fn send_activity(
|
||||
|
@ -76,7 +89,7 @@ async fn send_activity(
|
|||
actor_key_id,
|
||||
)?;
|
||||
|
||||
let client = build_client(instance)?;
|
||||
let client = build_client(instance, inbox_url)?;
|
||||
let request = client.post(inbox_url)
|
||||
.header("Host", headers.host)
|
||||
.header("Date", headers.date)
|
||||
|
|
|
@ -6,7 +6,7 @@ use serde_json::Value;
|
|||
use mitra_config::Instance;
|
||||
use mitra_utils::{
|
||||
files::sniff_media_type,
|
||||
urls::guess_protocol,
|
||||
urls::{get_hostname, guess_protocol},
|
||||
};
|
||||
|
||||
use crate::activitypub::{
|
||||
|
@ -31,6 +31,9 @@ pub enum FetchError {
|
|||
#[error(transparent)]
|
||||
SignatureError(#[from] HttpSignatureError),
|
||||
|
||||
#[error("inavlid URL")]
|
||||
UrlError(#[from] url::ParseError),
|
||||
|
||||
#[error(transparent)]
|
||||
RequestError(#[from] reqwest::Error),
|
||||
|
||||
|
@ -50,8 +53,18 @@ pub enum FetchError {
|
|||
OtherError(&'static str),
|
||||
}
|
||||
|
||||
fn build_client(instance: &Instance) -> reqwest::Result<Client> {
|
||||
build_federation_client(instance, FETCHER_TIMEOUT)
|
||||
fn build_client(
|
||||
instance: &Instance,
|
||||
request_uri: &str,
|
||||
) -> Result<Client, FetchError> {
|
||||
let hostname = get_hostname(request_uri)?;
|
||||
let is_onion = hostname.ends_with(".onion");
|
||||
let client = build_federation_client(
|
||||
instance,
|
||||
is_onion,
|
||||
FETCHER_TIMEOUT,
|
||||
)?;
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
fn build_request(
|
||||
|
@ -75,7 +88,7 @@ async fn send_request(
|
|||
url: &str,
|
||||
query_params: &[(&str, &str)],
|
||||
) -> Result<String, FetchError> {
|
||||
let client = build_client(instance)?;
|
||||
let client = build_client(instance, url)?;
|
||||
let mut request_builder = build_request(instance, client, Method::GET, url)
|
||||
.header(reqwest::header::ACCEPT, AP_MEDIA_TYPE);
|
||||
|
||||
|
@ -113,7 +126,7 @@ pub async fn fetch_file(
|
|||
file_max_size: usize,
|
||||
output_dir: &Path,
|
||||
) -> Result<(String, usize, Option<String>), FetchError> {
|
||||
let client = build_client(instance)?;
|
||||
let client = build_client(instance, url)?;
|
||||
let request_builder =
|
||||
build_request(instance, client, Method::GET, url);
|
||||
let response = request_builder.send().await?.error_for_status()?;
|
||||
|
@ -164,7 +177,7 @@ pub async fn perform_webfinger_query(
|
|||
guess_protocol(&actor_address.hostname),
|
||||
actor_address.hostname,
|
||||
);
|
||||
let client = build_client(instance)?;
|
||||
let client = build_client(instance, &webfinger_url)?;
|
||||
let request_builder =
|
||||
build_request(instance, client, Method::GET, &webfinger_url);
|
||||
let webfinger_data = request_builder
|
||||
|
|
|
@ -9,10 +9,16 @@ const CONNECTION_TIMEOUT: u64 = 30;
|
|||
|
||||
pub fn build_federation_client(
|
||||
instance: &Instance,
|
||||
is_onion: bool,
|
||||
timeout: u64,
|
||||
) -> reqwest::Result<Client> {
|
||||
let mut client_builder = Client::builder();
|
||||
if let Some(ref proxy_url) = instance.proxy_url {
|
||||
let mut maybe_proxy_url = instance.proxy_url.as_ref();
|
||||
if is_onion {
|
||||
maybe_proxy_url = maybe_proxy_url
|
||||
.or(instance.onion_proxy_url.as_ref());
|
||||
};
|
||||
if let Some(proxy_url) = maybe_proxy_url {
|
||||
let proxy = Proxy::all(proxy_url)?;
|
||||
client_builder = client_builder.proxy(proxy);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue