Skip to content

Commit

Permalink
test (and fix) close delimited responses
Browse files Browse the repository at this point in the history
a HTTP response with Connection:close but no content length should be
interepreted as having its body stop at the connection end
  • Loading branch information
Geal committed Aug 20, 2021
1 parent e6e685f commit 6981f09
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
9 changes: 8 additions & 1 deletion lib/src/protocol/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,14 @@ impl<Front:SocketHandler> Http<Front> {
if self.response == Some(ResponseState::Initial) {
self.set_answer(DefaultAnswerStatus::Answer503, None);
} else {
self.set_answer(DefaultAnswerStatus::Answer502, None);
if let Some(ResponseState::ResponseWithBodyCloseDelimited(_, _, ref mut back_closed)) = self.response.as_mut() {
*back_closed = true;
// trick the protocol into calling readable() again
self.back_readiness.event.insert(Ready::readable());
return SessionResult::Continue;
} else {
self.set_answer(DefaultAnswerStatus::Answer502, None);
}
}
// we're not expecting any more data from the backend
self.back_readiness.interest = Ready::empty();
Expand Down
21 changes: 20 additions & 1 deletion lib/tests/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,25 @@ fn test() {
assert_eq!(res.header("Content-Length"), Some("5"));
assert_eq!(res.into_string().unwrap(), "Hello");

let barrier2 = barrier.clone();
let _ = thread::spawn(move || {
let listener = TcpListener::bind("127.0.0.1:2048").expect("could not parse address");
barrier2.wait();
let mut stream = listener.incoming().next().unwrap().unwrap();
let response = b"HTTP/1.1 200 Ok\r\nConnection: close\r\n\r\nHello world!";
stream.write(&response[..]).unwrap();
stream.shutdown(std::net::Shutdown::Both).unwrap();
});

barrier.wait();
info!("expecting 200 then close, without content length");
let res = agent
.get("http://example.com:8080/")
.call().unwrap();
assert_eq!(res.status(), 200);
assert_eq!(res.status_text(), "Ok");
assert_eq!(res.into_string().unwrap(), "Hello world!");


let barrier2 = barrier.clone();
let _ = thread::spawn(move || {
Expand Down Expand Up @@ -254,7 +273,7 @@ fn test() {

//let _ = jg.join();
//barrier.wait();
info!("expecting 200");
info!("expecting 100");
let res = agent
.get("http://example.com:8080/100")
.set("Expect", "100-continue")
Expand Down

0 comments on commit 6981f09

Please sign in to comment.