index : static-web-server.git

ascending towards madness

author Eduardo M Gomes <eduardo.2001.06@gmail.com> 2022-12-02 3:45:06.0 +00:00:00
committer GitHub <noreply@github.com> 2022-12-02 3:45:06.0 +00:00:00
commit
b431c68bbc2c5a846daa30a13516fdb0cacbb91c [patch]
tree
7b3406261d13f4480a4302121516e8a40b30d746
parent
8017446d9d1099217b7d1ed451e57b2912d0cc1e
download
b431c68bbc2c5a846daa30a13516fdb0cacbb91c.tar.gz

fix: panic on compression static when base_path is a dot (#166)

for example, serving:

$ static-web-server -p 12345 --root . --compression-static true
thread 'static-web-server' panicked at 'called `Option::unwrap()` on a `None` value', src/compression_static.rs:34:53
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fish: Job 1, 'static-web-server -p 12345 --ro…' terminated by signal SIGABRT (Abort)

client support compression:
$ curl -H "accept-encoding: gzip, deflate, br" http://localhost:12345
curl: (52) Empty reply from server

Diff

 src/compression_static.rs   | 30 ++++++++++++++++--------------
 tests/compression_static.rs | 27 +++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/src/compression_static.rs b/src/compression_static.rs
index 1fd92c6..a569340 100644
--- a/src/compression_static.rs
+++ b/src/compression_static.rs
@@ -31,20 +31,22 @@ pub async fn precompressed_variant(
    // Try to find the pre-compressed metadata variant for the given file path
    if let Some(ext) = precomp_ext {
        let mut filepath_precomp = file_path;
        let filename = filepath_precomp.file_name().unwrap().to_str().unwrap();
        let precomp_file_name = [filename, ".", ext].concat();
        filepath_precomp.set_file_name(precomp_file_name);

        tracing::trace!(
            "getting metadata for pre-compressed file variant {}",
            filepath_precomp.display()
        );

        if let Ok((meta, _)) = file_metadata(&filepath_precomp) {
            tracing::trace!("pre-compressed file variant found, serving it directly");

            let encoding = if ext == "gz" { "gzip" } else { ext };
            precompressed = Some((filepath_precomp, meta, encoding));
        if let Some(filename) = filepath_precomp.file_name() {
            let filename = filename.to_str().unwrap();
            let precomp_file_name = [filename, ".", ext].concat();
            filepath_precomp.set_file_name(precomp_file_name);

            tracing::trace!(
                "getting metadata for pre-compressed file variant {}",
                filepath_precomp.display()
            );

            if let Ok((meta, _)) = file_metadata(&filepath_precomp) {
                tracing::trace!("pre-compressed file variant found, serving it directly");

                let encoding = if ext == "gz" { "gzip" } else { ext };
                precompressed = Some((filepath_precomp, meta, encoding));
            }
        }

        // Note: In error case like "no such file or dir" the workflow just continues
diff --git a/tests/compression_static.rs b/tests/compression_static.rs
index c15de60..63715ad 100644
--- a/tests/compression_static.rs
+++ b/tests/compression_static.rs
@@ -126,4 +126,31 @@ mod tests {
            "body and index_gz_buf are not equal in length"
        );
    }

    #[tokio::test]
    async fn compression_static_base_path_as_dot() {
        let mut headers = HeaderMap::new();
        headers.insert(
            http::header::ACCEPT_ENCODING,
            "gzip, deflate, br".parse().unwrap(),
        );

        let base_path = PathBuf::from(".");

        let (_resp, _) = static_files::handle(&HandleOpts {
            method: &Method::GET,
            headers: &headers,
            base_path: &base_path,
            uri_path: "/",
            uri_query: None,
            dir_listing: true,
            dir_listing_order: 6,
            dir_listing_format: &DirListFmt::Html,
            redirect_trailing_slash: true,
            compression_static: true,
            ignore_hidden_files: false,
        })
        .await
        .expect("unexpected error response on `handle` function");
    }
}