Rocket icon indicating copy to clipboard operation
Rocket copied to clipboard

Static files ,IfMatch/IfModifiedSince/ComputeRange/ComputeIfRange

Open mokeyish opened this issue 2 years ago • 3 comments

Related issues:

  • https://github.com/SergioBenitez/Rocket/issues/95
  • https://github.com/SergioBenitez/Rocket/pull/1376
  • https://github.com/SergioBenitez/Rocket/issues/989
  1. rust-embed - examples

    
    use std::path::PathBuf;
    use std::ffi::OsStr;
    use std::io::Cursor;
    use rocket::{
        http::{
            ContentType,
            DateTimeOffset,
            EntityTagHeaderValue
        },
        Request,
        response::{
            self, Responder,
        },
        fs::StaticFileContext
    };
    
    
    #[derive(rust_embed::RustEmbed)]
    #[folder = "dist"]
    struct Asset;
    
    pub struct EmbeddedFile {
        file: rust_embed::EmbeddedFile,
        content_type: Option<ContentType>,
    }
    
    
    impl EmbeddedFile {
        pub fn get(file_name: PathBuf) -> Option<Self> {
            let file: Option<rust_embed::EmbeddedFile>  = file_name.to_str().and_then(Asset::get);
    
            let file = file?;
    
            let content_type: Option<ContentType> = file_name
                .extension()
                .and_then(OsStr::to_str)
                .and_then(ContentType::from_extension);
            Some(Self { file, content_type })
        }
    }
    
    impl<'r> Responder<'r, 'static> for EmbeddedFile {
        fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
            let Self{file, content_type} = self;
            let mut static_ctx = StaticFileContext::from((
                file.data.len() as u64, content_type,
                EntityTagHeaderValue::from(&file.metadata.sha256_hash()),
                file.metadata.last_modified().map(|t| t * 1000).map(DateTimeOffset::from).unwrap_or_else(DateTimeOffset::now)
            ));
            static_ctx.comprehend_request_headers(req);
            static_ctx.proceed(req, |(builder, pos ,len)| {
                let mut data = Cursor::new(file.data);
                if pos > 0 {
                    data.set_position(pos);
                }
                builder.sized_body(len as usize, data);
            })
        }
    }
    
    

mokeyish avatar Aug 01 '21 06:08 mokeyish

@mokeyish Could you fix also clippy warning? (only in added files) There is plenty of them, like: unussed_imports, let_and_return, len_zero, field_reassign_with_default, redundant_closure.

Just run cargo clippy

mateuszkj avatar Aug 04 '21 14:08 mateuszkj

@mokeyish Could you fix also clippy warning? (only in added files) There is plenty of them, like: unussed_imports, let_and_return, len_zero, field_reassign_with_default, redundant_closure.

Just run cargo clippy

Crash in release mode has been fixed. But cargo clippy seems a lot of work, Can you fix it and send a PR to my branch? I din't have enough time to fixe it, since I am busy these days .

mokeyish avatar Aug 05 '21 01:08 mokeyish

Are you sure about this? It seems to me it should be if current >= input.len() || input[current] == '.' { You should return 0 if current points out of input buffer. Same mistake is repeated in other changes in this commit.

Sorry :sweat_smile:

mokeyish avatar Aug 13 '21 15:08 mokeyish

I'm sorry I'm coming to this a year and a half later. Perhaps if I had reviewed it earlier, we would have made progress on this by now. Unfortunately, I cannot accept the PR as is because it reimplements functionality that already exists in Rocket. I do not understand why a new responder type StaticFile is being added when Rocket has (and has had) NamedFile. I also don't understand how these changes apply to anything existing, including FileServer and NamedFile. It feels to me that this is a dump of an external library into Rocket's core, which is generally not something we'd like to do.

Since this can live outside of Rocket and doesn't integrate into any of Rocket's existing infrastructure (and duplicates much of it), I'm closing this out. If you'd like to pursue this further, please submit a PR that begins with a design idea and perhaps a minimal implementation of it. For example, an implementation that includes two headers, one which has a value and one which doesn't, and an example enabling those headers for FileServer and NamedFile.

Thank you for the contribution.

SergioBenitez avatar Mar 30 '23 23:03 SergioBenitez