#static-file #file-server #static #hyper #file #serve-static

hyper-static

A static file handler for Rust/Hyper with minimal logic

8 releases

0.2.1 Dec 30, 2023
0.2.0 Dec 30, 2023
0.1.6 Oct 30, 2022
0.1.4 Apr 24, 2022

#332 in HTTP server

Download history 9/week @ 2023-12-28 23/week @ 2024-02-15 25/week @ 2024-02-22 22/week @ 2024-02-29 41/week @ 2024-03-07 26/week @ 2024-03-14 8/week @ 2024-03-21 19/week @ 2024-03-28 15/week @ 2024-04-04

72 downloads per month
Used in 2 crates

MIT license

18KB
423 lines

hyper-static - a static file handler for Rust/Hyper with minimal logic

The idea is to have a static file handler with no overhead. Make any handler function for Hyper, with own logic, if a static file needs to be returned - give the crate a path and that is it.

For Hyper 0.14 use the crate version 0.1.x.

  • serves large files with zero-copy buffers
  • correctly handles partial requests (Content-Range)
  • handles If-Modified-Since, If-None-Match
  • crate errors can be transformed directly into Hyper results

Example:

use hyper_static::{serve::static_file, Streamed};

async fn handler(req: Request<Incoming>) -> Result<Streamed, http::Error> {
    // ....
    // serve a file when necessary
    // in a simple way
    let mut path = std::path::Path::new("/path/to/files").to_owned();
    path.push(&req.uri().path()[1..]);
    return match static_file(
        &path,
        Some("application/octet-stream"), // mime type
        req.headers(),                    // hyper request header map
        65536,                            // buffer size
    )
    .await
    {
        Ok(v) => v,         // return it
        Err(e) => e.into(), // transform the error and return
    };
    //more complicated - analyze errors, e.g. log them
    match static_file(
        &path,
        Some("application/octet-stream"),
        req.headers(),
        65536,
    )
    .await
    {
        Ok(v) => {
            println!(
                r#""GET {}" {}"#,
                req.uri(),
                v.as_ref().map_or(0, |res| res.status().as_u16())
            );
            v
        }
        Err(e) => {
            let resp: Result<Streamed, http::Error> = e.into();
            eprintln!(
                r#""GET {}" {}"#,
                req.uri(),
                resp.as_ref().map_or(0, |res| res.status().as_u16())
            );
            resp
        }
    }
}

Dependencies

~6–8.5MB
~146K SLoC