]> OzVa Git service - ozva-cloud/commitdiff
feat: provide healthcheck API (#474)
authorsigoden <sigoden@gmail.com>
Sun, 27 Oct 2024 23:37:21 +0000 (07:37 +0800)
committerGitHub <noreply@github.com>
Sun, 27 Oct 2024 23:37:21 +0000 (07:37 +0800)
README.md
src/server.rs
tests/health.rs [new file with mode: 0644]

index 1456c1d9985efdcb3bb615f07f7b847bd1364617..dad7dfd4d36f8f1c9fb6dfe5487a57d501a86e02 100644 (file)
--- a/README.md
+++ b/README.md
@@ -216,8 +216,14 @@ dd skip=$upload_offset if=file status=none ibs=1 | \
   curl -X PATCH -H "X-Update-Range: append" --data-binary @- http://127.0.0.1:5000/file
 ```
 
+Health checks
+
+```sh
+curl http://127.0.0.1:5000/__dufs__/health
+```
+
 <details>
-<summary><h2>Advanced topics</h2></summary>
+<summary><h2>Advanced Topics</h2></summary>
 
 ### Access Control
 
@@ -395,6 +401,8 @@ Dufs allows users to customize the UI with your own assets.
 dufs --assets my-assets-dir/
 ```
 
+> If you only need to make slight adjustments to the current UI, you copy dufs's [assets](https://github.com/sigoden/dufs/tree/main/assets) directory and modify it accordingly. The current UI doesn't use any frameworks, just plain HTML/JS/CSS. As long as you have some basic knowledge of web development, it shouldn't be difficult to modify.
+
 Your assets folder must contains a `index.html` file.
 
 `index.html` can use the following placeholder variables to retrieve internal data.
index 3aa172da0d1d71ce8b3f55f67a4acb7a9add3357..5c404ca64fb9ae03920e5c851a6d2620523219eb 100644 (file)
@@ -62,6 +62,7 @@ const INDEX_NAME: &str = "index.html";
 const BUF_SIZE: usize = 65536;
 const EDITABLE_TEXT_MAX_SIZE: u64 = 4194304; // 4M
 const RESUMABLE_UPLOAD_MIN_SIZE: u64 = 20971520; // 20M
+const HEALTH_CHECK_PATH: &str = "__dufs__/health";
 
 pub struct Server {
     args: Args,
@@ -171,7 +172,7 @@ impl Server {
 
         if method == Method::GET
             && self
-                .handle_assets(&relative_path, headers, &mut res)
+                .handle_internal(&relative_path, headers, &mut res)
                 .await?
         {
             return Ok(res);
@@ -738,7 +739,7 @@ impl Server {
         Ok(())
     }
 
-    async fn handle_assets(
+    async fn handle_internal(
         &self,
         req_path: &str,
         headers: &HeaderMap<HeaderValue>,
@@ -789,6 +790,12 @@ impl Server {
                 HeaderValue::from_static("nosniff"),
             );
             Ok(true)
+        } else if req_path == HEALTH_CHECK_PATH {
+            res.headers_mut()
+                .typed_insert(ContentType::from(mime_guess::mime::APPLICATION_JSON));
+
+            *res.body_mut() = body_full(r#"{"status":"OK"}"#);
+            Ok(true)
         } else {
             Ok(false)
         }
diff --git a/tests/health.rs b/tests/health.rs
new file mode 100644 (file)
index 0000000..56d4f5b
--- /dev/null
@@ -0,0 +1,31 @@
+mod fixtures;
+mod utils;
+
+use fixtures::{server, Error, TestServer};
+use rstest::rstest;
+
+const HEALTH_CHECK_PATH: &str = "__dufs__/health";
+const HEALTH_CHECK_RESPONSE: &str = r#"{"status":"OK"}"#;
+
+#[rstest]
+fn normal_health(server: TestServer) -> Result<(), Error> {
+    let resp = reqwest::blocking::get(format!("{}{HEALTH_CHECK_PATH}", server.url()))?;
+    assert_eq!(resp.text()?, HEALTH_CHECK_RESPONSE);
+    Ok(())
+}
+
+#[rstest]
+fn auth_health(
+    #[with(&["--auth", "user:pass@/:rw", "-A"])] server: TestServer,
+) -> Result<(), Error> {
+    let resp = reqwest::blocking::get(format!("{}{HEALTH_CHECK_PATH}", server.url()))?;
+    assert_eq!(resp.text()?, HEALTH_CHECK_RESPONSE);
+    Ok(())
+}
+
+#[rstest]
+fn path_prefix_health(#[with(&["--path-prefix", "xyz"])] server: TestServer) -> Result<(), Error> {
+    let resp = reqwest::blocking::get(format!("{}xyz/{HEALTH_CHECK_PATH}", server.url()))?;
+    assert_eq!(resp.text()?, HEALTH_CHECK_RESPONSE);
+    Ok(())
+}