Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't move MIME out of the body #83

Merged
merged 1 commit into from
Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pin_project_lite::pin_project! {
pub struct Body {
#[pin]
reader: Box<dyn BufRead + Unpin + Send + Sync + 'static>,
mime: Option<Mime>,
mime: Mime,
length: Option<usize>,
}
}
Expand All @@ -74,7 +74,7 @@ impl Body {
pub fn empty() -> Self {
Self {
reader: Box::new(io::empty()),
mime: Some(mime::BYTE_STREAM),
mime: mime::BYTE_STREAM,
length: Some(0),
}
}
Expand Down Expand Up @@ -104,7 +104,7 @@ impl Body {
) -> Self {
Self {
reader: Box::new(reader),
mime: Some(mime::BYTE_STREAM),
mime: mime::BYTE_STREAM,
length: len,
}
}
Expand Down Expand Up @@ -147,9 +147,8 @@ impl Body {
self.reader
}

/// Return the mime type.
pub(crate) fn take_mime(&mut self) -> Mime {
self.mime.take().expect("internal error: missing mime")
pub(crate) fn mime(&self) -> &Mime {
&self.mime
}
}

Expand All @@ -167,7 +166,7 @@ impl From<String> for Body {
Self {
length: Some(s.len()),
reader: Box::new(io::Cursor::new(s.into_bytes())),
mime: Some(string_mime()),
mime: string_mime(),
}
}
}
Expand All @@ -177,7 +176,7 @@ impl<'a> From<&'a str> for Body {
Self {
length: Some(s.len()),
reader: Box::new(io::Cursor::new(s.to_owned().into_bytes())),
mime: Some(string_mime()),
mime: string_mime(),
}
}
}
Expand All @@ -195,7 +194,7 @@ impl From<Vec<u8>> for Body {
Self {
length: Some(b.len()),
reader: Box::new(io::Cursor::new(b)),
mime: Some(mime::BYTE_STREAM),
mime: mime::BYTE_STREAM,
}
}
}
Expand Down
20 changes: 13 additions & 7 deletions src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,7 @@ impl Request {
/// req.set_body("Hello, Nori!");
/// ```
pub fn set_body(&mut self, body: impl Into<Body>) {
self.body = body.into();
if self.header(&CONTENT_TYPE).is_none() {
let mime = self.body.take_mime();
self.set_content_type(mime);
}
self.replace_body(body);
}

/// Swaps the value of the body with another body, without deinitializing
Expand All @@ -141,7 +137,9 @@ impl Request {
/// # Ok(()) }) }
/// ```
pub fn replace_body(&mut self, body: impl Into<Body>) -> Body {
mem::replace(&mut self.body, body.into())
let body = mem::replace(&mut self.body, body.into());
self.copy_content_type_from_body();
body
}

/// Replace the request body with a new body, and return the old body.
Expand All @@ -168,6 +166,7 @@ impl Request {
/// ```
pub fn swap_body(&mut self, body: &mut Body) {
mem::swap(&mut self.body, body);
self.copy_content_type_from_body();
}

/// Take the request body, replacing it with an empty body.
Expand Down Expand Up @@ -270,6 +269,13 @@ impl Request {
self.insert_header(CONTENT_TYPE, value).unwrap()
}

/// Copy MIME data from the body.
fn copy_content_type_from_body(&mut self) {
if self.header(&CONTENT_TYPE).is_none() {
self.set_content_type(self.body.mime().clone());
}
}

/// Get the current content type
pub fn content_type(&self) -> Option<Mime> {
self.header(&CONTENT_TYPE)?.last()?.as_str().parse().ok()
Expand Down Expand Up @@ -446,7 +452,7 @@ impl Request {
/// assert_eq!(req.local().get(), Some(&"hello from the extension"));
/// #
/// # Ok(()) }
/// ```
/// ```
pub fn local_mut(&mut self) -> &mut TypeMap {
&mut self.local
}
Expand Down
20 changes: 13 additions & 7 deletions src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,7 @@ impl Response {
/// # Ok(()) }
/// ```
pub fn set_body(&mut self, body: impl Into<Body>) {
self.body = body.into();
if self.header(&CONTENT_TYPE).is_none() {
let mime = self.body.take_mime();
self.set_content_type(mime);
}
self.replace_body(body);
}

/// Replace the response body with a new body, returning the old body.
Expand All @@ -168,7 +164,9 @@ impl Response {
/// # Ok(()) }) }
/// ```
pub fn replace_body(&mut self, body: impl Into<Body>) -> Body {
mem::replace(&mut self.body, body.into())
let body = mem::replace(&mut self.body, body.into());
self.copy_content_type_from_body();
body
}

/// Swaps the value of the body with another body, without deinitializing
Expand Down Expand Up @@ -197,6 +195,7 @@ impl Response {
/// ```
pub fn swap_body(&mut self, body: &mut Body) {
mem::swap(&mut self.body, body);
self.copy_content_type_from_body();
}

/// Take the response body, replacing it with an empty body.
Expand Down Expand Up @@ -236,6 +235,13 @@ impl Response {
self.insert_header(CONTENT_TYPE, value).unwrap()
}

/// Copy MIME data from the body.
fn copy_content_type_from_body(&mut self) {
if self.header(&CONTENT_TYPE).is_none() {
self.set_content_type(self.body.mime().clone());
}
}

/// Get the length of the body stream, if it has been set.
///
/// This value is set when passing a fixed-size object into as the body. E.g. a string, or a
Expand Down Expand Up @@ -412,7 +418,7 @@ impl Response {
/// assert_eq!(res.local().get(), Some(&"hello from the extension"));
/// #
/// # Ok(()) }
/// ```
/// ```
pub fn local_mut(&mut self) -> &mut TypeMap {
&mut self.local
}
Expand Down
30 changes: 30 additions & 0 deletions tests/req_res_body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use async_std::io::prelude::*;
use http_types::{Body, Method, Request, Response, StatusCode, Url};

#[test]
fn test_req_res_set_body() {
let mut req = Request::new(Method::Get, Url::parse("http://example.com/").unwrap());
req.set_body(Body::empty());
let mut res = Response::new(StatusCode::Ok);
res.set_body(req);
let body = async_std::task::block_on(async move {
let mut body = Vec::new();
res.read_to_end(&mut body).await.unwrap();
body
});
assert!(body.is_empty());
}

#[test]
fn test_req_res_take_replace_body() {
let mut req = Request::new(Method::Get, Url::parse("http://example.com/").unwrap());
req.take_body();
let mut res = Response::new(StatusCode::Ok);
res.replace_body(req);
let body = async_std::task::block_on(async move {
let mut body = Vec::new();
res.read_to_end(&mut body).await.unwrap();
body
});
assert!(body.is_empty());
}