Comments (20)
@Boscop Yes. The crate mime_guess is needed to response content-type
. actix-web also relys on that crate (you can find usage in src/fs.rs folder of actix-web).
from rust-embed.
@Boscop Got it. This kind of use case didn't cross my mind. Will keep it the same way. Also will look for a proper solution for dev/prod paths being resolved properly. For the time being it works within the project root folder
from rust-embed.
Sorry. The actix example is TBD at the moment for a very long time. Will finish it when I get the time and based on need.
from rust-embed.
I'm very interested in the actix example because I want to do the same for my rust application for which I'm creating a GUI with yew..
Would this crate be necessary? https://crates.io/crates/mime_guess
from rust-embed.
Maybe. In the rocket example I use rockets inbuilt content guesser.
let content_type = ContentType::from_extension(ext).expect("Could not get file content type");
Maybe actix has an example like this.
from rust-embed.
Thanks to @Gowee We have a working example now. Or do we need some more improvements for this to be closed.
from rust-embed.
@Gowee Thanks. But in the actix example I don't see where it use the file extension of the path. It only does HttpResponse::Ok().body(content)
which doesn't use the extension..
I currently have:
.resource("/{tail:.*}", move |r| r.f({
move |r| -> Result<fs::NamedFile> {
let mut path: String = r.match_info().query("tail")?;
if path == "" {
path = "index.html".into();
}
match Asset::get(path) {
Some(content) => HttpResponse::Ok().body(content),
None => HttpResponse::NotFound().body("404 Not Found"),
}
}
}))
How can I use the mime type I get from mime_guess to set the content type of the HttpResponse
? (The actix docs failed to build, apparently..)
from rust-embed.
@Boscop
1.
HttpResponse::Ok()
.content_type(guess_mime_type(path).as_ref())
.body(content)
should work.
2. The lastest available document I find on doc.rs is 0.6.11. I do not known why the document for 0.6.15 is not available on doc.rs, but I can build that document using cargo doc --package actix-web --open
locally.
3. The return type Result<fs::NamedFile>
in your code seems to be incorrect here. fs:NamedFile
is just a wrapper of std::fs::File
, which corresponds to actual files in the filesystem. But I am also not familiar with actix-web
's API, you may consult the document for correcting.
from rust-embed.
.resource("/{tail:.*}", move |r| r.f({
move |r| {
let mut path: String = r.match_info().query("tail").unwrap();
if path == "" {
path = "index.html".into();
}
match Assets::get(&path) {
Some(content) => HttpResponse::Ok().content_type(&mime_guess::guess_mime_type(path)).body(content),
None => HttpResponse::NotFound().body("404 Not Found"),
}
}
}))
error: webui\src\act.rs:201: the trait bound
actix_web::http::header::HeaderValue: actix_web::http::HttpTryFrom<&mime_guess::Mime>
is not satisfied
error: webui\src\act.rs:201: the traitactix_web::http::HttpTryFrom<&mime_guess::Mime>
is not implemented foractix_web::http::header::HeaderValue
help: webui\src\act.rs:201: the following implementations were found:
<actix_web::http::header::HeaderValue as actix_web::http::HttpTryFrom<&'a str>>
<actix_web::http::header::HeaderValue as actix_web::http::HttpTryFrombytes::bytes::Bytes>
<actix_web::http::header::HeaderValue as actix_web::http::HttpTryFrom<&'a [u8]>>
<actix_web::http::header::HeaderValue as actix_web::http::HttpTryFrom<actix_web::http::header::HeaderValue>>
So how can I do this? (Without going through a String
with .to_string().as_str()
) :)
from rust-embed.
- I am using the lastest version 2.0.0-alpha.6 of mime_guess. So you may need to make sure you also use the same or higher version.
- In the latest version of mime_guess, there is
impl AsRef<str> for Mime
which provides the methodas_ref
. Here theMime
is the type of the value returned byguess_mime_type
. This trait can convert aMime
into a&str
which in turn can be used inHttpResponse::Ok().content_type(...)
. Do not replaceas_ref
with&
. They can not be used interchangeably AFAIK. With&
, you just get a value of&Mime
. Withas_ref
, the compiler can infer the correct type for you (&str
here). As is indicated by the log you give, there is<actix_web::http::header::HeaderValue as actix_web::http::HttpTryFrom<&'a str>>
and hence...content_type(...)
can take a&str
.
from rust-embed.
Ah thanks, I was using 1.8
but I updated it now to 2.0.0-alpha.6
.
But I always get 404 for every file that should be embedded, any idea why?
I have
#[derive(RustEmbed)]
#[folder = "../target/deploy"] // built with yew: cargo web deploy. the `..` is because this crate is part of a workspace
struct Assets;
.resource("/{tail:.*}", move |r| r.f({
move |r| {
let mut path: String = r.match_info().query("tail").unwrap();
if path == "" {
path = "index.html".into();
}
println!("{}", path);
match Assets::get(&path) {
Some(content) => HttpResponse::Ok().content_type(mime_guess::guess_mime_type(path).as_ref()).body(content),
None => HttpResponse::NotFound().body("404 Not Found"),
}
}
}))
E.g. I try with index.html
and style.css
, I always get 404. But that dir has those files!
from rust-embed.
@Boscop
https://github.com/pyros2097/rust-embed/blob/93bf8334488a8387ab419164aeabf7855ceda29d/src/lib.rs#L23
Try #[folder = "../target/deploy"]
=> #[folder = "../target/deploy/"]
?
from rust-embed.
Thanks, I also had to add another level of ../
to get out of src
first (I thought it'd take the crate root folder as starting point).
I'd prefer if the trailing /
was not mandatory, for usability/convenience reasons!
Or if the procmacro terminated with an error if the path has no trailing slash!
But it STILL doesn't work, still 404 error..
from rust-embed.
I'd prefer if the trailing / was not mandatory, for usability/convenience reasons! Or if the procmacro terminated with an error if the path has no trailing slash!
- I am not the maintainer. @pyros2097
But it STILL doesn't work, still 404 error..
- No idea. I suggest you
git clone
this repo locally, addprintln!("{}", path.canonicalize());
after this line:
https://github.com/pyros2097/rust-embed/blob/93bf8334488a8387ab419164aeabf7855ceda29d/src/lib.rs#L24 and use the modified version (by specifyingrust-embed = { path = "PATH_TO_CLONED_REPO"}
in Cargo.toml) in your project to ensure the path is what you expected.
from rust-embed.
Haha.. This is where the println!("{}", name);
was going to be really useful. It seems to me that rust-embed is not able to locate your dir. If you see the example the public folder is relative to the source file. It has to be this way since we use include_bytes
https://doc.rust-lang.org/std/macro.include_bytes.html
Also you are using cargo web not cargo build. I don't know how it handles this case.
It would be better if you explain your folder structure or create a simple example repo to try it out.
Welcome to suggestions and PR's for this I'd prefer if the trailing / was not mandatory, for usability
from rust-embed.
@pyros2097 I'm only using cargo web
to build the frontend files that will be embedded. I'm using a normal cargo build to build the backend that embeds the frontend files!
The problem is: In debug build, the dir would have to be target/deploy
because it's relative to the workspace from where I do cargo run
but in release build it would have to be ../../target/deploy
because include_bytes
uses paths relative to the .rs file, and that is in webui/src/act.rs
.
But this rust-embed crates uses the same path for debug AND release build, so it's not possible!
Since the build (and its embedded files) should not depend on the dir from where cargo build
is run, the path given to #[folder = ...]
SHOULD be relative to the .rs file in which it is written (or an absolute path).
Then, for debug builds, the procmacro code has to be adjusted so that it uses the right path:
It checks if it's a relative path, and if yes, it prepends the path of the folder of the .rs file that the #[derive(RustEmbed)]
was invoked in (this path is stored in a constant by the procmacro).
That way, the same path (relative to the .rs file's folder, or absolute) can be used for both debug and release builds. After all, that is the goal of this crate, right? :)
Otherwise people would be limited to absolute paths, which would be horrible for teams (everyone has their own different folder structure).
from rust-embed.
Ah no, when I use #[folder = "target/deploy/"]
it works in debug and release.
But still, in debug build, it should work, no matter which folder cargo
is invoked from!
#34
from rust-embed.
Haha... It works because it finds the files in your debug folder which is still present because its not cleaned.
Try cleaning it and building a fresh release build and it should fail since those files wont be present.
Also I'm thinking of using the same macro for debug and release that will solve the issue. I don't think rustc takes too much time to load files in the binary, so making dev and prod reproducible would make more sense now.
from rust-embed.
@Boscop Closing this now as @Gowee has implemented the mime guessing feature.
from rust-embed.
@pyros2097 But there are other crates that embed the files regardless of build mode! (At least 4 other crates, really.)
The whole point of this crate is to load the files from disk during debug and embed during release!
I don't want to have to rebuild (and link) my backend every time my frontend files changes during debug.
I'm using cargo web to build the frontend files, and want to fetch the new files when reloading the page in the browser.
My frontend page connects to the actix backend via websockets on the same port as the port that the page is served from.
It takes over a minute to only link my backend. It would slow down my frontend's development even more if I had to rebuild & link my backend every time my frontend code changes. As if the Rust build time for the frontend itself wasn't long enough (using yew, stdweb etc.)!
So please keep this behavior that it loads the files from disk in debug.
Btw, what do you mean by "It works because it finds the files in your debug folder which is still present because its not cleaned."? (cargo web deploy
builds into target/deploy
.)
from rust-embed.
Related Issues (20)
- Depending on wrong version of `walkdir`. HOT 1
- Bump `syn` ^2 HOT 1
- The `mime-guess` feature doesn't work HOT 4
- using with askama compile time templates HOT 3
- Fix compression with interpolated env HOT 2
- Clarify MSRV policy HOT 7
- error[E0609]: no field `data` on type `Cow<'_, [u8]>` HOT 1
- Is there a way to include files based on an externally generated list HOT 6
- Rename RustEmbed trait to Embed? HOT 5
- Axum 0.7.1 - no function or associated item named `get` found for struct `Asset` in the current scope HOT 1
- Is there a way to encrypt embedded file? Maybe before/after hooks? HOT 10
- A feature analogous to debug-embed, but for WASM? HOT 2
- Debug builds more lenient when loading relative paths
- `RustEmbed` derive macro is susceptible to naming collisions HOT 2
- rust-embed is tainted with MPL-2 via option-ext HOT 1
- low compilation performance when embeding large folder even though having excludes. HOT 1
- Unable to read symbolic link in debug mode HOT 4
- Replace / expand `prefix` to allow using a generic function for rewriting paths HOT 2
- Option to not include file contents HOT 1
- Check files exist at compile time HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust-embed.