diff --git a/examples/tls/http.rs b/examples/tls/http.rs index 82c6e52..d785d25 100644 --- a/examples/tls/http.rs +++ b/examples/tls/http.rs @@ -1,5 +1,5 @@ -use std::fs; -use std::io::{Read, Write}; +use std::fs::OpenOptions; +use std::io::{self, ErrorKind, Read, Write}; use std::os::unix::net::UnixStream; use std::path::PathBuf; @@ -7,11 +7,15 @@ pub(super) fn handler(mut stream: UnixStream) -> i32 { println!("entered http handler"); let mut buf = Vec::new(); - loop { - let buf_len = buf.len(); - buf.resize_with(buf_len + 1024, Default::default); + let mut buf_len = 0; - if stream.read(&mut buf[buf_len..]).unwrap() == 0 { + loop { + buf.resize_with(buf_len + 4096, Default::default); + + let read_bytes = stream.read(&mut buf[buf_len..]).unwrap(); + buf_len += read_bytes; + + if read_bytes == 0 { break; } @@ -29,33 +33,53 @@ pub(super) fn handler(mut stream: UnixStream) -> i32 { req.path }; - let status_line = if filename.is_some() { - "HTTP/1.1 200 OK" - } else { - "HTTP/1.1 404 NOT FOUND" - }; + if let Some(filename) = filename { + if try_serve_file(&mut stream, filename).unwrap() { + return exitcode::OK; + } + } - let contents = if let Some(filename) = filename { - fs::read_to_string( - PathBuf::from("/var/www/html/") - .join(filename.strip_prefix('/').unwrap_or(filename)), - ) - .unwrap() - } else { - "content not found\n".to_string() - }; + let status_line = "HTTP/1.1 404 NOT FOUND"; + let contents = "file not found\n"; - let response_header = format!( - "{}\r\nContent-Length: {}\r\n\r\n", + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", status_line, contents.len(), + contents ); - stream.write_all(response_header.as_bytes()).unwrap(); - stream.write_all(contents.as_bytes()).unwrap(); - + stream.write_all(response.as_bytes()).unwrap(); break; } exitcode::OK } + +fn try_serve_file(stream: &mut impl io::Write, filename: &str) -> io::Result { + let mut fd = match OpenOptions::new() + .read(true) + .open(PathBuf::from("/var/www/html/").join(filename.strip_prefix('/').unwrap_or(filename))) + { + Ok(fd) => fd, + Err(e) => { + if e.kind() == ErrorKind::NotFound { + return Ok(false); + } + return Err(e); + } + }; + + let status_line = "HTTP/1.1 200 OK"; + + let response_header = format!( + "{}\r\nContent-Length: {}\r\n\r\n", + status_line, + fd.metadata()?.len(), + ); + + stream.write_all(response_header.as_bytes())?; + io::copy(&mut fd, stream)?; + + Ok(true) +} diff --git a/examples/tls/tls.rs b/examples/tls/tls.rs index 39cae5c..962c435 100644 --- a/examples/tls/tls.rs +++ b/examples/tls/tls.rs @@ -56,6 +56,9 @@ pub(crate) fn handler( } } + tls_conn.send_close_notify(); + tls_conn.write_tls(&mut stream).unwrap(); + exitcode::OK }