From c3de23adb421e54db62bcd1a80a4caa201d9647a Mon Sep 17 00:00:00 2001 From: dawn Date: Tue, 22 Sep 2026 21:01:51 +0300 Subject: [PATCH] sites: well-known method/cache hygiene, write-path field validation Signed-off-by: dawn --- sites/src/lib.rs | 12 +++++++++++- sites/src/xrpc.rs | 26 +++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/sites/src/lib.rs b/sites/src/lib.rs index 25c366f6f..50700e20e 100644 --- a/sites/src/lib.rs +++ b/sites/src/lib.rs @@ -118,9 +118,19 @@ async fn fetch_inner(req: Request, env: Env, ctx: Context) -> Result { if path == "/.well-known/atproto-did" { // from the domain claim, never the site + if req.method() != Method::Get { + let mut resp = Response::error("Method Not Allowed", 405)?; + resp.headers_mut().set("Allow", "GET")?; + return Ok(resp); + } let store = SitesStore::d1(env.d1("SITES_DB")?); return match store.select_claim_by_domain(&host).await { - Ok(Some(claim)) if claim.deleted.is_none() => Response::ok(claim.did), + Ok(Some(claim)) if claim.deleted.is_none() => { + let mut resp = Response::ok(claim.did)?; + resp.headers_mut() + .set("Cache-Control", "public, max-age=300")?; + Ok(resp) + } Ok(_) => Response::error("Not Found", 404), Err(e) => { console_warn!("atproto-did claim lookup for {} failed: {}", host, e); diff --git a/sites/src/xrpc.rs b/sites/src/xrpc.rs index 3f42d1d01..28d2d5538 100644 --- a/sites/src/xrpc.rs +++ b/sites/src/xrpc.rs @@ -84,6 +84,18 @@ fn query_param(url: &Url, name: &str) -> Option { .map(|(_, v)| v.into_owned()) } +fn require_non_empty(field: &str, value: &str) -> Result { + let trimmed = value.trim(); + if trimmed.is_empty() { + return Err(XrpcError::new( + "InvalidRequest", + format!("'{}' must not be empty", field), + 400, + )); + } + Ok(trimmed.to_string()) +} + async fn verify_sd(req: &Request, env: &Env, nsid: &str) -> Result { let did = serviceauth::verify(req, env, nsid).await?; let sd = env @@ -280,10 +292,10 @@ async fn handle_update_site_config( .await .map_err(|_| XrpcError::new("InvalidRequest", "request body must be JSON", 400))?; - let branch = body.branch.trim().to_string(); - if branch.is_empty() { - return Err(XrpcError::new("InvalidRequest", "'branch' must not be empty", 400)); - } + let branch = require_non_empty("branch", &body.branch)?; + let rkey = require_non_empty("rkey", &body.rkey)?; + let name = require_non_empty("name", &body.name)?; + let knot = require_non_empty("knot", &body.knot)?; let store = store(env)?; let Some(domain) = store @@ -305,9 +317,9 @@ async fn handle_update_site_config( .update_site_config( &body.repo_did, &did, - &body.name, - &body.rkey, - &body.knot, + &name, + &rkey, + &knot, &branch, &dir, body.is_index, -- 2.51.2