#resources #hyper #static #hyper-http #web #http

nightly build web-static-pack

Embed static resources (GUI, assets, images, styles, html) within executable. Serve with hyper or any server of your choice.

16 releases

Uses new Rust 2024

new 0.5.0 Apr 17, 2025
0.5.0-beta.3 Jan 7, 2025
0.5.0-beta.2 Jul 6, 2024
0.4.4 Nov 8, 2023
0.2.0 Dec 29, 2019

#135 in Build Utils

Download history 93/week @ 2025-01-05 13/week @ 2025-01-12 5/week @ 2025-02-02 8/week @ 2025-02-09 17/week @ 2025-02-16 3/week @ 2025-02-23 8/week @ 2025-03-09 8/week @ 2025-03-16 127/week @ 2025-04-13

127 downloads per month

MIT license

53KB
788 lines

web-static-pack

web-static-pack is the "loader" (2nd stage) part of the web-static-pack project. See project page for a general idea how two parts cooperate.

Once a pack is created with build script / CI / build.rs using web-static-pack-packer it will usually be included in your target application with https://docs.rs/include_bytes_aligned/latest/include_bytes_aligned/. Then it will be loaded with a loader::load, utilizing zero-copy deserialization (so file contents will be sent from executable contents directly). The pack is then possibly wrapped with responder::Responder http service and used with a web server like hyper.

The main part of this crate is responder::Responder. Its responder::Responder::respond_flatten method makes a [http] service - a function taking http::Request parts (method, path, headers) and returning http::Response.

To make a responder::Responder, a common::pack::Pack is needed. It can be obtained by loader::load function by passing (possibly included in binary) contents of a pack created with the packer.

Examples

Creating and calling responder

use anyhow::Error;
use include_bytes_aligned::include_bytes_aligned;
use http::{HeaderMap, Method, StatusCode};
use web_static_pack::{loader::load, responder::Responder};

// assume we have a vcard-personal-portfolio.pack available from packer examples
static PACK_ARCHIVED_SERIALIZED: &[u8] =
   include_bytes_aligned!(16, "vcard-personal-portfolio.pack");

fn main() -> Result<(), Error> {
    // load (map / cast) [common::pack::PackArchived] from included bytes
    let pack_archived = unsafe { load(PACK_ARCHIVED_SERIALIZED).unwrap() };

    // create a responder from `pack`
    let responder = Responder::new(pack_archived);

    // do some checks on the responder
    assert_eq!(
        responder.respond_flatten(
            &Method::GET,
            "/present",
            &HeaderMap::default(),
        ).status(),
        StatusCode::OK
    );

    Ok(())
}

Adapting to hyper service

This example is based on https://hyper.rs/guides/1/server/graceful-shutdown/ which is a bit complicated.

You can run full working example from tests/examples/vcard_personal_portfolio_server.rs

use anyhow::Error;
use web_static_pack::responder::Responder;
use std::{
    convert::Infallible,
    mem::transmute,
};

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Error> {
    // lets assume we have a `responder: Responder` object available from previous example
    // hyper requires service to be static
    // we use graceful, no connections will outlive server function
    let responder = unsafe {
        transmute::<
            &Responder<'_, _>,
            &Responder<'static, _>,
        >(&responder)
    };

    // make hyper service
    let service_fn = service_fn(|request| async {
        // you can probably filter your /api requests here
        let (parts, _body) = request.into_parts();

        let response = responder.respond_flatten(
            &parts.method,
            parts.uri.path(),
            &parts.headers
        );

        Ok::<_, Infallible>(response)
    });

    // use service_fn like in hyper example
    Ok(())
}

License: MIT

Dependencies

~4MB
~82K SLoC