diff --git a/tests/data/cert_missing/key.rsa b/tests/data/cert_missing/key.rsa new file mode 100644 index 0000000..a713c8e --- /dev/null +++ b/tests/data/cert_missing/key.rsa @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQD7f6oYIWWsoyrI +KXu47tAn4gtnH3izCVzFo7VWjamVq7+ssWSw1Ob0R5PmR+i+ATxQhfK7BBZk6jE6 +i5pffS3dJS3WqEza0nD5uSA34zTYtJeLrsBuOoldZ4mz7JAvrhFV0zdzXdCjDoQG +qQ49JWIhI22nT0Yq58qB49bqm1vx+TajXIDuKdCJwJfthF/9sXirmqM4GsOOzAMf +xbU3lWfxdU1rXJ0tBlZSH/b31ZnuNCAuAgWIn1Ev2qG2X0WVK83fJ5GefLcBfhuT +4jrrq+aV6oAHznv1AJPvBwYhVq09fvVvTFnFrIJkc3NxZMjidkjYI7lvhPzwX2rO +0zw3MEL8680pU8CJOsXAyeXGDeipt70S+p6nZS3+floqOSB5YMdQjntWgBYkR89Y +8q4mEg+eaiR/lFHOOoZreKe+K+djMPYmdrRExQ18DcKNWl239zj/n2QpTdnzjy7N +kuvDZyZf4pmm/0u4Kd9So6cSybCGjGtlpmpvzC4Xuebto/A7zlJeIghl2mmbo3VM +hlM44nQekO61mIqz2dkqgGgf7kqQKSvvo/Rj5u8D4N3FnRXQm/JqvlCyQlpzeFuk +7vFJz1yA1fK3CxfuK6xuclMhjo2vgNCwaiBFjb/eAnrM+/btUfKTGXIx4nedErls +TuTqukJRCOulVdv0ZVsVnW6/0t4h+QIDAQABAoICAF7c+LvBXSiRI0H8474N1lY0 +3Tg4lr5xeZzS80OCi8T404PAJcrNg5AAr7jcxt1keeulmrkQAaJu88Kxhbke7n3L +2E5vjQ288wA+4/gwq25SMBdwAwWQ7t9cfoRvZrOVZNSKpw/NAzV99C7O9Z/6ydjW +FDZXoI/ufmQgHKDBmRzcc8+KxNcQzqgnDSd6FvsKRgn0ejxfXAQwz7zcRk6A/IQH +SvyEIoUpLsYraGxzFWzUHI8+E/hEn8r9HKI9rXFm5HCX7EVrpVvaxWwymSbr4D4M +Bd7r87WmUiaG77kDiLT5fnpMwk/dkhFxusm6ykshcriUQQ3fi8jfNNpusvfeLGWa +4IcwkWPGd5EWNjM1eqeCfh79FAdJe8sEYf2pAkT8LVNT23J/jsL5dsLy3VFQ6svV +NReDnaWBxw92Xh/zqmo7L7/zGaLKXJPSQYHlnDUuYBOxoKhnzDY7P1XWk3STKDan +1rwSelBb/9Z/KGgeg92YlHrYOspw7JaCaYbzpsi8vCS+ZrTrbQ0UoHUAVKgRkTsG +pgUvlbX+RL1+nweGmjenDYEGn5MsPhoKgJFhJLgqqdo3ZTruEazU9Q5xLZDhWz82 +hxJKm3WFAqIL8Q5Wd22z7+DjS9YLuHYB+o9dSbqR0UOiyvYb+eL8gkvPtlvnE0yC +iWl1SDg25iWmbQz1X7EBAoIBAQD+AImpGYgRhIglB2MSz9LPLEC9lGZX6ZznfS91 +1tc5iPcqqKQ3VBCJWnCNOTh5RXlau0s/+vE6zKytSiWrzgkTBMkd18xPTy6c5O4J +XUCArZHx+GoXooOkSPxcLM1IGElTpHT/4Ua4KrGzMpdI8khHLDfiXeUL9mlgYrho +rLjArOo/1pBURYfNSay+bmTB/CzoS+0EXYc6fCNhNvE8fOkCCdPiwrpUjuZyYzmR +pkU1XVOzgqLEqBadywXfp6NeyRBVWO9OxWcJ63smwWCJz/KcTYhBAG5TH/959O6z +115Q7tst+amhBZLgOvHnYJ1S/dK1fU4PDRAm6dEW7kqeFd11AoIBAQD9ehX2SVdo +RHT69H4ItMpYWiBUtAwOEE5d5RPVrjtFtSh/V1pZ+jjGTyqTL5+885o1A6q2Nkrc +d8kYG5VVaGkjJEibCk6px0TWN2Lt73Q0ixNbBmcjxsjRp4EfHvMR/5IqvSZNuUjy +8j3dFHgeB6/PFY283Z9XbMrcFZeEsL4rljF+/XCX2ZeMIUBU93cbZr80o1LgcwpI +Qw61g6Kfjwm6jJEws3doxcmAGSkbR4PzZyRI8lLlIEWWccRG1k34J7s2eDfk8O6F +awv/pgcyFQQwl3zMXmCDNvdHkHV7EDu0gZc8WEuKBTA9tOfokkQmp4rbvMGqtJJm +OfYFZZR/YU31AoIBAHUulFPiRocmaJUEum1kWbJgjSGpRCoMyel2NJ4d1r9hc/5H +PTOVYeesRL6yhl5Uce8s90N2JzJkWMm9qnF/pWoTzCErfMOeGTgi2bqSPf7flLRY +UcHDpQ326g4wUSiQo8ul1KB0MucmM0Mj9O2fcT78pG+Xt+Lz9JuWD9Oi0714SL3Y +5E8soMFR2xMj5PIlwCYPWTKpX4jY2o2wBk1Mp0bcd9dm1QXLw39ETbvnRIihHMt1 +Wlh137E+h+At+83v3swxMn5Zzfain/c6QapyuE/p6RFr/Hn3Cisel716f7XA7Hdi +diKmaqNuLkn7pbkzBrHaNFf3Q9tgBamZl+0k0z0CggEAAuOgWnVNjL+zAaVFxn2h +DM7CLZT7yjE/Y2yYBEh/HnVJJ+JsAjiK6x+94X2aeYHhURdgm8EUq1ymKyMtWZLe +F+ty9Glyqha+Xx60fvfKwEqRhukUxeCfK1yYaS1mId9i4B/Vzu78uOAv+lQgZl86 +Dsc1HWD9TvbLfSS13GpTUJXerI7g+KofQxah8BX+Ao7yQPxXln1ZMaeqBEGi2eS8 +fKbbhM2W39fZSx9+S3ROObkEPdydO0VZ5bQYQ6JvsxNo298U7AQfA+BLe7d9v4Fj +0dX4MzAkM3qt6N/ppuRxecY8XhC3k7Qpb5qfRhRcuIASYhzNrE9wl7+zYS5eOfF2 +/QKCAQEAyOKjglWIpOul3EIOF2D0O6fkulxLfUya6URok00p3CxFXlFdDXwTzC9R +TNYMVE0WrxnXk1KT7ave4PJRFKMNk/PxbMQbtji9m3mWlZsM2vNNQ9nuWnrfOAha +plI7XBPJ4NNapl/RAFVhu3WVHG4CaYiqWPR3dMBi1/2Uk7EhZjhuJ8/AsJz5v7iO +Nv0ydQX7ZisNwf1eksL7odZjGcm/PNOxdAnFI67DuXo4YvyMjzovhTgm0s4yrecC +OMkrvwvefnzUQKV8m9na8pPG+ZJd518oK8nuk9UMgwsJnCWEVgzVjzRIxv7AElrO +tPwNvAOh6tUMmDlbRt+xdpFmU238jA== +-----END PRIVATE KEY----- diff --git a/tests/data/key_missing/cert.pem b/tests/data/key_missing/cert.pem new file mode 100644 index 0000000..df3fbd8 --- /dev/null +++ b/tests/data/key_missing/cert.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIFCTCCAvGgAwIBAgIUP60wPmdZzVFdc9c1ReFbzcWk9CwwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMTEwODE0MzE1NloXDTMwMTEw +NjE0MzE1NlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA+3+qGCFlrKMqyCl7uO7QJ+ILZx94swlcxaO1Vo2plau/ +rLFksNTm9EeT5kfovgE8UIXyuwQWZOoxOouaX30t3SUt1qhM2tJw+bkgN+M02LSX +i67AbjqJXWeJs+yQL64RVdM3c13Qow6EBqkOPSViISNtp09GKufKgePW6ptb8fk2 +o1yA7inQicCX7YRf/bF4q5qjOBrDjswDH8W1N5Vn8XVNa1ydLQZWUh/299WZ7jQg +LgIFiJ9RL9qhtl9FlSvN3yeRnny3AX4bk+I666vmleqAB8579QCT7wcGIVatPX71 +b0xZxayCZHNzcWTI4nZI2CO5b4T88F9qztM8NzBC/OvNKVPAiTrFwMnlxg3oqbe9 +Evqep2Ut/n5aKjkgeWDHUI57VoAWJEfPWPKuJhIPnmokf5RRzjqGa3invivnYzD2 +Jna0RMUNfA3CjVpdt/c4/59kKU3Z848uzZLrw2cmX+KZpv9LuCnfUqOnEsmwhoxr +ZaZqb8wuF7nm7aPwO85SXiIIZdppm6N1TIZTOOJ0HpDutZiKs9nZKoBoH+5KkCkr +76P0Y+bvA+DdxZ0V0Jvyar5QskJac3hbpO7xSc9cgNXytwsX7iusbnJTIY6Nr4DQ +sGogRY2/3gJ6zPv27VHykxlyMeJ3nRK5bE7k6rpCUQjrpVXb9GVbFZ1uv9LeIfkC +AwEAAaNTMFEwHQYDVR0OBBYEFI7IjwaA0gwpeZXl5x7Knw8i4STDMB8GA1UdIwQY +MBaAFI7IjwaA0gwpeZXl5x7Knw8i4STDMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggIBANQJ+WuQ8UZsk86t7jTS9K2Igit22ImXhdddDHHbBrbdLXoN +g4IXij8mEJqfPyqZhT49S23booihvJOyhT/RgRB6LI/hBuV1vTwARmIRU4WhZAh0 +xIwVCqniDp6Rgf6OEOYgLGk11CEv7vMfPZYbLddDY1HvmSl8l087CLEQ37WRb51M +5Quhsrny441s6aTn8I7c9WY2H/CUmlF8byoLuIl2MpR5bQN17binfsJZPYkKaMyJ +5URM0nCVUEr+o/1znYsQJYa+GSVEsJJ6OyS7TMSoFJlVFslOxbdPzNkdcL6jxpXN +B0rCrC1gTaQynxTOoQ56N8Z74V9xoXNd0ZwaSgEWfeM++YOyk3qgfvhobd0F8rTD +8+dvMN7eI+N8P+S+VCnX9YzrQIZyTwEhHK9fXLlcqoiAhpizgGhlGctiZ1MmpzT2 +aqFmLOCKpcQLyofsSLSFbhV2/w8rJbS1kTlrzwQLzaJvtLVy+ZZdQFP49Vj8Lb7n +3Oos/YeNoGhJoTWX7S2nQBChYMsSUA15+IS7RN0b+cJroHESsqCkbp07M20zhztz +fDWdYFh+o4V2lF9ecnqV7MwTvz9WxpchcUfQgENrJ3dgTn35hsZOMM2anwFWrmG+ +KVyFMhWNnZB1E530Nsu9cNHntqc3sFBdJebrFED9gOFErt5Vou8btjIqPm/Y +-----END CERTIFICATE----- diff --git a/tests/data/multicert/ca_cert.pem b/tests/data/multicert/ca_cert.pem new file mode 100644 index 0000000..7cca683 --- /dev/null +++ b/tests/data/multicert/ca_cert.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIFCzCCAvOgAwIBAgIUIBGuqsV2UiwpjgNTBhsCWSEofMEwDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKZXhhbXBsZSBDQTAeFw0yMTAzMDMxNzI1MjFaFw0zMTAz +MDExNzI1MjFaMBUxEzARBgNVBAMMCmV4YW1wbGUgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDAYjrXvFY9MpJ0Cy9Jte42u9peeUQ+4isGIDmnSAmA +hngVqoDlqvr6mXXU+N0c7jDkLEcs7EySORP/k1rRrAtQPSZeMSVQ47aJirmIlcnb +P9/ivyYv8lyndZCZikOAOz7D1beRV66MX2q1/plnW1QuWHbk83IqNniZcL8QRTWw +EYy8CxNd9UO9TlzF/kuIadNlFEywiQ6pbZiIhPChCtg2vKx/abQukYSGDoQxTIEp +T6uqoHevAMZFMhwhURG5kUX65xQcIDSobvxyziSc3fKW/fxzu/ORkLHBB5T3jcQJ ++BL4pb+hZl7Xe/r4TvfhSpdzu5hoLFAqLWhQUHymMG8kmqJ6Q9lfuQO4A/HuqCQN +cYtEce88uOaF/TPt99qhvg/7V1LXxZ9UNnyc2cQUroT8jx+5NtWBPQvekKSoufxX +4Kv4kdtaPyGRVZcshLQKog6kD49nzlCJhYV9UUiGQMUrzb7H5n+Y2puN87B5oUVY +djNJ65h7y27fKeXfrpvTJ+kqi9A6hrwNR6INTkRJ+l6mnpX0tnTmGmSiChsW+xCF +R2bIl04y4efqYToG3fQk0vzn+rGx57DqnpgDavIYJxsNWzJ4qWWxdN08QV8OsmEo +0u6Ks9+EVv6sHmY+WWsOB+8Jgwa0p2HcQ2nu0KrIDNVxUS29jPA/Iw7g/w95az/X +2wIDAQABo1MwUTAdBgNVHQ4EFgQUtyhzhR/wxqDZlRxR4odCXFhSwtEwHwYDVR0j +BBgwFoAUtyhzhR/wxqDZlRxR4odCXFhSwtEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAZYiHTpAsWvOdqsMa9KhiWgOYAtJ/vERaTkWowxfqpBrx +nC9k5PAU4r5mAa38RX9hbRWEpXA2oEET/txg4a9oHkYPCk8+Nq/K7JwoY32gdsuC +EeAFIFhsfV5aDnoMxEfjOo7erFa89UBLup9bw3VupQ6+9B7UJP5Q1g8aapdcw2Io +nFiof56TNBUNSSJc0ErfBInCQ+T2yIbbyXvsNhbENidlP8nDv9cwHEQewUPbH9/y +k4MqsZVsdrm00m0ZWgdQfZnTgM5/TBp+tTyHJOQqfekPiqob7lPGgakMhkpGHJvu +EnkQJecgHA1/k2ETM4Ja162kbshN8LjLLrXi9aEwDYTW1xFbvK9MrHKcSOTq+FJs +WV3RK1J56pqq3iNJLXkXjSuo6bNIA4fjxJk8scRdsANAYfV9I3pJUY1EB/LvycSo +zCUgpp+tnqT+lgvCZ3aFi/Iajb0TgoNb/xgHo2MJmRNLj6RQlJkLDEYBQTE1iiru +bWZW2jf7LEBM9MwT2+I2AbmCLyPoA04ZT7GH2yeugU1YrxO5Erj6m3JBdwuKIU7g +DJH2DttPIm1ay00tFBapYoODfXwqqIPtYRSAhSxxuWRV1fl5kVgyT2TjEvv9b/8j +SMRrGvo4Ws2H8W8Fcf0EVIywkVxpE2YlzztEWhVJEmltM74slX82QZ2ppWCmepg= +-----END CERTIFICATE----- diff --git a/tests/data/multicert/ca_key.rsa b/tests/data/multicert/ca_key.rsa new file mode 100644 index 0000000..b5fb859 --- /dev/null +++ b/tests/data/multicert/ca_key.rsa @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +uabNtK2No3EmpBOK31TRSIKWx7bFnw== +-----END PRIVATE KEY----- diff --git a/tests/data/multicert/create_certs.sh b/tests/data/multicert/create_certs.sh new file mode 100755 index 0000000..8b5e0e7 --- /dev/null +++ b/tests/data/multicert/create_certs.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +mkdir -p example.com example.org + +# create our own CA so we can use rustls without it complaining about using a +# CA cert as end cert +openssl req -x509 -newkey rsa:4096 -keyout ca_key.rsa -out ca_cert.pem -days 3650 -nodes -subj "/CN=example CA" + +for domain in "example.com" "example.org" +do +openssl genpkey -out $domain/key.rsa -algorithm RSA -pkeyopt rsa_keygen_bits:4096 + +cat >openssl.conf < SocketAddr { struct Server { server: std::process::Child, buf: u8, + // is set when output is collected by stop() + output: Option>, } impl Server { @@ -44,17 +47,20 @@ impl Server { Self { server, buf: buffer[0], + output: None, } } -} -impl Drop for Server { - fn drop(&mut self) { - // try to stop the server again - match self.server.try_wait() { - Err(e) => panic!("cannot access orchestrated program: {:?}", e), + pub fn stop(&mut self) -> Result<(), String> { + // try to stop the server + if let Some(output) = self.output.clone() { + return output; + } + + self.output = Some(match self.server.try_wait() { + Err(e) => Err(format!("cannot access orchestrated program: {:?}", e)), // everything fine, still running as expected, kill it now - Ok(None) => self.server.kill().unwrap(), + Ok(None) => Ok(self.server.kill().unwrap()), Ok(Some(_)) => { // forward stderr so we have a chance to understand the problem let buffer = std::iter::once(Ok(self.buf)) @@ -62,23 +68,37 @@ impl Drop for Server { .collect::, _>>() .unwrap(); - eprintln!("{}", String::from_utf8_lossy(&buffer)); - // make the test fail - panic!("program had crashed"); + Err(String::from_utf8_lossy(&buffer).into_owned()) } + }); + return self.output.clone().unwrap(); + } +} + +impl Drop for Server { + fn drop(&mut self) { + if self.output.is_none() && !std::thread::panicking() { + // a potential error message was not yet handled + self.stop().unwrap(); + } else if self.output.is_some() { + // error was already handled, ignore it + self.stop().unwrap_or(()); + } else { + // we are panicking and a potential error was not handled + self.stop().unwrap_or_else(|e| eprintln!("{:?}", e)); } } } fn get(args: &[&str], addr: SocketAddr, url: &str) -> Result { - let _server = Server::new(args); + let mut server = Server::new(args); // actually perform the request let page = tokio::runtime::Runtime::new() .unwrap() .block_on(async { Page::fetch_from(&Url::parse(url).unwrap(), addr, None).await }); - page + server.stop().map_err(|e| anyhow!(e)).and(page) } #[test] @@ -298,65 +318,161 @@ fn explicit_tls_version() { tls.read(&mut buf).unwrap(); } -#[test] -/// - simple vhosts are enabled when multiple hostnames are supplied -/// - the vhosts access the correct files -fn vhosts_example_com() { - let page = get( - &[ - "--addr", - "[::]:1977", - "--hostname", - "example.com", - "--hostname", - "example.org", - ], - addr(1977), - "gemini://example.com/", - ) - .expect("could not get page"); +mod vhosts { + use super::*; - assert_eq!(page.header.status, Status::Success); - - assert_eq!( - page.body, - Some( - std::fs::read_to_string(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/data/content/example.com/index.gmi" - )) - .unwrap() + #[test] + /// - simple vhosts are enabled when multiple hostnames are supplied + /// - the vhosts access the correct files + fn example_com() { + let page = get( + &[ + "--addr", + "[::]:1977", + "--hostname", + "example.com", + "--hostname", + "example.org", + ], + addr(1977), + "gemini://example.com/", ) - ); + .expect("could not get page"); + + assert_eq!(page.header.status, Status::Success); + + assert_eq!( + page.body, + Some( + std::fs::read_to_string(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/data/content/example.com/index.gmi" + )) + .unwrap() + ) + ); + } + + #[test] + /// - the vhosts access the correct files + fn example_org() { + let page = get( + &[ + "--addr", + "[::]:1978", + "--hostname", + "example.com", + "--hostname", + "example.org", + ], + addr(1978), + "gemini://example.org/", + ) + .expect("could not get page"); + + assert_eq!(page.header.status, Status::Success); + + assert_eq!( + page.body, + Some( + std::fs::read_to_string(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/data/content/example.org/index.gmi" + )) + .unwrap() + ) + ); + } } -#[test] -/// - the vhosts access the correct files -fn vhosts_example_org() { - let page = get( - &[ - "--addr", - "[::]:1978", - "--hostname", - "example.com", - "--hostname", - "example.org", - ], - addr(1978), - "gemini://example.org/", - ) - .expect("could not get page"); +mod multicert { + use super::*; - assert_eq!(page.header.status, Status::Success); + #[test] + fn cert_missing() { + let mut server = Server::new(&["--addr", "[::]:1979", "--certs", "cert_missing"]); - assert_eq!( - page.body, - Some( - std::fs::read_to_string(concat!( + // wait for the server to stop, it should crash + let _ = server.server.wait(); + + assert!(server + .stop() + .unwrap_err() + .to_string() + .contains("certificate file for fallback is missing")); + } + + #[test] + fn key_missing() { + let mut server = Server::new(&["--addr", "[::]:1980", "--certs", "key_missing"]); + + // wait for the server to stop, it should crash + let _ = server.server.wait(); + + assert!(server + .stop() + .unwrap_err() + .to_string() + .contains("key file for fallback is missing")); + } + + #[test] + fn example_com() { + use rustls::ClientSession; + use std::io::{Cursor, Write}; + use std::net::TcpStream; + + let mut server = Server::new(&["--addr", "[::]:1981", "--certs", "multicert"]); + + let mut config = rustls::ClientConfig::new(); + config + .root_store + .add_pem_file(&mut Cursor::new(include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), - "/tests/data/content/example.org/index.gmi" - )) - .unwrap() - ) - ); + "/tests/data/multicert/ca_cert.pem" + )))) + .unwrap(); + + let dns_name = webpki::DNSNameRef::try_from_ascii_str("example.com").unwrap(); + let mut session = ClientSession::new(&std::sync::Arc::new(config), dns_name); + let mut tcp = TcpStream::connect(addr(1981)).unwrap(); + let mut tls = rustls::Stream::new(&mut session, &mut tcp); + + write!(tls, "gemini://example.com/\r\n").unwrap(); + + let mut buf = [0; 10]; + tls.read(&mut buf).unwrap(); + + server.stop().unwrap() + } + + #[test] + fn example_org() { + use rustls::ClientSession; + use std::io::{Cursor, Write}; + use std::net::TcpStream; + + let mut server = Server::new(&["--addr", "[::]:1982", "--certs", "multicert"]); + + let mut config = rustls::ClientConfig::new(); + config + .root_store + .add_pem_file(&mut Cursor::new(include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/data/multicert/ca_cert.pem" + )))) + .unwrap(); + + let dns_name = webpki::DNSNameRef::try_from_ascii_str("example.org").unwrap(); + let mut session = ClientSession::new(&std::sync::Arc::new(config), dns_name); + let mut tcp = TcpStream::connect(addr(1982)).unwrap(); + let mut tls = rustls::Stream::new(&mut session, &mut tcp); + + write!(tls, "gemini://example.org/\r\n").unwrap(); + + let mut buf = [0; 10]; + tls.read(&mut buf).unwrap(); + + server.stop().unwrap() + } }