diff --git a/crates/examples/sel4cp/http-server/pds/server/core/src/server.rs b/crates/examples/sel4cp/http-server/pds/server/core/src/server.rs index b0d5a4573..b5c6b9aa0 100644 --- a/crates/examples/sel4cp/http-server/pds/server/core/src/server.rs +++ b/crates/examples/sel4cp/http-server/pds/server/core/src/server.rs @@ -23,25 +23,34 @@ impl Server { &self, conn: &mut U, ) -> Result<(), ClosedError> { - let mut buf = vec![0; 1024 * 16]; - let mut i = 0; loop { - let n = conn.recv(&mut buf[i..]).await?; - assert_ne!(n, 0); - i += n; - if is_request_complete(&buf[..i]).unwrap_or(false) { - break; + let mut buf = vec![0; 1024 * 16]; + let mut i = 0; + loop { + let n = conn.recv(&mut buf[i..]).await?; + assert_ne!(n, 0); + i += n; + if is_request_complete(&buf[..i]).unwrap_or(false) { + break; + } } - } - let mut headers = [httparse::EMPTY_HEADER; 32]; - let mut req = httparse::Request::new(&mut headers); - match req.parse(&buf) { - Ok(status) => { - assert!(status.is_complete()); - self.handle_request(conn, req.path.unwrap()).await?; + let mut headers = [httparse::EMPTY_HEADER; 32]; + let mut req = httparse::Request::new(&mut headers); + let mut keep_alive = false; + match req.parse(&buf) { + Ok(status) => { + assert!(status.is_complete()); + self.handle_request(conn, req.path.unwrap()).await?; + if should_keep_alive(&req) { + keep_alive = true; + } + } + Err(err) => { + log::warn!("error parsing request: {err:?}"); + } } - Err(err) => { - log::warn!("error parsing request: {err:?}"); + if !keep_alive { + break; } } Ok(()) @@ -228,6 +237,27 @@ fn is_request_complete(buf: &[u8]) -> Result { req.parse(buf).map(|status| status.is_complete()) } +fn should_keep_alive(req: &httparse::Request) -> bool { + let version = req.version.unwrap(); + let default = match version { + 0 => false, + 1 => true, + _ => panic!(), + }; + for header in req.headers.iter() { + if header.name.to_lowercase() == "Connection" { + if header.value == b"close" { + return false; + } + if header.value == b"keep-alive" { + return true; + } + panic!(); + } + } + default +} + fn content_type_from_name(name: &str) -> &'static str { for (ext, ty) in MIME_ASSOCS { if ext.is_suffix_of(name) {