index : static-web-server.git

ascending towards madness

author Jose Quintana <joseluisquintana20@gmail.com> 2021-08-10 21:23:31.0 +00:00:00
committer Jose Quintana <joseluisquintana20@gmail.com> 2021-08-11 6:57:21.0 +00:00:00
commit
c7e8ec92bda0f8328bfee68eca6833617122b823 [patch]
tree
d229c3c02674ea4347d69c9f7f37aa69a8cf9617
parent
2459ec418b6bc89c8e98904805badee4948ec80d
download
c7e8ec92bda0f8328bfee68eca6833617122b823.tar.gz

tests: static files cases



Diff

 src/static_files.rs   |  17 +--
 tests/static_files.rs | 544 +++++++++++++++++++++++++++++++++++----------------
 2 files changed, 389 insertions(+), 172 deletions(-)

diff --git a/src/static_files.rs b/src/static_files.rs
index c1e4a7a..f1f4b9e 100644
--- a/src/static_files.rs
+++ b/src/static_files.rs
@@ -498,22 +498,21 @@ fn bytes_range(range: Option<Range>, max_len: u64) -> Result<(u64, u64), BadRang
        return Ok((0, max_len));
    };

    let ret = range
    let res = range
        .iter()
        .map(|(start, end)| {
            let (start, end) = match (start, end) {
                (Bound::Unbounded, Bound::Unbounded) => (0, max_len),
                (Bound::Included(a), Bound::Included(b)) => {
                    // For the special case where e == the file size
                    let e = if b == max_len { b } else { b + 1 };
                    (a, e)
                    // For the special case where b == the file size
                    (a, if b == max_len { b } else { b + 1 })
                }
                (Bound::Included(s), Bound::Unbounded) => (s, max_len),
                (Bound::Unbounded, Bound::Included(e)) => {
                    if e > max_len {
                (Bound::Included(a), Bound::Unbounded) => (a, max_len),
                (Bound::Unbounded, Bound::Included(b)) => {
                    if b > max_len {
                        return Err(BadRange);
                    }
                    (max_len - e, max_len)
                    (max_len - b, max_len)
                }
                _ => unreachable!(),
            };
@@ -527,7 +526,7 @@ fn bytes_range(range: Option<Range>, max_len: u64) -> Result<(u64, u64), BadRang
        })
        .next()
        .unwrap_or(Ok((0, max_len)));
    ret
    res
}

fn file_stream(
diff --git a/tests/static_files.rs b/tests/static_files.rs
index aa93c1b..77167dc 100644
--- a/tests/static_files.rs
+++ b/tests/static_files.rs
@@ -46,7 +46,7 @@ mod tests {

        let body = hyper::body::to_bytes(res.body_mut())
            .await
            .expect("unexpected bytes error during `body` convertion");
            .expect("unexpected bytes error during `body` conversion");

        assert_eq!(body, buf);
    }
@@ -82,27 +82,225 @@ mod tests {

        let body = hyper::body::to_bytes(res.body_mut())
            .await
            .expect("unexpected bytes error during `body` convertion");
            .expect("unexpected bytes error during `body` conversion");

        assert_eq!(body, buf);
    }

    #[tokio::test]
    async fn handle_file_not_found() {
        match static_files::handle(
            &Method::GET,
            &HeaderMap::new(),
            root_dir(),
            "xyz.html",
            false,
        )
        .await
        {
            Ok(_) => {
                panic!("expected a status error 404 but not status 200")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &HeaderMap::new(), root_dir(), "xyz.html", false)
                .await
            {
                Ok(_) => {
                    panic!("expected a status error 404 but not status 200")
                }
                Err(status) => {
                    assert_eq!(status, StatusCode::NOT_FOUND);
                }
            }
        }
    }

    #[tokio::test]
    async fn handle_append_index_on_dir() {
        let buf = fs::read(root_dir().join("index.html"))
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        for method in [Method::HEAD, Method::GET] {
            for uri in ["", "/"] {
                match static_files::handle(&method, &HeaderMap::new(), root_dir(), uri, false).await
                {
                    Ok(res) => {
                        assert_eq!(res.status(), 200);
                        assert_eq!(res.headers()["content-length"], buf.len().to_string());
                    }
                    Err(_) => {
                        panic!("expected a status 200 but not a status error")
                    }
                }
            }
        }
    }

    #[tokio::test]
    async fn handle_file_encoded() {
        let buf = fs::read(root_dir().join("index.html"))
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(
                &method,
                &HeaderMap::new(),
                root_dir(),
                "/index%2ehtml",
                false,
            )
            .await
            {
                Ok(res) => {
                    assert_eq!(res.status(), 200);
                    assert_eq!(res.headers()["content-length"], buf.len().to_string());
                }
                Err(_) => {
                    panic!("expected a status 200 but not a status error")
                }
            }
        }
    }

    #[tokio::test]
    async fn handle_bad_encoded_path() {
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(
                &method,
                &HeaderMap::new(),
                root_dir(),
                "/%2E%2e.html",
                false,
            )
            .await
            {
                Ok(_) => {
                    panic!("expected a status 200 but not a status error")
                }
                Err(status) => {
                    assert_eq!(status, 404);
                }
            }
        }
    }

    #[tokio::test]
    async fn handle_not_modified() {
        let buf = fs::read(root_dir().join("index.html"))
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        for method in [Method::HEAD, Method::GET] {
            let res1 = match static_files::handle(
                &method,
                &HeaderMap::new(),
                root_dir(),
                "index.html",
                false,
            )
            .await
            {
                Ok(res) => {
                    assert_eq!(res.status(), 200);
                    assert_eq!(res.headers()["content-length"], buf.len().to_string());
                    res
                }
                Err(_) => {
                    panic!("expected a status 200 but not a status error")
                }
            };

            // if-modified-since
            let mut headers = HeaderMap::new();
            headers.insert(
                "if-modified-since",
                res1.headers()["last-modified"].to_owned(),
            );

            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 304);
                    assert_eq!(res.headers().get("content-length"), None);
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, "");
                }
                Err(_) => {
                    panic!("expected a status 304 but not a status error")
                }
            }

            // clearly too old
            let mut headers = HeaderMap::new();
            headers.insert(
                "if-modified-since",
                "Mon, 18 Nov 1974 00:00:00 GMT".parse().unwrap(),
            );

            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 200);
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, buf);
                    assert_eq!(res1.headers()["content-length"], buf.len().to_string());
                }
                Err(_) => {
                    panic!("expected a status 200 but not a status error")
                }
            }
        }
    }

    #[tokio::test]
    async fn handle_precondition() {
        for method in [Method::HEAD, Method::GET] {
            let res1 = match static_files::handle(
                &method,
                &HeaderMap::new(),
                root_dir(),
                "index.html",
                false,
            )
            .await
            {
                Ok(res) => {
                    assert_eq!(res.status(), 200);
                    res
                }
                Err(_) => {
                    panic!("expected a status 200 but not a status error")
                }
            };

            // if-unmodified-since
            let mut headers = HeaderMap::new();
            headers.insert(
                "if-unmodified-since",
                res1.headers()["last-modified"].to_owned(),
            );

            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(res) => {
                    assert_eq!(res.status(), 200);
                }
                Err(_) => {
                    panic!("expected a status 200 but not a status error")
                }
            }
            Err(status) => {
                assert_eq!(status, StatusCode::NOT_FOUND);

            // clearly too old
            let mut headers = HeaderMap::new();
            headers.insert(
                "if-unmodified-since",
                "Mon, 18 Nov 1974 00:00:00 GMT".parse().unwrap(),
            );

            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 412);

                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");

                    assert_eq!(body, "");
                }
                Err(_) => {
                    panic!("expected a status 200 but not a status error")
                }
            }
        }
    }
