Skip to content

Commit

Permalink
fix(server): skip automatic Content-Length header for HTTP 304 responses
Browse files Browse the repository at this point in the history
  • Loading branch information
jxs authored and seanmonstar committed May 7, 2019
1 parent 7fde9ba commit b342c38
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
17 changes: 11 additions & 6 deletions src/proto/h1/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,14 +476,20 @@ impl Http1Transaction for Server {
},
None |
Some(BodyLength::Known(0)) => {
extend(dst, b"content-length: 0\r\n");
if msg.head.subject != StatusCode::NOT_MODIFIED {
extend(dst, b"content-length: 0\r\n");
}
Encoder::length(0)
},
Some(BodyLength::Known(len)) => {
extend(dst, b"content-length: ");
let _ = ::itoa::write(&mut dst, len);
extend(dst, b"\r\n");
Encoder::length(len)
if msg.head.subject == StatusCode::NOT_MODIFIED {
Encoder::length(0)
} else {
extend(dst, b"content-length: ");
let _ = ::itoa::write(&mut dst, len);
extend(dst, b"\r\n");
Encoder::length(len)
}
},
};
}
Expand Down Expand Up @@ -1583,4 +1589,3 @@ mod tests {
})
}
}

46 changes: 45 additions & 1 deletion tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1687,6 +1687,51 @@ fn http2_service_poll_ready_error_sends_goaway() {
assert_eq!(h2_err.reason(), Some(h2::Reason::INADEQUATE_SECURITY));
}

#[test]
fn skips_content_length_for_304_responses() {
let server = serve();
server.reply()

.status(hyper::StatusCode::NOT_MODIFIED)
.body("foo");
let mut req = connect(server.addr());
req.write_all(b"\
GET / HTTP/1.1\r\n\
Host: example.domain\r\n\
Connection: close\r\n\
\r\n\
").unwrap();

let mut response = String::new();
req.read_to_string(&mut response).unwrap();
assert!(!response.contains("content-length:"));
}

#[test]
fn skips_content_length_and_body_for_304_responses() {
let server = serve();
server.reply()

.status(hyper::StatusCode::NOT_MODIFIED)
.body("foo");
let mut req = connect(server.addr());
req.write_all(b"\
GET / HTTP/1.1\r\n\
Host: example.domain\r\n\
Connection: close\r\n\
\r\n\
").unwrap();

let mut response = String::new();
req.read_to_string(&mut response).unwrap();
assert!(!response.contains("content-length:"));
let mut lines = response.lines();
assert_eq!(lines.next(), Some("HTTP/1.1 304 Not Modified"));

let mut lines = lines.skip_while(|line| !line.is_empty());
assert_eq!(lines.next(), Some(""));
assert_eq!(lines.next(), None);
}
// -------------------------------------------------
// the Server that is used to run all the tests with
// -------------------------------------------------
Expand Down Expand Up @@ -2058,4 +2103,3 @@ impl Drop for Dropped {
self.0.store(true, Ordering::SeqCst);
}
}

0 comments on commit b342c38

Please sign in to comment.