diff --git a/src/activitypub/deliverer.rs b/src/activitypub/deliverer.rs index 9db2741..151a1c1 100644 --- a/src/activitypub/deliverer.rs +++ b/src/activitypub/deliverer.rs @@ -49,7 +49,8 @@ async fn send_activity( .header("Date", headers.date) .header("Digest", headers.digest.unwrap()) .header("Signature", headers.signature) - .header("Content-Type", ACTIVITY_CONTENT_TYPE) + .header(reqwest::header::CONTENT_TYPE, ACTIVITY_CONTENT_TYPE) + .header(reqwest::header::USER_AGENT, instance.agent()) .body(activity_json.to_owned()); if instance.is_private { diff --git a/src/activitypub/fetcher/fetchers.rs b/src/activitypub/fetcher/fetchers.rs index 816340b..85ddf6c 100644 --- a/src/activitypub/fetcher/fetchers.rs +++ b/src/activitypub/fetcher/fetchers.rs @@ -59,6 +59,11 @@ async fn send_request( .header("Date", headers.date) .header("Signature", headers.signature); }; + if !instance.is_private { + // Public instance should set User-Agent header + request_builder = request_builder + .header(reqwest::header::USER_AGENT, instance.agent()); + }; let data = request_builder .header(reqwest::header::ACCEPT, ACTIVITY_CONTENT_TYPE) @@ -106,7 +111,13 @@ pub async fn fetch_profile( // TOOD: support http let webfinger_url = format!("https://{}/.well-known/webfinger", actor_host); let client = reqwest::Client::new(); - let webfinger_data = client.get(&webfinger_url) + let mut request_builder = client.get(&webfinger_url); + if !instance.is_private { + // Public instance should set User-Agent header + request_builder = request_builder + .header(reqwest::header::USER_AGENT, instance.agent()); + }; + let webfinger_data = request_builder .query(&[("resource", webfinger_account_uri)]) .send().await? .error_for_status()? diff --git a/src/config.rs b/src/config.rs index cdd3e79..7490a5f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -144,6 +144,7 @@ impl Config { pub fn instance(&self) -> Instance { Instance { _url: self.try_instance_url().unwrap(), + _version: self.version.clone(), actor_key: self.try_instance_rsa_key().unwrap(), is_private: matches!(self.environment, Environment::Development), } @@ -160,6 +161,7 @@ impl Config { pub struct Instance { _url: Url, + _version: String, // Instance actor pub actor_key: RsaPrivateKey, // Private instance won't send signed HTTP requests @@ -183,6 +185,14 @@ impl Instance { pub fn actor_key_id(&self) -> String { format!("{}#main-key", self.actor_id()) } + + pub fn agent(&self) -> String { + format!( + "Mitra {version}; {instance_url}", + version=self._version, + instance_url=self.url(), + ) + } } pub fn parse_config() -> Config { @@ -225,12 +235,14 @@ mod tests { let instance_rsa_key = RsaPrivateKey::new(&mut OsRng, 512).unwrap(); let instance = Instance { _url: instance_url, + _version: "1.0.0".to_string(), actor_key: instance_rsa_key, is_private: true, }; assert_eq!(instance.url(), "https://example.com"); assert_eq!(instance.host(), "example.com"); + assert_eq!(instance.agent(), "Mitra 1.0.0; https://example.com"); } #[test] @@ -239,6 +251,7 @@ mod tests { let instance_rsa_key = RsaPrivateKey::new(&mut OsRng, 512).unwrap(); let instance = Instance { _url: instance_url, + _version: "1.0.0".to_string(), actor_key: instance_rsa_key, is_private: true, };