diff --git a/CHANGES.md b/CHANGES.md index e40bad5b..83803abb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Changes +## [x.x.xx] - xxxx-xx-xx + +### Added + +* Add `from_file` and `from_file_with_config` to `NamedFile` to allow sending files without a known path. #670 + ## [0.7.18] - 2019-01-10 ### Added diff --git a/src/fs.rs b/src/fs.rs index b7370c64..04ababd0 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -120,6 +120,32 @@ pub struct NamedFile { } impl NamedFile { + /// Creates an instance from a previously opened file. + /// + /// The given `path` need not exist and is only used to determine the `ContentType` and + /// `ContentDisposition` headers. + /// + /// # Examples + /// + /// ```no_run + /// extern crate actix_web; + /// + /// use actix_web::fs::NamedFile; + /// use std::io::{self, Write}; + /// use std::env; + /// use std::fs::File; + /// + /// fn main() -> io::Result<()> { + /// let mut file = File::create("foo.txt")?; + /// file.write_all(b"Hello, world!")?; + /// let named_file = NamedFile::from_file(file, "bar.txt")?; + /// Ok(()) + /// } + /// ``` + pub fn from_file>(file: File, path: P) -> io::Result { + Self::from_file_with_config(file, path, DefaultConfig) + } + /// Attempts to open a file in read-only mode. /// /// # Examples @@ -135,16 +161,29 @@ impl NamedFile { } impl NamedFile { - /// Attempts to open a file in read-only mode using provided configiration. + /// Creates an instance from a previously opened file using the provided configuration. + /// + /// The given `path` need not exist and is only used to determine the `ContentType` and + /// `ContentDisposition` headers. /// /// # Examples /// - /// ```rust - /// use actix_web::fs::{DefaultConfig, NamedFile}; + /// ```no_run + /// extern crate actix_web; /// - /// let file = NamedFile::open_with_config("foo.txt", DefaultConfig); + /// use actix_web::fs::{DefaultConfig, NamedFile}; + /// use std::io::{self, Write}; + /// use std::env; + /// use std::fs::File; + /// + /// fn main() -> io::Result<()> { + /// let mut file = File::create("foo.txt")?; + /// file.write_all(b"Hello, world!")?; + /// let named_file = NamedFile::from_file_with_config(file, "bar.txt", DefaultConfig)?; + /// Ok(()) + /// } /// ``` - pub fn open_with_config>(path: P, _: C) -> io::Result> { + pub fn from_file_with_config>(file: File, path: P, _: C) -> io::Result> { let path = path.as_ref().to_path_buf(); // Get the name of the file and use it to construct default Content-Type @@ -169,7 +208,6 @@ impl NamedFile { (ct, cd) }; - let file = File::open(&path)?; let md = file.metadata()?; let modified = md.modified().ok(); let cpu_pool = None; @@ -188,6 +226,19 @@ impl NamedFile { }) } + /// Attempts to open a file in read-only mode using provided configuration. + /// + /// # Examples + /// + /// ```rust + /// use actix_web::fs::{DefaultConfig, NamedFile}; + /// + /// let file = NamedFile::open_with_config("foo.txt", DefaultConfig); + /// ``` + pub fn open_with_config>(path: P, config: C) -> io::Result> { + Self::from_file_with_config(File::open(&path)?, path, config) + } + /// Returns reference to the underlying `File` object. #[inline] pub fn file(&self) -> &File {