{"id":21182808,"url":"https://github.com/seriousbug/actix-web-rust-embed-responder","last_synced_at":"2025-07-10T00:32:52.721Z","repository":{"id":63095035,"uuid":"552390965","full_name":"SeriousBug/actix-web-rust-embed-responder","owner":"SeriousBug","description":"An actix-web responder for rust-embed that implements cache revalidation and compressed responses.","archived":false,"fork":false,"pushed_at":"2024-06-28T01:06:13.000Z","size":1766,"stargazers_count":2,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-29T01:58:42.936Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://seriousbug.github.io/actix-web-rust-embed-responder/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SeriousBug.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-16T13:44:19.000Z","updated_at":"2024-06-28T01:06:15.000Z","dependencies_parsed_at":"2024-06-28T02:06:16.210Z","dependency_job_id":null,"html_url":"https://github.com/SeriousBug/actix-web-rust-embed-responder","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Factix-web-rust-embed-responder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Factix-web-rust-embed-responder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Factix-web-rust-embed-responder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Factix-web-rust-embed-responder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SeriousBug","download_url":"https://codeload.github.com/SeriousBug/actix-web-rust-embed-responder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225606620,"owners_count":17495551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T17:58:11.318Z","updated_at":"2024-11-20T17:58:12.060Z","avatar_url":"https://github.com/SeriousBug.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [Rust Embed Responder for Actix Web](https://github.com/SeriousBug/actix-web-rust-embed-responder)\n\n[![All Contributors](https://img.shields.io/github/all-contributors/SeriousBug/actix-web-rust-embed-responder)](#contributors)\n[![Crates.io](https://img.shields.io/crates/v/actix-web-rust-embed-responder)](https://crates.io/crates/actix-web-rust-embed-responder)\n[![docs.rs](https://img.shields.io/docsrs/actix-web-rust-embed-responder)](https://docs.rs/actix-web-rust-embed-responder/latest/actix_web_rust_embed_responder/)\n[![tests](https://img.shields.io/github/actions/workflow/status/SeriousBug/actix-web-rust-embed-responder/test.yml?label=tests\u0026branch=main)](https://github.com/SeriousBug/actix-web-rust-embed-responder/actions/workflows/test.yml)\n[![Test coverage report](https://img.shields.io/codecov/c/github/SeriousBug/actix-web-rust-embed-responder)](https://codecov.io/gh/SeriousBug/actix-web-rust-embed-responder)\n[![lint checks](https://img.shields.io/github/actions/workflow/status/SeriousBug/actix-web-rust-embed-responder/lint.yml?label=lint\u0026branch=main)](https://github.com/SeriousBug/actix-web-rust-embed-responder/actions/workflows/lint.yml)\n[![MIT license](https://img.shields.io/github/license/SeriousBug/actix-web-rust-embed-responder)](https://github.com/SeriousBug/actix-web-rust-embed-responder/blob/main/LICENSE.txt)\n\nAn Actix Web responder for serving files embedded into the server.\nYou can embed files into your server, and then use this responder to serve them out of your server.\nFor example you can have a web app serve its own assets, html, css, javascript files, and more.\n\nThis crate implements responders for [rust embed](https://docs.rs/rust-embed/latest/rust_embed/index.html),\nas well as a more efficient fork [rust-embed-for-web](https://github.com/SeriousBug/rust-embed-for-web).\n\n## Usage\n\nFirst, add this crate and `rust-embed` or `rust-embed-for-web` into your `Cargo.toml`.\n\n```toml\n[dependencies]\nactix-web = \"4.2\"\nrust-embed = \"6.4\" # or rust-embed-for-web = \"11.1\"\nactix-web-rust-embed-responder = \"2.1.1\"\n```\n\nThen, setup your embed and handler, and add your responder.\n\n```rs\nuse actix_web::{route, web, App, HttpServer};\nuse actix_web_rust_embed_responder::{EmbedResponse, IntoResponse};\nuse rust_embed::{EmbeddedFile, RustEmbed};\n\n#[derive(RustEmbed)]\n#[folder = \"path/to/assets/\"]\nstruct Embed;\n\n// This responder implements both GET and HEAD\n#[route(\"/{path:.*}\", method = \"GET\", method = \"HEAD\")]\n// The return type is important, that is the type for this responder\nasync fn serve_assets(path: web::Path\u003cString\u003e) -\u003e EmbedResponse\u003cEmbeddedFile\u003e {\n    // This is not required, but is likely what you want if you want this\n    // to serve `index.html` as the home page.\n    let path = if path.is_empty() {\n        \"index.html\"\n    } else {\n        path.as_str()\n    };\n    // There are implementations of `.into_response()` for both `EmbeddedFile` and `Option\u003cEmbeddedFile\u003e`.\n    // With `Option\u003cEmbeddedFile\u003e`, this responder will also handle sending a 404 response for `None`.\n    // If you want to customize the `404` response, you can handle the `None` case yourself: see the\n    // `custom-404.rs` test for an example.\n    Embed::get(path).into_response().\n}\n\n#[actix_web::main] // or #[tokio::main]\nasync fn main() -\u003e std::io::Result\u003c()\u003e {\n    HttpServer::new(|| App::new().service(serve_assets))\n        .bind((\"127.0.0.1\", 8080))?\n        .run()\n        .await\n}\n```\n\n## About the `rust-embed-for-web` fork\n\nThe fork pre-computes certain things, like the header values that are used in responses.\nIt can also compressed the data ahead of time.\nThis can significantly increase the size of your compiled binary, but in exchange improves performance significantly.\nYou can disable the pre-compression which will minimize the increase (see `rust-embed-for-web` readme for details).\n\nIn exchange for these limitations, you get improved performance.\nBased on some benchmarks, using the fork is 16% to 35% faster.\nFor more detailed information check the [benchmark reports](https://seriousbug.github.io/actix-web-rust-embed-responder/reports/).\n\n## Compression\n\nWith `rust-embed-for-web`, this crate will serve compressed responses to clients\nthat support them if compression is enabled for the embed (you didn't add\n`#[gzip = false]` and `#[br = false]`) and the file being served actually benefits from compression.\n\nWith `rust-embed`, compressed responses are not served by default. However you\ncan set `.use_compression(Compress::Always)` to turn it on. If you do, the files\nwill be compressed on the fly and cached. This will always compress files, even\nfor files like image files that are unlikely to benefit from compression.\n\n```rs\nEmbed::get(path).into_response().use_compression(Compress::Always)\n```\n\nFor `rust-embed-for-web`, if you disabled pre-compression with `#[gzip = false]` and `#[br = false]`,\nyou can also enable on-the-fly compression with `Compress::Always`.\nAlternatively, you can use `Compress::IfWellKnown` which will only compress files\nknown to be compressible such as html, css, and javascript.\nYou can also disable compression entirely with `Compress::Never`.\n\n## Customizing responses\n\nActix-web has a built-in response customization feature you can use.\n\n```rs\n#[route(\"/{path:.*}\", method = \"GET\", method = \"HEAD\")]\nasync fn handler(\n    path: web::Path\u003cString\u003e,\n) -\u003e CustomizeResponder\u003cEmbedResponse\u003cEmbeddedFile\u003e\u003e {\n    EmbedRE::get(path)\n        .into_response()\n        .customize()\n        .insert_header((\"X-My-Header\", \"My Header Value\"))\n}\n```\n\n## Examples\n\nThere are examples for both `rust-embed` and `rust-embed-for-web` in the [examples folder](https://github.com/SeriousBug/actix-web-rust-embed-responder/tree/main/examples).\nYou can run these examples by using `cargo run --example rust_embed --release` or `cargo run --example rust_embed_for_web --release`, then visiting `localhost:8080` in your browser.\n\n## Features\n\nBy default, this crate enables support for both `rust-embed` and\n`rust-embed-for-web`. You can disable support for the one you're not using:\n\n```toml\n# If you are using `rust-embed`:\nactix-web-rust-embed-responder = { version = \"2.1.1\", default-features = false, features = [\"support-rust-embed\"] }\n# If you are using `rust-embed-for-web`:\nactix-web-rust-embed-responder = { version = \"2.1.1\", default-features = false, features = [\"support-rust-embed-for-web\"] }\n```\n\nThere's also a feature flag `always-embed` which is disabled by default. This is only useful for testing, you can ignore this feature.\n\n## Compared to `actix-plus-static-files`\n\nCompared to [actix-plus-static-files](https://crates.io/crates/actix-plus-static-files):\n\n- This crate handles sending `304 Not Modified` responses both with `If-None-Match` and `If-Unmodified-Since` headers, while `actix-plus-static-files` only supports `If-None-Match`.\n- This crate supports compression, ahead of time with `rust-embed-for-web` or during transmission with `rust-embed`.\n- This crate uses base85 with `rust-embed-for-web` and base64 with `rust-embed` for the `ETag`, which is more space efficient than the hex encoding used by `actix-plus-static-files`.\n- This crate is only a responder for the `EmbeddedFile` type that you can add to your handlers, while `actix-plus-static-files` implements a service you can directly add into your app.\n- `actix-plus-for-web` implements `If-Any-Match` conditional requests, this crate does not. These are not usually used for `GET` and `HEAD` requests.\n\n## Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/hengfeiyang\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/1628250?v=4?s=100\" width=\"100px;\" alt=\"Hengfei Yang\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eHengfei Yang\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/SeriousBug/actix-web-rust-embed-responder/commits?author=hengfeiyang\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/mpalmer\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/357?v=4?s=100\" width=\"100px;\" alt=\"Matt Palmer\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMatt Palmer\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/SeriousBug/actix-web-rust-embed-responder/commits?author=mpalmer\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseriousbug%2Factix-web-rust-embed-responder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseriousbug%2Factix-web-rust-embed-responder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseriousbug%2Factix-web-rust-embed-responder/lists"}