char/serve-esm

git clone https://git.t4t.associates/char/serve-esm

Charlotte SomRewrite serve-esm in Rust using Tower and Hypere06f6b7

main
1.7 KiB55 linesraw
1use std::{
2    io::{BufRead, BufReader, Read, Write},
3    net::TcpStream,
4    path::Path,
5    process::{Child, Command, Stdio},
6};
7
8struct Server(Child);
9
10impl Drop for Server {
11    fn drop(&mut self) {
12        let _ = self.0.kill();
13        let _ = self.0.wait();
14    }
15}
16
17fn start(root: &Path, socket: Option<&Path>) -> (Server, String) {
18    let mut command = Command::new(env!("CARGO_BIN_EXE_serve-esm"));
19    command.env("TARGET_DIR", root).env_remove("SOCKET_PATH");
20    command.env("LISTEN", "127.0.0.1:0").stderr(Stdio::piped());
21    if let Some(socket) = socket {
22        command.env("SOCKET_PATH", socket);
23    }
24    let mut server = Server(command.spawn().unwrap());
25    let mut line = String::new();
26    BufReader::new(server.0.stderr.take().unwrap())
27        .read_line(&mut line)
28        .unwrap();
29    let address = line
30        .trim()
31        .strip_prefix("listening on ")
32        .expect(&line)
33        .to_owned();
34    (server, address)
35}
36
37fn request(mut stream: impl Read + Write) {
38    stream
39        .write_all(b"GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n")
40        .unwrap();
41    let mut response = String::new();
42    stream.read_to_string(&mut response).unwrap();
43    assert!(response.starts_with("HTTP/1.1 404"), "{response}");
44    assert!(response.ends_with("\r\n\r\nnot found"), "{response}");
45}
46
47#[test]
48fn tcp_and_unix_listeners() {
49    let root = tempfile::tempdir().unwrap();
50    let (_server, address) = start(root.path(), None);
51    request(TcpStream::connect(address.strip_prefix("http://").unwrap()).unwrap());
52    let socket = root.path().join("serve-esm.sock");
53    let (_unix_server, _) = start(root.path(), Some(&socket));
54    request(std::os::unix::net::UnixStream::connect(socket).unwrap());
55}