@@ -351,10 +351,11 @@ impl Body {
351351 Ok ( serde_urlencoded:: from_str ( & s) . status ( StatusCode :: UnprocessableEntity ) ?)
352352 }
353353
354- /// Create a `Body` from a file.
354+ /// Create a `Body` from a file named by a path .
355355 ///
356- /// The Mime type set to `application/octet-stream` if no other mime type has
357- /// been set or can be sniffed.
356+ /// The Mime type is sniffed from the file contents if possible, otherwise
357+ /// it is inferred from the path's extension if possible, otherwise is set
358+ /// to `application/octet-stream`.
358359 ///
359360 /// # Examples
360361 ///
@@ -363,16 +364,68 @@ impl Body {
363364 /// use http_types::{Body, Response, StatusCode};
364365 ///
365366 /// let mut res = Response::new(StatusCode::Ok);
366- /// res.set_body(Body::from_file ("/path/to/file").await?);
367+ /// res.set_body(Body::from_path ("/path/to/file").await?);
367368 /// # Ok(()) }) }
368369 /// ```
369370 #[ cfg( all( feature = "fs" , not( target_os = "unknown" ) ) ) ]
370- pub async fn from_file < P > ( path : P ) -> io:: Result < Self >
371+ pub async fn from_path < P > ( path : P ) -> io:: Result < Self >
371372 where
372373 P : AsRef < std:: path:: Path > ,
373374 {
374375 let path = path. as_ref ( ) ;
375- let mut file = async_std:: fs:: File :: open ( path) . await ?;
376+ let file = async_std:: fs:: File :: open ( path) . await ?;
377+ Self :: from_file_with_path ( file, path) . await
378+ }
379+
380+ /// Create a `Body` from an already-open file.
381+ ///
382+ /// The Mime type is sniffed from the file contents if possible, otherwise
383+ /// is set to `application/octet-stream`.
384+ ///
385+ /// # Examples
386+ ///
387+ /// ```no_run
388+ /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
389+ /// use http_types::{Body, Response, StatusCode};
390+ ///
391+ /// let mut res = Response::new(StatusCode::Ok);
392+ /// let path = std::path::Path::new("/path/to/file");
393+ /// let file = async_std::fs::File::open(path).await?;
394+ /// res.set_body(Body::from_file(file).await?);
395+ /// # Ok(()) }) }
396+ /// ```
397+ #[ cfg( all( feature = "fs" , not( target_os = "unknown" ) ) ) ]
398+ #[ inline]
399+ pub async fn from_file ( file : async_std:: fs:: File ) -> io:: Result < Self > {
400+ Self :: from_file_with_path ( file, std:: path:: Path :: new ( "" ) ) . await
401+ }
402+
403+ /// Create a `Body` from an already-open file.
404+ ///
405+ /// The Mime type is sniffed from the file contents if possible, otherwise
406+ /// it is inferred from the path's extension if possible, otherwise is set
407+ /// to `application/octet-stream`.
408+ ///
409+ /// The path here is only used to provide an extension for guessing the Mime
410+ /// type, and may be empty if the path is unknown.
411+ ///
412+ /// # Examples
413+ ///
414+ /// ```no_run
415+ /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
416+ /// use http_types::{Body, Response, StatusCode};
417+ ///
418+ /// let mut res = Response::new(StatusCode::Ok);
419+ /// let path = std::path::Path::new("/path/to/file");
420+ /// let file = async_std::fs::File::open(path).await?;
421+ /// res.set_body(Body::from_file_with_path(file, path).await?);
422+ /// # Ok(()) }) }
423+ /// ```
424+ #[ cfg( all( feature = "fs" , not( target_os = "unknown" ) ) ) ]
425+ pub async fn from_file_with_path (
426+ mut file : async_std:: fs:: File ,
427+ path : & std:: path:: Path ,
428+ ) -> io:: Result < Self > {
376429 let len = file. metadata ( ) . await ?. len ( ) ;
377430
378431 // Look at magic bytes first, look at extension second, fall back to
0 commit comments