Repository: thecoshman/http (language: rust)

Issue:
Thread panic upon service of files
Every time this crate serves a file, I get this:
```
[2018-12-23 01:16:27] ip was served file /home/moveax41h/static_server/index.html as text/html
[2018-12-23 01:16:27]                     found index file for directory /home/moveax41h/static_server
thread '<unnamed>' panicked at 'Failed to get file metadata: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
[2018-12-23 01:16:45] ip was served file /home/moveax41h/static_server/index.html as text/html
[2018-12-23 01:16:45]                     found index file for directory /home/moveax41h/static_server
thread '<unnamed>' panicked at 'Failed to get file metadata: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/libcore/result.rs:1009:5
```

Using nightly rust rustc 1.33.0-nightly (2d3e909e4 2018-12-22)

Server still works, but just a weird occurrence.


Discussion / hints:
Yeah, I've been eyeing the `panic!()`king issue for a long time but I've resented going back into the codebase because it'd entail rewriting a bunch of error handling which I'm not looking forward to :v

That particular one looks like it's coming across an inaccessible file during directory enumeration.

I'll try to take a look at any cases of this particular error in the next couple of days, though.

Fix patch:
diff --git a/src/ops.rs b/src/ops.rs
index 3e96e7f..0a0c679 100644
--- a/src/ops.rs
+++ b/src/ops.rs
@@ -141,25 +141,35 @@ impl HttpHandler {
 
     fn handle_get(&self, req: &mut Request) -> IronResult<Response> {
         let (req_p, symlink, url_err) = self.parse_requested_path(req);
-        let file = is_actually_file(&req_p.metadata().expect("Failed to get file metadata").file_type());
-        let range = req.headers.get().map(|r: &headers::Range| (*r).clone());
-        let raw_fs = req.headers.get().map(|r: &RawFsApiHeader| r.0).unwrap_or(false);
 
         if url_err {
-            self.handle_invalid_url(req, "<p>Percent-encoding decoded to invalid UTF-8.</p>")
-        } else if !req_p.exists() || (symlink && !self.follow_symlinks) ||
-                  (symlink && self.follow_symlinks && self.sandbox_symlinks && !is_descendant_of(&req_p, &self.hosted_directory.1)) {
-            self.handle_nonexistant(req, req_p)
-        } else if file && raw_fs {
-            self.handle_get_raw_fs_file(req, req_p)
-        } else if file && range.is_some() {
-            self.handle_get_file_range(req, req_p, range.unwrap())
-        } else if file {
-            self.handle_get_file(req, req_p)
-        } else if raw_fs {
-            self.handle_get_raw_fs_dir(req, req_p)
+            return self.handle_invalid_url(req, "<p>Percent-encoding decoded to invalid UTF-8.</p>");
+        }
+
+        if !req_p.exists()
+            || (symlink && !self.follow_symlinks)
+            || (symlink && self.follow_symlinks && self.sandbox_symlinks && !is_descendant_of(&req_p, &self.hosted_directory.1))
+        {
+            return self.handle_nonexistant(req, req_p);
+        }
+
+        let is_file = is_actually_file(&req_p.metadata().expect("Failed to get file metadata").file_type());
+        let range = req.headers.get().map(|r: &headers::Range| (*r).clone());
+        let raw_fs = req.headers.get().map(|r: &RawFsApiHeader| r.0).unwrap_or(false);
+        if is_file {
+            if raw_fs {
+                self.handle_get_raw_fs_file(req, req_p)
+            } else if range.is_some() {
+                self.handle_get_file_range(req, req_p, range.unwrap())
+            } else {
+                self.handle_get_file(req, req_p)
+            }
         } else {
-            self.handle_get_dir(req, req_p)
+            if raw_fs {
+                self.handle_get_raw_fs_dir(req, req_p)
+            } else {
+                self.handle_get_dir(req, req_p)
+            }
         }
     }
 


Test patch: