Repository: seanmonstar/warp (language: 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
```


Discussion / hints:
Ya I think this is assuming a slash, which will fail when receiving a URI in authority-form.

Fix patch:
diff --git a/src/route.rs b/src/route.rs
index 8eed7d79f..cceb2581f 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 738ec06d6..0ecaf7be2 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 14e1a10da..3d5662cad 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]