Browse Source

Add HEAD routes to avoid spurious error messages

Rocket automatically implements a HEAD route when there's a matching GET
route, but relying on this behavior also means a spurious error gets
logged due to <https://github.com/SergioBenitez/Rocket/issues/1098>.

Add explicit HEAD routes for `/` and `/alive` to prevent uptime monitoring
services from generating error messages like `No matching routes for HEAD /`.
With these new routes, `HEAD /` only checks that the server can respond over
the network, while `HEAD /alive` also checks that the database connection is
alive, similar to `GET /alive`.
Jeremy Lin 2 years ago
parent
commit
d3626eba2a
1 changed files with 21 additions and 3 deletions
  1. 21 3
      src/api/web.rs

+ 21 - 3
src/api/web.rs

@@ -4,7 +4,7 @@ use rocket::{fs::NamedFile, http::ContentType, response::content::RawHtml as Htm
 use serde_json::Value;
 
 use crate::{
-    api::{core::now, ApiResult},
+    api::{core::now, ApiResult, EmptyResult},
     error::Error,
     util::{Cached, SafeString},
     CONFIG,
@@ -14,9 +14,9 @@ pub fn routes() -> Vec<Route> {
     // If addding more routes here, consider also adding them to
     // crate::utils::LOGGED_ROUTES to make sure they appear in the log
     if CONFIG.web_vault_enabled() {
-        routes![web_index, app_id, web_files, attachments, alive, static_files]
+        routes![web_index, web_index_head, app_id, web_files, attachments, alive, alive_head, static_files]
     } else {
-        routes![attachments, alive, static_files]
+        routes![attachments, alive, alive_head, static_files]
     }
 }
 
@@ -43,6 +43,17 @@ async fn web_index() -> Cached<Option<NamedFile>> {
     Cached::short(NamedFile::open(Path::new(&CONFIG.web_vault_folder()).join("index.html")).await.ok(), false)
 }
 
+#[head("/")]
+fn web_index_head() -> EmptyResult {
+    // Add an explicit HEAD route to prevent uptime monitoring services from
+    // generating "No matching routes for HEAD /" error messages.
+    //
+    // Rocket automatically implements a HEAD route when there's a matching GET
+    // route, but relying on this behavior also means a spurious error gets
+    // logged due to <https://github.com/SergioBenitez/Rocket/issues/1098>.
+    Ok(())
+}
+
 #[get("/app-id.json")]
 fn app_id() -> Cached<(ContentType, Json<Value>)> {
     let content_type = ContentType::new("application", "fido.trusted-apps+json");
@@ -92,6 +103,13 @@ fn alive(_conn: DbConn) -> Json<String> {
     now()
 }
 
+#[head("/alive")]
+fn alive_head(_conn: DbConn) -> EmptyResult {
+    // Avoid logging spurious "No matching routes for HEAD /alive" errors
+    // due to <https://github.com/SergioBenitez/Rocket/issues/1098>.
+    Ok(())
+}
+
 #[get("/vw_static/<filename>")]
 pub fn static_files(filename: String) -> Result<(ContentType, &'static [u8]), Error> {
     match filename.as_ref() {