mirror of https://github.com/http-rs/http-types
Merge pull request #318 from sunfishcode/main
Rename Body::from_file to Body::from_path, add Body::from_file, handle filename-based MIME-type guessing for File objects
This commit is contained in:
commit
bf5ace678c
65
src/body.rs
65
src/body.rs
|
@ -351,10 +351,11 @@ impl Body {
|
|||
Ok(serde_urlencoded::from_str(&s).status(StatusCode::UnprocessableEntity)?)
|
||||
}
|
||||
|
||||
/// Create a `Body` from a file.
|
||||
/// Create a `Body` from a file named by a path.
|
||||
///
|
||||
/// The Mime type set to `application/octet-stream` if no other mime type has
|
||||
/// been set or can be sniffed.
|
||||
/// The Mime type is sniffed from the file contents if possible, otherwise
|
||||
/// it is inferred from the path's extension if possible, otherwise is set
|
||||
/// to `application/octet-stream`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -363,16 +364,68 @@ impl Body {
|
|||
/// use http_types::{Body, Response, StatusCode};
|
||||
///
|
||||
/// let mut res = Response::new(StatusCode::Ok);
|
||||
/// res.set_body(Body::from_file("/path/to/file").await?);
|
||||
/// res.set_body(Body::from_path("/path/to/file").await?);
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(all(feature = "fs", not(target_os = "unknown")))]
|
||||
pub async fn from_file<P>(path: P) -> io::Result<Self>
|
||||
pub async fn from_path<P>(path: P) -> io::Result<Self>
|
||||
where
|
||||
P: AsRef<std::path::Path>,
|
||||
{
|
||||
let path = path.as_ref();
|
||||
let mut file = async_std::fs::File::open(path).await?;
|
||||
let file = async_std::fs::File::open(path).await?;
|
||||
Self::from_file_with_path(file, path).await
|
||||
}
|
||||
|
||||
/// Create a `Body` from an already-open file.
|
||||
///
|
||||
/// The Mime type is sniffed from the file contents if possible, otherwise
|
||||
/// is set to `application/octet-stream`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
|
||||
/// use http_types::{Body, Response, StatusCode};
|
||||
///
|
||||
/// let mut res = Response::new(StatusCode::Ok);
|
||||
/// let path = std::path::Path::new("/path/to/file");
|
||||
/// let file = async_std::fs::File::open(path).await?;
|
||||
/// res.set_body(Body::from_file(file).await?);
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(all(feature = "fs", not(target_os = "unknown")))]
|
||||
#[inline]
|
||||
pub async fn from_file(file: async_std::fs::File) -> io::Result<Self> {
|
||||
Self::from_file_with_path(file, std::path::Path::new("")).await
|
||||
}
|
||||
|
||||
/// Create a `Body` from an already-open file.
|
||||
///
|
||||
/// The Mime type is sniffed from the file contents if possible, otherwise
|
||||
/// it is inferred from the path's extension if possible, otherwise is set
|
||||
/// to `application/octet-stream`.
|
||||
///
|
||||
/// The path here is only used to provide an extension for guessing the Mime
|
||||
/// type, and may be empty if the path is unknown.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
|
||||
/// use http_types::{Body, Response, StatusCode};
|
||||
///
|
||||
/// let mut res = Response::new(StatusCode::Ok);
|
||||
/// let path = std::path::Path::new("/path/to/file");
|
||||
/// let file = async_std::fs::File::open(path).await?;
|
||||
/// res.set_body(Body::from_file_with_path(file, path).await?);
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(all(feature = "fs", not(target_os = "unknown")))]
|
||||
pub async fn from_file_with_path(
|
||||
mut file: async_std::fs::File,
|
||||
path: &std::path::Path,
|
||||
) -> io::Result<Self> {
|
||||
let len = file.metadata().await?.len();
|
||||
|
||||
// Look at magic bytes first, look at extension second, fall back to
|
||||
|
|
|
@ -6,7 +6,7 @@ mod tests {
|
|||
|
||||
#[async_std::test]
|
||||
async fn guess_plain_text_mime() -> io::Result<()> {
|
||||
let body = Body::from_file("tests/fixtures/index.html").await?;
|
||||
let body = Body::from_path("tests/fixtures/index.html").await?;
|
||||
let mut res = Response::new(200);
|
||||
res.set_body(body);
|
||||
assert_eq!(res.content_type(), Some(mime::HTML));
|
||||
|
@ -15,7 +15,7 @@ mod tests {
|
|||
|
||||
#[async_std::test]
|
||||
async fn guess_binary_mime() -> http_types::Result<()> {
|
||||
let body = Body::from_file("tests/fixtures/nori.png").await?;
|
||||
let body = Body::from_path("tests/fixtures/nori.png").await?;
|
||||
let mut res = Response::new(200);
|
||||
res.set_body(body);
|
||||
assert_eq!(res.content_type(), Some(mime::PNG));
|
||||
|
@ -29,7 +29,7 @@ mod tests {
|
|||
|
||||
#[async_std::test]
|
||||
async fn guess_mime_fallback() -> io::Result<()> {
|
||||
let body = Body::from_file("tests/fixtures/unknown.custom").await?;
|
||||
let body = Body::from_path("tests/fixtures/unknown.custom").await?;
|
||||
let mut res = Response::new(200);
|
||||
res.set_body(body);
|
||||
assert_eq!(res.content_type(), Some(mime::BYTE_STREAM));
|
||||
|
@ -38,7 +38,7 @@ mod tests {
|
|||
|
||||
#[async_std::test]
|
||||
async fn parse_empty_files() -> http_types::Result<()> {
|
||||
let body = Body::from_file("tests/fixtures/empty.custom").await?;
|
||||
let body = Body::from_path("tests/fixtures/empty.custom").await?;
|
||||
let mut res = Response::new(200);
|
||||
res.set_body(body);
|
||||
assert_eq!(res.content_type(), Some(mime::BYTE_STREAM));
|
||||
|
|
Loading…
Reference in New Issue