Always strip bodies on 'HEAD' requests.

Closes #544.
Closes #514.
This commit is contained in:
Sergio Benitez 2018-01-19 11:21:56 -08:00
parent 72d2ccc2a5
commit d2727972fd
2 changed files with 29 additions and 18 deletions

View File

@ -227,7 +227,7 @@ impl Rocket {
let request: &'r mut Request<'s> =
unsafe { (&mut *(request as *const _ as *mut _)) };
// There was no matching route.
// There was no matching route. Autohandle `HEAD` requests.
if request.method() == Method::Head {
info_!("Autohandling {} request.", Paint::white("HEAD"));
request.set_method(Method::Get);
@ -241,6 +241,11 @@ impl Rocket {
Outcome::Failure(status) => self.handle_error(status, request),
};
// Strip the body if this is a `HEAD` request.
if request.method() == Method::Head {
response.strip_body();
}
// Add the 'rocket' server header to the response and run fairings.
// TODO: If removing Hyper, write out `Date` header too.
response.set_header(Header::new("Server", "Rocket"));

View File

@ -16,13 +16,15 @@ fn index() -> &'static str {
}
#[head("/other")]
fn other() -> content::Json<()> {
content::Json(())
fn other() -> content::Json<&'static str> {
content::Json("{ 'hi': 'hello' }")
}
mod tests {
mod head_handling_tests {
use super::*;
use std::io::Read;
use rocket::Route;
use rocket::local::Client;
use rocket::http::{Status, ContentType};
@ -32,37 +34,41 @@ mod tests {
routes![index, empty, other]
}
fn assert_empty_sized_body<T: Read>(body: Body<T>, expected_size: u64) {
match body {
Body::Sized(mut body, size) => {
let mut buffer = vec![];
let n = body.read_to_end(&mut buffer).unwrap();
assert_eq!(size, expected_size);
assert_eq!(n, 0);
}
_ => panic!("Expected a sized body.")
}
}
#[test]
fn auto_head() {
let client = Client::new(rocket::ignite().mount("/", routes())).unwrap();
let mut response = client.head("/").dispatch();
assert_eq!(response.status(), Status::Ok);
if let Some(body) = response.body() {
match body {
Body::Sized(_, n) => assert_eq!(n, "Hello, world!".len() as u64),
_ => panic!("Expected a sized body!")
}
assert_eq!(body.into_string(), Some("".to_string()));
} else {
panic!("Expected a non-empty body!")
}
assert_empty_sized_body(response.body().unwrap(), 13);
let content_type: Vec<_> = response.headers().get("Content-Type").collect();
assert_eq!(content_type, vec![ContentType::Plain.to_string()]);
let response = client.head("empty").dispatch();
let mut response = client.head("/empty").dispatch();
assert_eq!(response.status(), Status::NoContent);
assert!(response.body_bytes().is_none());
}
#[test]
fn user_head() {
let client = Client::new(rocket::ignite().mount("/", routes())).unwrap();
let response = client.head("/other").dispatch();
let mut response = client.head("/other").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_empty_sized_body(response.body().unwrap(), 17);
let content_type: Vec<_> = response.headers().get("Content-Type").collect();
assert_eq!(response.status(), Status::Ok);
assert_eq!(content_type, vec![ContentType::JSON.to_string()]);
}
}