From: cetra3 <cetra3@hotmail.com>
Date: Wed, 19 Jul 2023 10:09:04 +0000 (+0930)
Subject: Add http cache for webfingers (#3317)
X-Git-Url: http://these/git/%22https:/image.com/%7B%60%24%7BghostArchiveUrl%7D/%24%7Bargs.pageFn.jump%20n%7D?a=commitdiff_plain;h=1f21bdb2f920fc638b8581bb1a89af0c066e0874;p=lemmy.git

Add http cache for webfingers (#3317)

* Add http cache for webfingers

* Remove the outgoing cache middleware & adjust the cache headers directive

* Use 1h & 3day cache header

* Update routes and adjust the cache headers location

* revert apub caching

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Felix Ableitner <me@nutomic.com>
---

diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs
index a71871ab..49cdb27b 100644
--- a/crates/routes/src/feeds.rs
+++ b/crates/routes/src/feeds.rs
@@ -20,7 +20,12 @@ use lemmy_db_views_actor::{
   person_mention_view::PersonMentionQuery,
   structs::{CommentReplyView, PersonMentionView},
 };
-use lemmy_utils::{claims::Claims, error::LemmyError, utils::markdown::markdown_to_html};
+use lemmy_utils::{
+  cache_header::cache_1hour,
+  claims::Claims,
+  error::LemmyError,
+  utils::markdown::markdown_to_html,
+};
 use once_cell::sync::Lazy;
 use rss::{
   extension::dublincore::DublinCoreExtensionBuilder,
@@ -65,10 +70,15 @@ enum RequestType {
 }
 
 pub fn config(cfg: &mut web::ServiceConfig) {
-  cfg
-    .route("/feeds/{type}/{name}.xml", web::get().to(get_feed))
-    .route("/feeds/all.xml", web::get().to(get_all_feed))
-    .route("/feeds/local.xml", web::get().to(get_local_feed));
+  cfg.service(
+    web::scope("/feeds")
+      .route("/{type}/{name}.xml", web::get().to(get_feed))
+      .route("/all.xml", web::get().to(get_all_feed).wrap(cache_1hour()))
+      .route(
+        "/local.xml",
+        web::get().to(get_local_feed).wrap(cache_1hour()),
+      ),
+  );
 }
 
 static RSS_NAMESPACE: Lazy<BTreeMap<String, String>> = Lazy::new(|| {
diff --git a/crates/routes/src/nodeinfo.rs b/crates/routes/src/nodeinfo.rs
index ef654462..f9df9412 100644
--- a/crates/routes/src/nodeinfo.rs
+++ b/crates/routes/src/nodeinfo.rs
@@ -3,14 +3,24 @@ use anyhow::anyhow;
 use lemmy_api_common::context::LemmyContext;
 use lemmy_db_schema::RegistrationMode;
 use lemmy_db_views::structs::SiteView;
-use lemmy_utils::{error::LemmyError, version};
+use lemmy_utils::{
+  cache_header::{cache_1hour, cache_3days},
+  error::LemmyError,
+  version,
+};
 use serde::{Deserialize, Serialize};
 use url::Url;
 
 pub fn config(cfg: &mut web::ServiceConfig) {
   cfg
-    .route("/nodeinfo/2.0.json", web::get().to(node_info))
-    .route("/.well-known/nodeinfo", web::get().to(node_info_well_known));
+    .route(
+      "/nodeinfo/2.0.json",
+      web::get().to(node_info).wrap(cache_1hour()),
+    )
+    .route(
+      "/.well-known/nodeinfo",
+      web::get().to(node_info_well_known).wrap(cache_3days()),
+    );
 }
 
 async fn node_info_well_known(
diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs
index 72adc950..e3a0a561 100644
--- a/crates/routes/src/webfinger.rs
+++ b/crates/routes/src/webfinger.rs
@@ -8,7 +8,7 @@ use lemmy_db_schema::{
   source::{community::Community, person::Person},
   traits::ApubActor,
 };
-use lemmy_utils::error::LemmyError;
+use lemmy_utils::{cache_header::cache_3days, error::LemmyError};
 use serde::Deserialize;
 use std::collections::HashMap;
 use url::Url;
@@ -21,7 +21,7 @@ struct Params {
 pub fn config(cfg: &mut web::ServiceConfig) {
   cfg.route(
     ".well-known/webfinger",
-    web::get().to(get_webfinger_response),
+    web::get().to(get_webfinger_response).wrap(cache_3days()),
   );
 }
 
diff --git a/crates/utils/src/cache_header.rs b/crates/utils/src/cache_header.rs
new file mode 100644
index 00000000..042c943a
--- /dev/null
+++ b/crates/utils/src/cache_header.rs
@@ -0,0 +1,22 @@
+use actix_web::middleware::DefaultHeaders;
+
+/// Adds a cache header to requests
+///
+/// Common cache amounts are:
+///   * 1 hour = 60s * 60m = `3600` seconds
+///   * 3 days = 60s * 60m * 24h * 3d = `259200` seconds
+///
+/// Mastodon & other activitypub server defaults to 3d
+pub fn cache_header(seconds: usize) -> DefaultHeaders {
+  DefaultHeaders::new().add(("Cache-Control", format!("public, max-age={seconds}")))
+}
+
+/// Set a 1 hour cache time
+pub fn cache_1hour() -> DefaultHeaders {
+  cache_header(3600)
+}
+
+/// Set a 3 day cache time
+pub fn cache_3days() -> DefaultHeaders {
+  cache_header(259200)
+}
diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs
index 9ca427cf..1ef8a842 100644
--- a/crates/utils/src/lib.rs
+++ b/crates/utils/src/lib.rs
@@ -4,6 +4,7 @@ extern crate strum_macros;
 extern crate smart_default;
 
 pub mod apub;
+pub mod cache_header;
 pub mod email;
 pub mod rate_limit;
 pub mod settings;