Repository: seanmonstar/warp (rust)

Issue:
Panic on invalid path
Hello,
I'm building a service and I'm using warp to for the http stack and at some point I had a malformed request and warp just panicked instead of returning an error for me to handle somehow...

The malformed request was
```
GET foo.txt HTTP/1.1


```
as you can see there's a missing slash at the start of the path, if I add it everything works fine...

This is the warp server code:
```
let warp = warp::get().and(warp::fs::dir(path)).with(warp::log::log("static webserver");
warp::serve(webserver).run(ADDR).await;
```

Backtrace [here](http://ix.io/2ll6).
This is the line just before the panic:
```
15: warp::filters::path::path_and_query
             at /home/karrq/.cargo/registry/src/github.com-1ecc6299db9ec823/warp-0.2.2/src/filters/path.rs:465
```

Pull request description:
Fix #568
This is difficult to reproduce, the provided code snippet in the issue did not run (mismatched parens etc)

The full code snippet that I believe the issue author was trying to provide would look more like:

```
use warp::Filter;

#[tokio::main]
async fn main() {
    let static_server = warp::get()
        .and(warp::fs::dir("files"))
        .with(warp::log::log("static webserver"));
    warp::serve(static_server).run(([0, 0, 0, 0], 3030)).await;
}
```

However, it's unclear how to send a malformed request like the one they were referencing, precisely _because_ it is malformed.

Instead I added a breaking test that I think mimics that malformed request, and then added code to fix it.

Patch:
diff --git a/src/route.rs b/src/route.rs
index 8eed7d7..cceb258 100644
--- a/src/route.rs
+++ b/src/route.rs
@@ -95,14 +95,14 @@ impl Route {
 
     pub(crate) fn set_unmatched_path(&mut self, index: usize) {
         let index = self.segments_index + index;
-
         let path = self.req.uri().path();
-
-        if path.len() == index {
+        if path.is_empty() {
+            // malformed path
+            return;
+        } else if path.len() == index {
             self.segments_index = index;
         } else {
             debug_assert_eq!(path.as_bytes()[index], b'/');
-
             self.segments_index = index + 1;
         }
     }


Test patch:
diff --git a/tests/fs.rs b/tests/fs.rs
index 738ec06..0ecaf7b 100644
--- a/tests/fs.rs
+++ b/tests/fs.rs
@@ -43,6 +43,9 @@ async fn dir() {
     assert_eq!(res.headers()["accept-ranges"], "bytes");
 
     assert_eq!(res.body(), &*contents);
+
+    let malformed_req = warp::test::request().path("todos.rs");
+    assert_eq!(malformed_req.reply(&file).await.status(), 404);
 }
 
 #[tokio::test]
diff --git a/tests/path.rs b/tests/path.rs
index 14e1a10..3d5662c 100644
--- a/tests/path.rs
+++ b/tests/path.rs
@@ -151,6 +151,13 @@ async fn tail() {
 
     let m = tail.and(warp::path::end());
     assert!(warp::test::request().path("/foo/bar").matches(&m).await);
+
+    let ex = warp::test::request()
+        .path("localhost")
+        .filter(&tail)
+        .await
+        .unwrap();
+    assert_eq!(ex.as_str(), "/");
 }
 
 #[tokio::test]