Repository: sigoden/dufs (Rust)

Issue:
Search not working with `--render-try-index`
First of all: thanks for this amazing little tool. I just discovered it a few minutes ago, but I already fell in love with it. Small, standalone, feature-rich aaaaand, at last, a file server with an easy upload function! Ticking all the right boxes for me! 👍  

Now for the small problem I have... 

---

**Problem**

I ran `dufs` with the following parameters:

```
$ dufs -A -p 8080 --render-try-index
```

Unfortunately, the search didn't work: whatever search term I entered, it would always just show the current directory's index. Also, it didn't matter if the search result would be within the current folder or in some directories below it.

Out of curiosity, I tried without `--render-try-index` and now the search function does work as expected (even recursively as I had hoped 🤓 ).

It would be great if we could use `--render-try-index` together with `--allow-search`. Index pages would take precedence and would deny any further processing of URL query parameters, such as `?q=...`.  But if no index file is found, the search should just work as if the `--render-try-index` option had not been set.

**Log**

N/A

**Environment:**
 - Dufs version: 0.23.1
 - Browser/Webdav Info: Chrome/101.0.4951.67
 - OS Info: Win10 21H2



Discussion:

Patch:
diff --git a/src/server.rs b/src/server.rs
index 356c6ef3a..577cc67ee 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -155,9 +155,18 @@ impl Server {
         match method {
             Method::GET | Method::HEAD => {
                 if is_dir {
-                    if render_try_index && query == "zip" {
-                        self.handle_zip_dir(path, head_only, &mut res).await?;
-                    } else if render_index || render_spa || render_try_index {
+                    if render_try_index {
+                        if query == "zip" {
+                            self.handle_zip_dir(path, head_only, &mut res).await?;
+                        } else if allow_search && query.starts_with("q=") {
+                            let q = decode_uri(&query[2..]).unwrap_or_default();
+                            self.handle_search_dir(path, &q, head_only, &mut res)
+                                .await?;
+                        } else {
+                            self.handle_render_index(path, headers, head_only, &mut res)
+                                .await?;
+                        }
+                    } else if render_index || render_spa {
                         self.handle_render_index(path, headers, head_only, &mut res)
                             .await?;
                     } else if query == "zip" {


Test patch:
diff --git a/tests/render.rs b/tests/render.rs
index 9ecfd8e36..29644c6a0 100644
--- a/tests/render.rs
+++ b/tests/render.rs
@@ -50,6 +50,18 @@ fn render_try_index3(#[with(&["--render-try-index"])] server: TestServer) -> Res
     Ok(())
 }
 
+#[rstest]
+#[case(server(&["--render-try-index"] as &[&str]), false)]
+#[case(server(&["--render-try-index", "--allow-search"] as &[&str]), true)]
+fn render_try_index4(#[case] server: TestServer, #[case] searched: bool) -> Result<(), Error> {
+    let resp = reqwest::blocking::get(format!("{}{}?q={}", server.url(), DIR_NO_INDEX, "😀.bin"))?;
+    assert_eq!(resp.status(), 200);
+    let paths = utils::retrive_index_paths(&resp.text()?);
+    assert!(!paths.is_empty());
+    assert_eq!(paths.iter().all(|v| v.contains("😀.bin")), searched);
+    Ok(())
+}
+
 #[rstest]
 fn render_spa(#[with(&["--render-spa"])] server: TestServer) -> Result<(), Error> {
     let resp = reqwest::blocking::get(server.url())?;