diff --git a/CHANGELOG.md b/CHANGELOG.md index 00e85d6..649373b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed * Agate now requires the use of SNI by any connecting client. +* All log lines are in the same format now: + `: "" "" [error:]` + If the connection could not be established correctly (e.g. because of TLS errors), the status code `00` is used. +* Messages from modules other than Agate itself are not logged by default. ## [2.5.3] - 2021-02-27 Thank you to @littleli and @06kellyjac for contributing to this release. diff --git a/Cargo.lock b/Cargo.lock index df4706b..065faae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,9 +178,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" +checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" [[package]] name = "log" @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" [[package]] name = "percent-encoding" @@ -275,9 +275,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" +checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" [[package]] name = "proc-macro2" @@ -354,9 +354,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "syn" -version = "1.0.60" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" +checksum = "123a78a3596b24fee53a6464ce52d8ecbf62241e6294c7e7fe12086cd161f512" dependencies = [ "proc-macro2", "quote", diff --git a/README.md b/README.md index 22bdeb1..7fb6e7a 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,16 @@ Using a directory named just `.` causes undefined behaviour as this would have t The files for a certificate/key pair have to be named `cert.pem` and `key.rsa` respectively. The certificate has to be a X.509 certificate in a PEM file and has to include a subject alt name of the domain name. The private key has to be in PKCS#8 format. For an example of how to create such certificates see Installation and Setup, step 2. +## Logging + +All requests will be logged using this format: +``` +: "" ""[ error:] +``` +The "error:" part will only be logged if an error occurred. This should only be used for informative purposes as the status code should provide the information that an error occurred. If the error consisted in the connection not being established (e.g. because of TLS errors), the status code `00` will be used. + +There are some lines apart from these that might occur in logs depending on the selected log level. For example the initial "Listening on..." line or information about listing a particular directory. + [Gemini]: https://gemini.circumlunar.space/ [Rust]: https://www.rust-lang.org/ [home]: gemini://qwertqwefsday.eu/agate.gmi diff --git a/src/main.rs b/src/main.rs index f60ac80..a8706fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,10 @@ use { fn main() -> Result { if !ARGS.silent { env_logger::Builder::new() - .filter_level(log::LevelFilter::Info) + // turn off logging for other modules + .filter_level(log::LevelFilter::Off) + // turn on logging for agate + .filter_module("agate", log::LevelFilter::Info) .parse_default_env() .init(); } @@ -230,7 +233,8 @@ impl RequestHandle { log_line, metadata, }), - Err(e) => Err(format!("{} error:{}", log_line, e)), + // use nonexistent status code 00 if connection was not established + Err(e) => Err(format!("{} \"\" 00 \"TLS error\" error:{}", log_line, e)), } } @@ -263,22 +267,31 @@ impl RequestHandle { let mut len = 0; // Read until CRLF, end-of-stream, or there's no buffer space left. - loop { - let bytes_read = self - .stream - .read(buf) - .await - .or(Err((59, "Request ended unexpectedly")))?; + // + // Since neither CR nor LF can be part of a URI according to + // ISOC-RFC 3986, we could use BufRead::read_line here, but that does + // not allow us to cap the number of read bytes at 1024+2. + let result = loop { + let bytes_read = if let Ok(read) = self.stream.read(buf).await { + read + } else { + break Err((59, "Request ended unexpectedly")); + }; len += bytes_read; if request[..len].ends_with(b"\r\n") { - break; + break Ok(()); } else if bytes_read == 0 { - return Err((59, "Request ended unexpectedly")); + break Err((59, "Request ended unexpectedly")); } buf = &mut request[len..]; } - let request = - std::str::from_utf8(&request[..len - 2]).or(Err((59, "Non-UTF-8 request")))?; + .and_then(|()| std::str::from_utf8(&request[..len - 2]).or(Err((59, "Non-UTF-8 request")))); + + let request = result.map_err(|e| { + // write empty request to log line for uniformity + write!(self.log_line, " \"\"").unwrap(); + e + })?; // log literal request (might be different from or not an actual URL) write!(self.log_line, " \"{}\"", request).unwrap();