diff options
-rw-r--r-- | src/login.rs | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/login.rs b/src/login.rs index e105bcc..646c832 100644 --- a/src/login.rs +++ b/src/login.rs @@ -1,11 +1,12 @@ -use std::borrow::Cow; +use std::{borrow::Cow, str::FromStr}; use futures_util::FutureExt; use axum::{extract::{FromRef, Host, Query, State}, http::HeaderValue, response::IntoResponse, Form}; -use axum_extra::extract::{cookie::{self, Cookie}, SignedCookieJar}; +use axum_extra::{extract::{cookie::{self, Cookie}, SignedCookieJar}, headers::HeaderMapExt, TypedHeader}; use hyper::{header::{CACHE_CONTROL, LOCATION}, StatusCode}; use kittybox_frontend_renderer::{Template, LoginPage, LogoutPage}; use kittybox_indieauth::{AuthorizationResponse, Error, GrantType, PKCEVerifier, Scope, Scopes}; +use sha2::Digest; use crate::database::Storage; @@ -321,7 +322,24 @@ async fn client_metadata<S: Storage + Send + Sync + 'static>( State(storage): State<S>, // XXX: blocked on https://github.com/hyperium/headers/pull/162 //TypedHeader(accept): TypedHeader<axum_extra::headers::Accept> + cached: Option<TypedHeader<axum_extra::headers::IfNoneMatch>>, ) -> axum::response::Response { + let etag = { + let mut digest = sha2::Sha256::new(); + digest.update(env!("CARGO_PKG_NAME").as_bytes()); + digest.update(b" "); + digest.update(env!("CARGO_PKG_VERSION").as_bytes()); + digest.update(b" "); + digest.update(crate::OAUTH2_SOFTWARE_ID.as_bytes()); + + let etag = String::from("W/") + &hex::encode(digest.finalize()); + axum_extra::headers::ETag::from_str(&etag).unwrap() + }; + if let Some(cached) = cached { + if cached.precondition_passes(&etag) { + return StatusCode::NOT_MODIFIED.into_response() + } + } let client_uri: url::Url = format!("https://{}/", host).parse().unwrap(); let client_id: url::Url = { let mut url = client_uri.clone(); @@ -345,6 +363,9 @@ async fn client_metadata<S: Storage + Send + Sync + 'static>( let mut response = metadata.into_response(); // Indicate to upstream caches this endpoint does different things depending on the Accept: header. response.headers_mut().append("Vary", HeaderValue::from_static("Accept")); + // Cache this metadata for an hour. + response.headers_mut().append("Cache-Control", HeaderValue::from_static("max-age=600")); + response.headers_mut().typed_insert(etag); response } |