diff --git a/src/crawler.rs b/src/crawler.rs index e033f91..c362148 100644 --- a/src/crawler.rs +++ b/src/crawler.rs @@ -110,6 +110,25 @@ impl Crawler { } } + pub async fn get_redirect_urls_for_service( + &self, + alias: &str, + ) -> Result, CrawlerError> { + let guard = self.data.read().await; + let data = guard.as_ref(); + let Some(services) = data else { + return Err(CrawlerError::CrawlerNotFetchedYet)?; + }; + let Some(service) = services.get_service_by_alias(alias) else { + return Err(CrawlerError::ServiceNotFound)?; + }; + Ok(service + .get_alive_instances() + .iter() + .map(|i| i.url.clone()) + .collect()) + } + async fn crawl_single_instance( service: &Service, instance: &Url, diff --git a/src/routes/redirect.rs b/src/routes/redirect.rs index 008e4f0..cc3c8e4 100644 --- a/src/routes/redirect.rs +++ b/src/routes/redirect.rs @@ -8,6 +8,7 @@ use actix_web::{ }; use askama::Template; use thiserror::Error; +use url::Url; use crate::{ config::AppConfig, @@ -18,6 +19,7 @@ use crate::{ pub fn scope(_config: &AppConfig) -> Scope { web::scope("") .service(history_redirect) + .service(cached_redirect) .service(base_redirect) } @@ -37,7 +39,34 @@ impl_api_error!(RedirectError, ); #[derive(Template)] -#[template(path = "history_redirect.html")] +#[template(path = "cached_redirect.html", escape = "none")] +pub struct CachedRedirectTemplate { + pub urls: Vec, +} + +#[get("/cached/{service_name}")] +async fn cached_redirect( + path: web::Path, + config: web::Data, + crawler: web::Data>, +) -> actix_web::Result { + let service_name = path.into_inner(); + + let urls = crawler + .get_redirect_urls_for_service(&service_name) + .await + .map_err(RedirectError::from)?; + + let template = CachedRedirectTemplate { urls }; + + Ok(actix_web::HttpResponse::Ok() + .content_type("text/html; charset=utf-8") + .append_header(("cache-control", format!("public, max-age {}, only-if-cached, stale-while-revalidate 86400, stale-if-error 86400, immutable", config.crawler.ping_interval.as_secs()))) + .body(template.render().expect("failed to render error page"))) +} + +#[derive(Template)] +#[template(path = "history_redirect.html", escape = "none")] pub struct HistoryRedirectTemplate<'a> { pub path: &'a str, } diff --git a/templates/cached_redirect.html b/templates/cached_redirect.html new file mode 100644 index 0000000..8ef673a --- /dev/null +++ b/templates/cached_redirect.html @@ -0,0 +1,21 @@ + + Fastside Cached Redirect + + + + + Redirecting... +
    + {% for instance in urls %}
  • {{ instance }}
  • {% endfor %} +
+ \ No newline at end of file