@@ -146,7 +344,7 @@ mod tests {

                        let body = hyper::body::to_bytes(res.body_mut())
                            .await
                            .expect("unexpected bytes error during `body` convertion");
                            .expect("unexpected bytes error during `body` conversion");

                        assert_eq!(body, buf);
                    }
@@ -219,21 +417,23 @@ mod tests {
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 206);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes 100-200/{}", buf.len())
                );
                assert_eq!(res.headers()["content-length"], "101");
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, &buf[100..=200]);
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 206);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes 100-200/{}", buf.len())
                    );
                    assert_eq!(res.headers()["content-length"], "101");
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, &buf[100..=200]);
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -247,21 +447,23 @@ mod tests {
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 416);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes */{}", buf.len())
                );
                assert_eq!(res.headers().get("content-length"), None);
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, "");
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 416);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes */{}", buf.len())
                    );
                    assert_eq!(res.headers().get("content-length"), None);
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, "");
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -276,14 +478,16 @@ mod tests {
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(res) => {
                assert_eq!(res.status(), 200);
                assert_eq!(res.headers()["content-length"], buf.len().to_string());
                assert_eq!(res.headers().get("content-range"), None);
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(res) => {
                    assert_eq!(res.status(), 200);
                    assert_eq!(res.headers()["content-length"], buf.len().to_string());
                    assert_eq!(res.headers().get("content-range"), None);
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -297,24 +501,26 @@ mod tests {
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 206);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes 100-{}/{}", buf.len() - 1, buf.len())
                );
                assert_eq!(
                    res.headers()["content-length"],
                    &buf[100..].len().to_string()
                );
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, &buf[100..]);
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 206);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes 100-{}/{}", buf.len() - 1, buf.len())
                    );
                    assert_eq!(
                        res.headers()["content-length"],
                        &buf[100..].len().to_string()
                    );
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, &buf[100..]);
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -328,21 +534,23 @@ mod tests {
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 206);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes {}-{}/{}", buf.len() - 100, buf.len() - 1, buf.len())
                );
                assert_eq!(res.headers()["content-length"], "100");
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, &buf[buf.len() - 100..]);
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 206);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes {}-{}/{}", buf.len() - 100, buf.len() - 1, buf.len())
                    );
                    assert_eq!(res.headers()["content-length"], "100");
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, &buf[buf.len() - 100..]);
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -356,21 +564,23 @@ mod tests {
            .expect("unexpected error during index.html reading");
        let buf = Bytes::from(buf);

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 416);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes */{}", buf.len())
                );
                assert_eq!(res.headers().get("content-length"), None);
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, "");
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 416);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes */{}", buf.len())
                    );
                    assert_eq!(res.headers().get("content-length"), None);
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, "");
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -387,21 +597,23 @@ mod tests {
            format!("bytes=-{}", buf.len() + 1).parse().unwrap(),
        );

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 416);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes */{}", buf.len())
                );
                assert_eq!(res.headers().get("content-length"), None);
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, "");
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 416);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes */{}", buf.len())
                    );
                    assert_eq!(res.headers().get("content-length"), None);
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, "");
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -416,16 +628,18 @@ mod tests {
        // Range::Unbounded for beginning and end
        headers.insert("range", "bytes=".parse().unwrap());

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 200);
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, buf);
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 200);
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, buf);
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -440,24 +654,26 @@ mod tests {
        // range including end of file (non-inclusive result)
        headers.insert("range", format!("bytes=100-{}", buf.len()).parse().unwrap());

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 206);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes 100-{}/{}", buf.len() - 1, buf.len())
                );
                assert_eq!(
                    res.headers()["content-length"],
                    format!("{}", buf.len() - 100)
                );
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, &buf[100..=buf.len() - 1]);
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 206);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes 100-{}/{}", buf.len() - 1, buf.len())
                    );
                    assert_eq!(
                        res.headers()["content-length"],
                        format!("{}", buf.len() - 100)
                    );
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, &buf[100..=buf.len() - 1]);
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }
@@ -475,24 +691,26 @@ mod tests {
            format!("bytes=100-{}", buf.len() - 1).parse().unwrap(),
        );

        match static_files::handle(&Method::GET, &headers, root_dir(), "index.html", false).await {
            Ok(mut res) => {
                assert_eq!(res.status(), 206);
                assert_eq!(
                    res.headers()["content-range"],
                    format!("bytes 100-{}/{}", buf.len() - 1, buf.len())
                );
                assert_eq!(
                    res.headers()["content-length"],
                    format!("{}", buf.len() - 100)
                );
                let body = hyper::body::to_bytes(res.body_mut())
                    .await
                    .expect("unexpected bytes error during `body` convertion");
                assert_eq!(body, &buf[100..=buf.len() - 1]);
            }
            Err(_) => {
                panic!("expected a normal response rather than a status error")
        for method in [Method::HEAD, Method::GET] {
            match static_files::handle(&method, &headers, root_dir(), "index.html", false).await {
                Ok(mut res) => {
                    assert_eq!(res.status(), 206);
                    assert_eq!(
                        res.headers()["content-range"],
                        format!("bytes 100-{}/{}", buf.len() - 1, buf.len())
                    );
                    assert_eq!(
                        res.headers()["content-length"],
                        format!("{}", buf.len() - 100)
                    );
                    let body = hyper::body::to_bytes(res.body_mut())
                        .await
                        .expect("unexpected bytes error during `body` conversion");
                    assert_eq!(body, &buf[100..=buf.len() - 1]);
                }
                Err(_) => {
                    panic!("expected a normal response rather than a status error")
                }
            }
        }
    }