diff --git a/site/public/robots.txt b/site/public/robots.txt new file mode 100644 index 00000000..df4a6efe --- /dev/null +++ b/site/public/robots.txt @@ -0,0 +1,5 @@ +User-agent: * +Allow: / +Disallow: /admin/ + +Sitemap: https://questlog.cc/sitemap.xml diff --git a/site/public/sitemap.xml b/site/public/sitemap.xml new file mode 100644 index 00000000..0d0848ef --- /dev/null +++ b/site/public/sitemap.xml @@ -0,0 +1,33 @@ + + + + https://questlog.cc/ + 2026-10-22 + weekly + 1.0 + + + https://questlog.cc/builder + 2026-10-22 + weekly + 0.9 + + + https://questlog.cc/wiki + 2026-10-22 + weekly + 0.8 + + + https://questlog.cc/cards + 2026-10-22 + weekly + 0.7 + + + https://questlog.cc/status + 2026-10-22 + daily + 0.3 + + diff --git a/src/server/mod.rs b/src/server/mod.rs index 03fea340..d12d136f 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -115,6 +115,8 @@ pub fn router(app: Arc>) -> Router { .route("/builder", get(|| async { static_file("builder.html", PAGE) })) .route("/status", get(|| async { static_file("status.html", PAGE) })) .route("/cards", get(|| async { static_file("cards.html", PAGE) })) + .route("/robots.txt", get(|| async { static_file("robots.txt", PAGE) })) + .route("/sitemap.xml", get(|| async { static_file("sitemap.xml", PAGE) })) .route("/admin/status", get(admin_status::)) .route("/admin/health", get(admin_health::)) // the admin page's shell is only served through its guarded address @@ -435,6 +437,12 @@ mod tests { assert_eq!(cc, if path == "/static/index.html" { ASSET } else { PAGE }, "{path}"); assert!(html && !body.is_empty()); } + for (path, ct, has) in [("/robots.txt", "text/plain; charset=utf-8", "Sitemap: https://questlog.cc/sitemap.xml"), + ("/sitemap.xml", "application/xml; charset=utf-8", "https://questlog.cc/wiki")] { + let (st, got, _, body) = raw(&format!("{base}{path}")).await; + assert_eq!((st, got.as_str()), (200, ct), "{path}"); + assert!(String::from_utf8_lossy(&body).contains(has), "{path}"); + } for bad in ["/static/missing.css", "/static/", "/static/%2e%2e/Cargo.toml", "/static/..%2fCargo.toml", "/static/../Cargo.toml"] { assert_eq!(raw(&format!("{base}{bad}")).await.0, 404, "{bad}"); } diff --git a/src/server/pages.rs b/src/server/pages.rs index a16aa1f8..62c832af 100644 --- a/src/server/pages.rs +++ b/src/server/pages.rs @@ -11,6 +11,7 @@ pub(super) fn content_type(path: &str) -> &'static str { "css" => "text/css; charset=utf-8", "js" => "text/javascript; charset=utf-8", "json" => "application/json", + "xml" => "application/xml; charset=utf-8", "txt" => "text/plain; charset=utf-8", "png" => "image/png", "webp" => "image/webp",