mirror of https://github.com/rwf2/Rocket.git
Strip body and content-length on 204, body on 304.
This works-around an issue where hyper incorrectly removes the body on 204 responses without removing the content-length or setting it to zero. Resolves #2821.
This commit is contained in:
parent
d3323391ab
commit
9496b70e8c
|
@ -134,12 +134,17 @@ impl Rocket<Orbit> {
|
|||
// Run the response fairings.
|
||||
self.fairings.handle_response(request, &mut response).await;
|
||||
|
||||
// Strip the body if this is a `HEAD` request.
|
||||
if was_head_request {
|
||||
// Strip the body if this is a `HEAD` request or a 304 response.
|
||||
if was_head_request || response.status() == Status::NotModified {
|
||||
response.strip_body();
|
||||
}
|
||||
|
||||
if let Some(size) = response.body_mut().size().await {
|
||||
// If the response status is 204, strip the body and its size (no
|
||||
// content-length header). Otherwise, check if the body is sized and use
|
||||
// that size to set the content-length headr appropriately.
|
||||
if response.status() == Status::NoContent {
|
||||
*response.body_mut() = crate::response::Body::unsized_none();
|
||||
} else if let Some(size) = response.body_mut().size().await {
|
||||
response.set_raw_header("Content-Length", size.to_string());
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,14 @@ impl<'r> Body<'r> {
|
|||
/// The present value is `4096`.
|
||||
pub const DEFAULT_MAX_CHUNK: usize = 4096;
|
||||
|
||||
pub(crate) fn unsized_none() -> Self {
|
||||
Body {
|
||||
size: None,
|
||||
inner: Inner::None,
|
||||
max_chunk: Body::DEFAULT_MAX_CHUNK,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn with_sized<T>(body: T, preset_size: Option<usize>) -> Self
|
||||
where T: AsyncReadSeek + Send + 'r
|
||||
{
|
||||
|
|
|
@ -7,3 +7,4 @@ pub mod mtls;
|
|||
pub mod sni_resolver;
|
||||
pub mod tracing;
|
||||
pub mod tls;
|
||||
pub mod no_content;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//! Ensure that responses with a status of 204 or 304 do not have a body, and
|
||||
//! for the former, do not have a Content-Length header.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use rocket::http::Status;
|
||||
|
||||
#[get("/<code>")]
|
||||
fn status(code: u16) -> (Status, &'static [u8]) {
|
||||
(Status::new(code), &[1, 2, 3, 4])
|
||||
}
|
||||
|
||||
pub fn test_no_content() -> Result<()> {
|
||||
let server = spawn!(Rocket::default().mount("/", routes![status]))?;
|
||||
|
||||
let client = Client::default();
|
||||
let response = client.get(&server, "/204")?.send()?;
|
||||
assert_eq!(response.status(), 204);
|
||||
assert!(response.headers().get("Content-Length").is_none());
|
||||
assert!(response.bytes()?.is_empty());
|
||||
|
||||
let response = client.get(&server, "/304")?.send()?;
|
||||
assert_eq!(response.status(), 304);
|
||||
assert_eq!(response.headers().get("Content-Length").unwrap(), "4");
|
||||
assert!(response.bytes()?.is_empty());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
register!(test_no_content);
|
Loading…
Reference in New Issue