diff --git a/command/src/certificate.rs b/command/src/certificate.rs index 600c81b74..0538f2b25 100644 --- a/command/src/certificate.rs +++ b/command/src/certificate.rs @@ -10,7 +10,7 @@ use crate::proto::command::TlsVersion; #[derive(thiserror::Error, Debug)] pub enum CertificateError { #[error("Could not parse PEM certificate from bytes: {0}")] - ParseError(String), + InvalidCertificate(String), } #[derive(Debug)] @@ -104,7 +104,7 @@ impl<'de> serde::Deserialize<'de> for Fingerprint { pub fn calculate_fingerprint(certificate: &[u8]) -> Result, CertificateError> { let parsed_certificate = parse(certificate) - .map_err(|parse_error| CertificateError::ParseError(parse_error.to_string()))?; + .map_err(|parse_error| CertificateError::InvalidCertificate(parse_error.to_string()))?; let fingerprint = Sha256::digest(parsed_certificate.contents()) .iter() .cloned() diff --git a/command/src/channel.rs b/command/src/channel.rs index 4894cafc0..f37c21ea7 100644 --- a/command/src/channel.rs +++ b/command/src/channel.rs @@ -21,7 +21,7 @@ use crate::{buffer::growable::Buffer, ready::Ready}; #[derive(thiserror::Error, Debug)] pub enum ChannelError { #[error("io read error")] - IoError(std::io::Error), + Read(std::io::Error), #[error("no byte written on the channel")] NoByteWritten, #[error("no byte left to read on the channel")] @@ -29,23 +29,21 @@ pub enum ChannelError { #[error("message too large for the capacity of the back fuffer ({0}. Consider increasing the back buffer size")] MessageTooLarge(usize), #[error("channel could not write on the back buffer")] - WriteError(std::io::Error), - #[error("channel buffer is full, cannot grow more, ignoring")] + Write(std::io::Error), + #[error("channel buffer is full, cannot grow more")] BufferFull, #[error("Timeout is reached: {0:?}")] TimeoutReached(Duration), #[error("Could not read anything on the channel")] NothingRead, - #[error("invalid utf-8 encoding in command message, ignoring: {0}")] - Utf8Error(String), + #[error("invalid char set in command message, ignoring: {0}")] + InvalidCharSet(String), #[error("Error deserializing message")] - SerdeError(serde_json::error::Error), + Serde(serde_json::error::Error), #[error("Could not change the blocking status ef the unix stream with file descriptor {fd}: {error}")] - BlockingStatusError { fd: i32, error: String }, - #[error("Connection error, continuing")] - ConnectionError, - #[error("Could not connect to socket with path {path}: {error}")] - FromPathError { path: String, error: String }, + BlockingStatus { fd: i32, error: String }, + #[error("Connection error: {0:?}")] + Connection(Option), } /// A wrapper around unix socket using the mio crate. @@ -69,11 +67,8 @@ impl Channel { buffer_size: usize, max_buffer_size: usize, ) -> Result, ChannelError> { - let unix_stream = - MioUnixStream::connect(path).map_err(|error| ChannelError::FromPathError { - path: path.to_owned(), - error: error.to_string(), - })?; + let unix_stream = MioUnixStream::connect(path) + .map_err(|io_error| ChannelError::Connection(Some(io_error)))?; Ok(Channel::new(unix_stream, buffer_size, max_buffer_size)) } @@ -113,12 +108,12 @@ impl Channel { unsafe { let fd = self.sock.as_raw_fd(); let stream = StdUnixStream::from_raw_fd(fd); - stream.set_nonblocking(nonblocking).map_err(|error| { - ChannelError::BlockingStatusError { + stream + .set_nonblocking(nonblocking) + .map_err(|error| ChannelError::BlockingStatus { fd, error: error.to_string(), - } - })?; + })?; let _fd = stream.into_raw_fd(); } self.blocking = !nonblocking; @@ -168,7 +163,7 @@ impl Channel { /// Handles readability by filling the front buffer with the socket data. pub fn readable(&mut self) -> Result { if !(self.interest & self.readiness).is_readable() { - return Err(ChannelError::ConnectionError); + return Err(ChannelError::Connection(None)); } let mut count = 0usize; @@ -191,10 +186,10 @@ impl Channel { self.readiness.remove(Ready::READABLE); break; } - _other_error => { + _ => { self.interest = Ready::EMPTY; self.readiness = Ready::EMPTY; - return Err(ChannelError::IoError(read_error)); + return Err(ChannelError::Read(read_error)); } }, Ok(bytes_read) => { @@ -210,7 +205,7 @@ impl Channel { /// Handles writability by writing the content of the back buffer onto the socket pub fn writable(&mut self) -> Result { if !(self.interest & self.readiness).is_writable() { - return Err(ChannelError::ConnectionError); + return Err(ChannelError::Connection(None)); } let mut count = 0usize; @@ -236,10 +231,10 @@ impl Channel { self.readiness.remove(Ready::WRITABLE); break; } - _other_error => { + _ => { self.interest = Ready::EMPTY; self.readiness = Ready::EMPTY; - return Err(ChannelError::IoError(write_error)); + return Err(ChannelError::Read(write_error)); } }, } @@ -314,7 +309,7 @@ impl Channel { match self .sock .read(self.front_buf.space()) - .map_err(ChannelError::IoError)? + .map_err(ChannelError::Read)? { 0 => return Err(ChannelError::NoByteToRead), bytes_read => self.front_buf.fill(bytes_read), @@ -326,9 +321,9 @@ impl Channel { fn read_and_parse_from_front_buffer(&mut self, position: usize) -> Result { let utf8_str = from_utf8(&self.front_buf.data()[..position]) - .map_err(|from_error| ChannelError::Utf8Error(from_error.to_string()))?; + .map_err(|from_error| ChannelError::InvalidCharSet(from_error.to_string()))?; - let json_parsed = serde_json::from_str(utf8_str).map_err(ChannelError::SerdeError)?; + let json_parsed = serde_json::from_str(utf8_str).map_err(ChannelError::Serde)?; self.front_buf.consume(position + 1); Ok(json_parsed) @@ -370,13 +365,11 @@ impl Channel { self.back_buf.grow(new_length); } - self.back_buf - .write(&message) - .map_err(ChannelError::WriteError)?; + self.back_buf.write(&message).map_err(ChannelError::Write)?; self.back_buf .write(&b"\0"[..]) - .map_err(ChannelError::WriteError)?; + .map_err(ChannelError::Write)?; self.interest.insert(Ready::WRITABLE); @@ -406,13 +399,11 @@ impl Channel { self.back_buf.grow(new_len); } - self.back_buf - .write(&message) - .map_err(ChannelError::WriteError)?; + self.back_buf.write(&message).map_err(ChannelError::Write)?; self.back_buf .write(&b"\0"[..]) - .map_err(ChannelError::WriteError)?; + .map_err(ChannelError::Write)?; loop { let size = self.back_buf.available_data(); @@ -440,7 +431,7 @@ impl Result<(Channel, Channel), ChannelError> { - let (command, proxy) = MioUnixStream::pair().map_err(ChannelError::IoError)?; + let (command, proxy) = MioUnixStream::pair().map_err(ChannelError::Read)?; let proxy_channel = Channel::new(proxy, buffer_size, max_buffer_size); let mut command_channel = Channel::new(command, buffer_size, max_buffer_size); command_channel.blocking()?; @@ -452,7 +443,7 @@ impl Result<(Channel, Channel), ChannelError> { - let (command, proxy) = MioUnixStream::pair().map_err(ChannelError::IoError)?; + let (command, proxy) = MioUnixStream::pair().map_err(ChannelError::Read)?; let proxy_channel = Channel::new(proxy, buffer_size, max_buffer_size); let command_channel = Channel::new(command, buffer_size, max_buffer_size); Ok((command_channel, proxy_channel)) diff --git a/command/src/config.rs b/command/src/config.rs index bd1ff8200..f957ecbc5 100644 --- a/command/src/config.rs +++ b/command/src/config.rs @@ -68,6 +68,7 @@ use crate::{ RequestHttpFrontend, RequestTcpFrontend, RulePosition, TcpListenerConfig, TlsVersion, }, request::WorkerRequest, + ObjectKind, }; /// provides all supported cipher suites exported by Rustls TLS @@ -154,38 +155,49 @@ pub const DEFAULT_COMMAND_BUFFER_SIZE: usize = 1_000_000; /// maximum size of the buffer for the channels, in bytes. (2 MB) pub const DEFAULT_MAX_COMMAND_BUFFER_SIZE: usize = 2_000_000; +#[derive(Debug)] +pub enum IncompatibilityKind { + PublicAddress, + ProxyProtocol, +} + +#[derive(Debug)] +pub enum MissingKind { + Field(String), + Protocol, + SavedState, +} + #[derive(thiserror::Error, Debug)] pub enum ConfigError { #[error("Could not parse socket address {address}: {error}")] - AddressParsingError { address: String, error: String }, + ParseSocketAddress { address: String, error: String }, #[error("env path not found: {0}")] - EnvError(String), + Env(String), #[error("Could not open file {path_to_open}: {io_error}")] - FileOpenError { + FileOpen { path_to_open: String, - io_error: String, + io_error: std::io::Error, }, #[error("Could not read file {path_to_read}: {io_error}")] - FileReadError { + FileRead { path_to_read: String, - io_error: String, + io_error: std::io::Error, + }, + #[error("the field {kind:?} of {object:?} with id or address {id} is incompatible with the rest of the options")] + Incompatible { + kind: IncompatibilityKind, + object: ObjectKind, + id: String, }, - #[error("the listener on {0} has incompatible options: it cannot use the expect proxy protocol and have a public_address field at the same time",)] - IncompatiblePublicAddress(String), - #[error("all the listeners for cluster {0} should have the same expect_proxy option")] - InconsistentExpectProxyOption(String), #[error("Invalid '{0}' field for a TCP frontend")] - InvalidField(String), + InvalidFrontendConfig(String), #[error("invalid path {0:?}")] InvalidPath(PathBuf), #[error("listening address {0} is already used in the configuration")] ListenerAddressAlreadyInUse(String), - #[error("Invalid '{0}' field to create a frontend")] - MissingField(String), - #[error("missing field 'protocol' to create a listener")] - MissingProtocol, - #[error("cannot activate automatic state save if the 'saved_state` option is not set")] - MissingSavedState, + #[error("missing {0:?}")] + Missing(MissingKind), #[error("could not get parent directory for file {0}")] NoFileParent(String), #[error("Could not get the path of the saved state")] @@ -193,7 +205,7 @@ pub enum ConfigError { #[error("Can not determine path to sozu socket: {0}")] SocketPathError(String), #[error("toml decoding error: {0}")] - TomlDeserialization(String), + DeserializeToml(String), #[error("Can not set this frontend on a {0:?} listener")] WrongFrontendProtocol(ListenerProtocol), #[error("Can not build a {expected:?} listener from a {found:?} config")] @@ -586,7 +598,7 @@ impl ListenerBuilder { fn parse_socket_address(address: &str) -> Result { address .parse::() - .map_err(|parse_error| ConfigError::AddressParsingError { + .map_err(|parse_error| ConfigError::ParseSocketAddress { error: parse_error.to_string(), address: address.to_owned(), }) @@ -594,15 +606,15 @@ fn parse_socket_address(address: &str) -> Result { fn open_and_read_file(path: &str) -> Result { let mut content = String::new(); - let mut file = File::open(path).map_err(|io_error| ConfigError::FileOpenError { + let mut file = File::open(path).map_err(|io_error| ConfigError::FileOpen { path_to_open: path.to_owned(), - io_error: io_error.to_string(), + io_error, })?; file.read_to_string(&mut content) - .map_err(|io_error| ConfigError::FileReadError { + .map_err(|io_error| ConfigError::FileRead { path_to_read: path.to_owned(), - io_error: io_error.to_string(), + io_error, })?; Ok(content) @@ -650,19 +662,25 @@ pub struct FileClusterFrontendConfig { impl FileClusterFrontendConfig { pub fn to_tcp_front(&self) -> Result { if self.hostname.is_some() { - return Err(ConfigError::InvalidField("hostname".to_string())); + return Err(ConfigError::InvalidFrontendConfig("hostname".to_string())); } if self.path.is_some() { - return Err(ConfigError::InvalidField("path_prefix".to_string())); + return Err(ConfigError::InvalidFrontendConfig( + "path_prefix".to_string(), + )); } if self.certificate.is_some() { - return Err(ConfigError::InvalidField("certificate".to_string())); + return Err(ConfigError::InvalidFrontendConfig( + "certificate".to_string(), + )); } if self.hostname.is_some() { - return Err(ConfigError::InvalidField("hostname".to_string())); + return Err(ConfigError::InvalidFrontendConfig("hostname".to_string())); } if self.certificate_chain.is_some() { - return Err(ConfigError::InvalidField("certificate_chain".to_string())); + return Err(ConfigError::InvalidFrontendConfig( + "certificate_chain".to_string(), + )); } Ok(TcpFrontendConfig { @@ -674,7 +692,11 @@ impl FileClusterFrontendConfig { pub fn to_http_front(&self, _cluster_id: &str) -> Result { let hostname = match &self.hostname { Some(hostname) => hostname.to_owned(), - None => return Err(ConfigError::MissingField("hostname".to_string())), + None => { + return Err(ConfigError::Missing(MissingKind::Field( + "hostname".to_string(), + ))) + } }; let key_opt = match self.key.as_ref() { @@ -781,9 +803,11 @@ impl FileClusterConfig { match has_expect_proxy { Some(true) => {} Some(false) => { - return Err(ConfigError::InconsistentExpectProxyOption( - cluster_id.to_owned(), - )) + return Err(ConfigError::Incompatible { + object: ObjectKind::Cluster, + id: cluster_id.to_owned(), + kind: IncompatibilityKind::ProxyProtocol, + }) } None => has_expect_proxy = Some(true), } @@ -791,9 +815,11 @@ impl FileClusterConfig { match has_expect_proxy { Some(false) => {} Some(true) => { - return Err(ConfigError::InconsistentExpectProxyOption( - cluster_id.to_owned(), - )) + return Err(ConfigError::Incompatible { + object: ObjectKind::Cluster, + id: cluster_id.to_owned(), + kind: IncompatibilityKind::ProxyProtocol, + }) } None => has_expect_proxy = Some(false), } @@ -1108,7 +1134,7 @@ impl FileConfig { Ok(config) => config, Err(e) => { display_toml_error(&data, &e); - return Err(ConfigError::TomlDeserialization(e.to_string())); + return Err(ConfigError::DeserializeToml(e.to_string())); } }; @@ -1257,7 +1283,9 @@ impl ConfigBuilder { )); } - let protocol = listener.protocol.ok_or(ConfigError::MissingProtocol)?; + let protocol = listener + .protocol + .ok_or(ConfigError::Missing(MissingKind::Protocol))?; self.known_addresses.insert(address, protocol); if listener.expect_proxy == Some(true) { @@ -1265,9 +1293,11 @@ impl ConfigBuilder { } if listener.public_address.is_some() && listener.expect_proxy == Some(true) { - return Err(ConfigError::IncompatiblePublicAddress( - listener.address.to_string(), - )); + return Err(ConfigError::Incompatible { + object: ObjectKind::Listener, + id: listener.address.to_owned(), + kind: IncompatibilityKind::PublicAddress, + }); } match protocol { @@ -1390,7 +1420,7 @@ impl ConfigBuilder { } let command_socket_path = self.file.command_socket.clone().unwrap_or({ - let mut path = env::current_dir().map_err(|e| ConfigError::EnvError(e.to_string()))?; + let mut path = env::current_dir().map_err(|e| ConfigError::Env(e.to_string()))?; path.push("sozu.sock"); let verified_path = path .to_str() @@ -1399,7 +1429,7 @@ impl ConfigBuilder { }); if let (None, Some(true)) = (&self.file.saved_state, &self.file.automatic_state_save) { - return Err(ConfigError::MissingSavedState); + return Err(ConfigError::Missing(MissingKind::SavedState)); } Ok(Config { @@ -1696,17 +1726,17 @@ impl Config { /// read any file to a string pub fn load_file(path: &str) -> Result { - std::fs::read_to_string(path).map_err(|io_error| ConfigError::FileReadError { + std::fs::read_to_string(path).map_err(|io_error| ConfigError::FileRead { path_to_read: path.to_owned(), - io_error: io_error.to_string(), + io_error, }) } /// read any file to bytes pub fn load_file_bytes(path: &str) -> Result, ConfigError> { - std::fs::read(path).map_err(|io_error| ConfigError::FileReadError { + std::fs::read(path).map_err(|io_error| ConfigError::FileRead { path_to_read: path.to_owned(), - io_error: io_error.to_string(), + io_error, }) } } diff --git a/command/src/lib.rs b/command/src/lib.rs index 879cb540a..d7422ec4e 100644 --- a/command/src/lib.rs +++ b/command/src/lib.rs @@ -71,3 +71,19 @@ pub mod scm_socket; pub mod state; /// A writer used for logging pub mod writer; + +/// Used only when returning errors +#[derive(Debug)] +pub enum ObjectKind { + Backend, + Certificate, + Cluster, + HttpFrontend, + HttpsFrontend, + HttpListener, + HttpsListener, + Listener, + TcpCluster, + TcpListener, + TcpFrontend, +} diff --git a/command/src/request.rs b/command/src/request.rs index 919dd262b..5edb0d816 100644 --- a/command/src/request.rs +++ b/command/src/request.rs @@ -15,10 +15,10 @@ use crate::{ #[derive(thiserror::Error, Debug)] pub enum RequestError { - #[error("Could not parse socket address {address}: {error}")] - WrongAddress { address: String, error: String }, - #[error("wrong value {value} for field '{name}'")] - WrongFieldValue { name: String, value: i32 }, + #[error("Invalid address {address}: {error}")] + InvalidSocketAddress { address: String, error: String }, + #[error("invalid value {value} for field '{name}'")] + InvalidValue { name: String, value: i32 }, } impl Request { @@ -135,7 +135,7 @@ impl RequestHttpFrontend { pub fn to_frontend(self) -> Result { Ok(HttpFrontend { address: self.address.parse::().map_err(|parse_error| { - RequestError::WrongAddress { + RequestError::InvalidSocketAddress { address: self.address.clone(), error: parse_error.to_string(), } @@ -144,12 +144,10 @@ impl RequestHttpFrontend { hostname: self.hostname, path: self.path, method: self.method, - position: RulePosition::from_i32(self.position).ok_or( - RequestError::WrongFieldValue { - name: "position".to_string(), - value: self.position.clone(), - }, - )?, + position: RulePosition::from_i32(self.position).ok_or(RequestError::InvalidValue { + name: "position".to_string(), + value: self.position.clone(), + })?, tags: Some(self.tags), }) } diff --git a/command/src/scm_socket.rs b/command/src/scm_socket.rs index 8c488edc9..ec91bce8c 100644 --- a/command/src/scm_socket.rs +++ b/command/src/scm_socket.rs @@ -18,15 +18,18 @@ pub const MAX_BYTES_OUT: usize = 4096; #[derive(thiserror::Error, Debug)] pub enum ScmSocketError { #[error("could not set the blocking status of the unix stream to {blocking}: {error}")] - SetBlocking { blocking: bool, error: String }, + SetBlocking { + blocking: bool, + error: std::io::Error, + }, #[error("could not send message per SCM socket: {0}")] - SendError(String), + Send(String), #[error("could not send message per SCM socket: {0}")] - ReceiveError(String), - #[error("could not parse utf8 from buffer: {0}")] - Utf8Error(String), + Receive(String), + #[error("invalid char set: {0}")] + InvalidCharSet(String), #[error("Could not deserialize utf8 string into listeners: {0}")] - ListenerParseError(String), + ListenerParse(String), } /// A unix socket specialized for file descriptor passing @@ -43,9 +46,9 @@ impl ScmSocket { let stream = StdUnixStream::from_raw_fd(fd); stream .set_nonblocking(false) - .map_err(|io_error| ScmSocketError::SetBlocking { + .map_err(|error| ScmSocketError::SetBlocking { blocking: false, - error: io_error.to_string(), + error, })?; let _dropped_fd = stream.into_raw_fd(); } @@ -67,10 +70,7 @@ impl ScmSocket { let stream = StdUnixStream::from_raw_fd(self.fd); stream .set_nonblocking(!blocking) - .map_err(|io_error| ScmSocketError::SetBlocking { - blocking, - error: io_error.to_string(), - })?; + .map_err(|error| ScmSocketError::SetBlocking { blocking, error })?; let _dropped_fd = stream.into_raw_fd(); } self.blocking = blocking; @@ -110,10 +110,10 @@ impl ScmSocket { debug!("{} received :{:?}", self.fd, (size, file_descriptor_length)); let raw_listener_list = from_utf8(&buf[..size]) - .map_err(|utf8_error| ScmSocketError::Utf8Error(utf8_error.to_string()))?; + .map_err(|utf8_error| ScmSocketError::InvalidCharSet(utf8_error.to_string()))?; let mut listeners_count = serde_json::from_str::(raw_listener_list) - .map_err(|error| ScmSocketError::ListenerParseError(error.to_string()))?; + .map_err(|error| ScmSocketError::ListenerParse(error.to_string()))?; let mut index = 0; let len = listeners_count.http.len(); @@ -160,14 +160,14 @@ impl ScmSocket { if fds.is_empty() { debug!("{} send empty", self.fd); socket::sendmsg::<()>(self.fd, &iov, &[], flags, None) - .map_err(|error| ScmSocketError::SendError(error.to_string()))?; + .map_err(|error| ScmSocketError::Send(error.to_string()))?; return Ok(()); }; let control_message = [socket::ControlMessage::ScmRights(fds)]; debug!("{} send with data", self.fd); socket::sendmsg::<()>(self.fd, &iov, &control_message, flags, None) - .map_err(|error| ScmSocketError::SendError(error.to_string()))?; + .map_err(|error| ScmSocketError::Send(error.to_string()))?; Ok(()) } @@ -187,7 +187,7 @@ impl ScmSocket { }; let msg = socket::recvmsg::<()>(self.fd, &mut iov[..], Some(&mut cmsg), flags) - .map_err(|error| ScmSocketError::ReceiveError(error.to_string()))?; + .map_err(|error| ScmSocketError::Receive(error.to_string()))?; let mut fd_count = 0; let received_fds = msg diff --git a/command/src/state.rs b/command/src/state.rs index 5fd98cfd8..8cd088a39 100644 --- a/command/src/state.rs +++ b/command/src/state.rs @@ -22,6 +22,7 @@ use crate::{ display::format_request_type, }, response::{Backend, HttpFrontend, TcpFrontend}, + ObjectKind, }; /// To use throughout Sōzu @@ -35,38 +36,24 @@ pub enum StateError { NoChange, #[error("State can not handle this request")] UndispatchableRequest, - #[error("Did not find cluster {0}")] - ClusterNotFound(String), - #[error("Listener exists already on address {0}")] - ListenerExistsAlready(String), + #[error("Did not find {kind:?} with address or id '{id}'")] + NotFound { kind: ObjectKind, id: String }, + #[error("{kind:?} '{id}' already exists")] + Exists { kind: ObjectKind, id: String }, #[error("Wrong request: {0}")] WrongRequest(String), - #[error("No listener to remove at address {0}")] - NoListenerToRemove(String), - #[error("No backend to remove with id {0}")] - NoBackendToRemove(String), - #[error("No listener to activate at address {0}")] - NoListenerToActivate(String), - #[error("No listener to deactivate at address {0}")] - NoListenerToDeactivate(String), - #[error("Can not add the frontend, it is already there: {0}")] - FrontendAlreadyThere(String), - #[error("Can not remove this frontend, it is not found: {0}")] - NoFrontendToRemove(String), #[error("Could not add certificate: {0}")] - AddCertificateError(String), + AddCertificate(String), #[error("Could not remove certificate: {0}")] - RemoveCertificateError(String), + RemoveCertificate(String), #[error("Could not replace certificate: {0}")] - ReplaceCertificateError(String), + ReplaceCertificate(String), #[error("The provided socket address '{address}' is wrong: {error}")] WrongSocketAddress { address: String, error: String }, - #[error("Certificate not found")] - CertificateNotFound, #[error( "Could not convert the frontend to an insertable one. Frontend: {frontend} error: {error}" )] - FrontendConversionError { frontend: String, error: String }, + FrontendConversion { frontend: String, error: String }, } /// The `ConfigState` represents the state of Sōzu's business, which is to forward traffic @@ -176,7 +163,10 @@ impl ConfigState { fn remove_cluster(&mut self, cluster_id: &str) -> Result<(), StateError> { match self.clusters.remove(cluster_id) { Some(_) => Ok(()), - None => Err(StateError::ClusterNotFound(cluster_id.to_owned())), + None => Err(StateError::NotFound { + kind: ObjectKind::Cluster, + id: cluster_id.to_owned(), + }), } } @@ -184,7 +174,12 @@ impl ConfigState { let address = listener.address.to_string(); match self.http_listeners.entry(address.clone()) { BTreeMapEntry::Vacant(vacant_entry) => vacant_entry.insert(listener.clone()), - BTreeMapEntry::Occupied(_) => return Err(StateError::ListenerExistsAlready(address)), + BTreeMapEntry::Occupied(_) => { + return Err(StateError::Exists { + kind: ObjectKind::HttpListener, + id: address, + }) + } }; Ok(()) } @@ -193,7 +188,12 @@ impl ConfigState { let address = listener.address.to_string(); match self.https_listeners.entry(address.clone()) { BTreeMapEntry::Vacant(vacant_entry) => vacant_entry.insert(listener.clone()), - BTreeMapEntry::Occupied(_) => return Err(StateError::ListenerExistsAlready(address)), + BTreeMapEntry::Occupied(_) => { + return Err(StateError::Exists { + kind: ObjectKind::HttpsListener, + id: address, + }) + } }; Ok(()) } @@ -202,7 +202,12 @@ impl ConfigState { let address = listener.address.to_string(); match self.tcp_listeners.entry(address.clone()) { BTreeMapEntry::Vacant(vacant_entry) => vacant_entry.insert(listener.clone()), - BTreeMapEntry::Occupied(_) => return Err(StateError::ListenerExistsAlready(address)), + BTreeMapEntry::Occupied(_) => { + return Err(StateError::Exists { + kind: ObjectKind::TcpListener, + id: address, + }) + } }; Ok(()) } @@ -220,117 +225,87 @@ impl ConfigState { fn remove_http_listener(&mut self, address: &str) -> Result<(), StateError> { if self.http_listeners.remove(address).is_none() { - return Err(StateError::NoListenerToRemove(address.to_owned())); + return Err(StateError::NoChange); } Ok(()) } fn remove_https_listener(&mut self, address: &str) -> Result<(), StateError> { if self.https_listeners.remove(address).is_none() { - return Err(StateError::NoListenerToRemove(address.to_owned())); + return Err(StateError::NoChange); } Ok(()) } fn remove_tcp_listener(&mut self, address: &str) -> Result<(), StateError> { if self.tcp_listeners.remove(address).is_none() { - return Err(StateError::NoListenerToRemove(address.to_owned())); + return Err(StateError::NoChange); } Ok(()) } fn activate_listener(&mut self, activate: &ActivateListener) -> Result<(), StateError> { match ListenerType::from_i32(activate.proxy) { - Some(ListenerType::Http) => { - if self - .http_listeners - .get_mut(&activate.address) - .map(|listener| listener.active = true) - .is_none() - { - return Err(StateError::NoListenerToActivate( - activate.address.to_owned(), - )); - } - } - Some(ListenerType::Https) => { - if self - .https_listeners - .get_mut(&activate.address) - .map(|listener| listener.active = true) - .is_none() - { - return Err(StateError::NoListenerToActivate( - activate.address.to_owned(), - )); - } - } - Some(ListenerType::Tcp) => { - if self - .tcp_listeners - .get_mut(&activate.address) - .map(|listener| listener.active = true) - .is_none() - { - return Err(StateError::NoListenerToActivate( - activate.address.to_owned(), - )); - } - } - None => { - return Err(StateError::WrongRequest( - "Wrong variant for ListenerType on request".to_string(), - )) - } + Some(ListenerType::Http) => self + .http_listeners + .get_mut(&activate.address) + .map(|listener| listener.active = true) + .ok_or(StateError::NotFound { + kind: ObjectKind::HttpListener, + id: activate.address.to_owned(), + }), + Some(ListenerType::Https) => self + .https_listeners + .get_mut(&activate.address) + .map(|listener| listener.active = true) + .ok_or(StateError::NotFound { + kind: ObjectKind::HttpsListener, + id: activate.address.to_owned(), + }), + Some(ListenerType::Tcp) => self + .tcp_listeners + .get_mut(&activate.address) + .map(|listener| listener.active = true) + .ok_or(StateError::NotFound { + kind: ObjectKind::TcpListener, + id: activate.address.to_owned(), + }), + None => Err(StateError::WrongRequest( + "Wrong variant for ListenerType on request".to_string(), + )), } - Ok(()) } fn deactivate_listener(&mut self, deactivate: &DeactivateListener) -> Result<(), StateError> { match ListenerType::from_i32(deactivate.proxy) { - Some(ListenerType::Http) => { - if self - .http_listeners - .get_mut(&deactivate.address) - .map(|listener| listener.active = false) - .is_none() - { - return Err(StateError::NoListenerToDeactivate( - deactivate.address.to_owned(), - )); - } - } - Some(ListenerType::Https) => { - if self - .https_listeners - .get_mut(&deactivate.address) - .map(|listener| listener.active = false) - .is_none() - { - return Err(StateError::NoListenerToDeactivate( - deactivate.address.to_owned(), - )); - } - } - Some(ListenerType::Tcp) => { - if self - .tcp_listeners - .get_mut(&deactivate.address) - .map(|listener| listener.active = false) - .is_none() - { - return Err(StateError::NoListenerToDeactivate( - deactivate.address.to_owned(), - )); - } - } - None => { - return Err(StateError::WrongRequest( - "Wrong variant for ListenerType on request".to_string(), - )) - } + Some(ListenerType::Http) => self + .http_listeners + .get_mut(&deactivate.address) + .map(|listener| listener.active = false) + .ok_or(StateError::NotFound { + kind: ObjectKind::HttpListener, + id: deactivate.address.to_owned(), + }), + Some(ListenerType::Https) => self + .https_listeners + .get_mut(&deactivate.address) + .map(|listener| listener.active = false) + .ok_or(StateError::NotFound { + kind: ObjectKind::HttpsListener, + id: deactivate.address.to_owned(), + }), + Some(ListenerType::Tcp) => self + .tcp_listeners + .get_mut(&deactivate.address) + .map(|listener| listener.active = false) + .ok_or(StateError::NotFound { + kind: ObjectKind::TcpListener, + id: deactivate.address.to_owned(), + }), + None => Err(StateError::WrongRequest( + "Wrong variant for ListenerType on request".to_string(), + )), } - Ok(()) } fn add_http_frontend(&mut self, front: &RequestHttpFrontend) -> Result<(), StateError> { @@ -339,14 +314,17 @@ impl ConfigState { match self.http_fronts.entry(front.to_string()) { BTreeMapEntry::Vacant(e) => { e.insert(front.clone().to_frontend().map_err(|into_error| { - StateError::FrontendConversionError { + StateError::FrontendConversion { frontend: front_as_key, error: into_error.to_string(), } })?) } BTreeMapEntry::Occupied(_) => { - return Err(StateError::FrontendAlreadyThere(front.to_string())) + return Err(StateError::Exists { + kind: ObjectKind::HttpFrontend, + id: front.to_string(), + }) } }; Ok(()) @@ -358,37 +336,46 @@ impl ConfigState { match self.https_fronts.entry(front.to_string()) { BTreeMapEntry::Vacant(e) => { e.insert(front.clone().to_frontend().map_err(|into_error| { - StateError::FrontendConversionError { + StateError::FrontendConversion { frontend: front_as_key, error: into_error.to_string(), } })?) } BTreeMapEntry::Occupied(_) => { - return Err(StateError::FrontendAlreadyThere(front.to_string())) + return Err(StateError::Exists { + kind: ObjectKind::HttpsFrontend, + id: front.to_string(), + }) } }; Ok(()) } fn remove_http_frontend(&mut self, front: &RequestHttpFrontend) -> Result<(), StateError> { - if self.http_fronts.remove(&front.to_string()).is_none() { - return Err(StateError::NoFrontendToRemove(front.to_string())); - } + self.http_fronts + .remove(&front.to_string()) + .ok_or(StateError::NotFound { + kind: ObjectKind::HttpFrontend, + id: front.to_string(), + })?; Ok(()) } fn remove_https_frontend(&mut self, front: &RequestHttpFrontend) -> Result<(), StateError> { - if self.https_fronts.remove(&front.to_string()).is_none() { - return Err(StateError::NoFrontendToRemove(front.to_string())); - } + self.https_fronts + .remove(&front.to_string()) + .ok_or(StateError::NotFound { + kind: ObjectKind::HttpsFrontend, + id: front.to_string(), + })?; Ok(()) } fn add_certificate(&mut self, add: &AddCertificate) -> Result<(), StateError> { let fingerprint = Fingerprint( calculate_fingerprint(add.certificate.certificate.as_bytes()).map_err( - |fingerprint_err| StateError::AddCertificateError(format!("{:#}", fingerprint_err)), + |fingerprint_err| StateError::AddCertificate(fingerprint_err.to_string()), )?, ); @@ -412,10 +399,10 @@ impl ConfigState { } fn remove_certificate(&mut self, remove: &RemoveCertificate) -> Result<(), StateError> { - let fingerprint = - Fingerprint(hex::decode(&remove.fingerprint).map_err(|decode_error| { - StateError::RemoveCertificateError(decode_error.to_string()) - })?); + let fingerprint = Fingerprint( + hex::decode(&remove.fingerprint) + .map_err(|decode_error| StateError::RemoveCertificate(decode_error.to_string()))?, + ); let address = parse_socket_address(&remove.address)?; @@ -433,20 +420,22 @@ impl ConfigState { fn replace_certificate(&mut self, replace: &ReplaceCertificate) -> Result<(), StateError> { let address = parse_socket_address(&replace.address)?; - let old_fingerprint = Fingerprint(hex::decode(&replace.old_fingerprint).map_err( - |decode_error| StateError::RemoveCertificateError(decode_error.to_string()), - )?); + let old_fingerprint = Fingerprint( + hex::decode(&replace.old_fingerprint) + .map_err(|decode_error| StateError::RemoveCertificate(decode_error.to_string()))?, + ); self.certificates .get_mut(&address) - .ok_or(StateError::CertificateNotFound)? + .ok_or(StateError::NotFound { + kind: ObjectKind::Certificate, + id: address.to_string(), + })? .remove(&old_fingerprint); let new_fingerprint = Fingerprint( calculate_fingerprint(replace.new_certificate.certificate.as_bytes()).map_err( - |fingerprint_err| { - StateError::ReplaceCertificateError(format!("{:#}", fingerprint_err)) - }, + |fingerprint_err| StateError::ReplaceCertificate(fingerprint_err.to_string()), )?, ); @@ -457,13 +446,13 @@ impl ConfigState { if !self .certificates .get(&address) - .ok_or(StateError::ReplaceCertificateError( + .ok_or(StateError::ReplaceCertificate( "Unlikely error. This entry in the certificate hashmap should be present" .to_string(), ))? .contains_key(&new_fingerprint) { - return Err(StateError::ReplaceCertificateError(format!( + return Err(StateError::ReplaceCertificate(format!( "Failed to insert the new certificate for address {}", replace.address ))); @@ -483,10 +472,10 @@ impl ConfigState { tags: front.tags.clone(), }; if tcp_frontends.contains(&tcp_frontend) { - return Err(StateError::FrontendAlreadyThere(format!( - "This tcp frontend is already present: {:?}", - tcp_frontend - ))); + return Err(StateError::Exists { + kind: ObjectKind::TcpFrontend, + id: format!("{:?}", tcp_frontend), + }); } tcp_frontends.push(tcp_frontend); @@ -499,9 +488,13 @@ impl ConfigState { ) -> Result<(), StateError> { let address = parse_socket_address(&front_to_remove.address)?; - let tcp_frontends = self.tcp_fronts.get_mut(&front_to_remove.cluster_id).ok_or( - StateError::NoFrontendToRemove(format!("{:?}", front_to_remove)), - )?; + let tcp_frontends = + self.tcp_fronts + .get_mut(&front_to_remove.cluster_id) + .ok_or(StateError::NotFound { + kind: ObjectKind::TcpFrontend, + id: format!("{:?}", front_to_remove), + })?; let len = tcp_frontends.len(); tcp_frontends.retain(|front| front.address != address); @@ -534,10 +527,13 @@ impl ConfigState { } fn remove_backend(&mut self, backend: &RemoveBackend) -> Result<(), StateError> { - let backend_list = self - .backends - .get_mut(&backend.cluster_id) - .ok_or(StateError::NoBackendToRemove(backend.backend_id.to_owned()))?; + let backend_list = + self.backends + .get_mut(&backend.cluster_id) + .ok_or(StateError::NotFound { + kind: ObjectKind::Backend, + id: backend.backend_id.to_owned(), + })?; let len = backend_list.len(); backend_list.retain(|b| { diff --git a/lib/src/backends.rs b/lib/src/backends.rs index 9cbbc617e..9040bc5b2 100644 --- a/lib/src/backends.rs +++ b/lib/src/backends.rs @@ -20,12 +20,10 @@ use super::load_balancing::*; pub enum BackendError { #[error("No backend found for cluster {0}")] NoBackendForCluster(String), - #[error("No more backend is available for cluster {0}")] - NoAvailableBackendForCluster(String), #[error("Failed to connect to socket with MIO: {0}")] - MioConnectionError(String), + MioConnection(std::io::Error), #[error("This backend is not in a normal status: status={0:?}")] - StatusNotNormal(BackendStatus), + Status(BackendStatus), #[error( "could not connect {cluster_id} to {backend_address:?} ({failures} failures): {error}" )] @@ -142,7 +140,7 @@ impl Backend { pub fn try_connect(&mut self) -> Result { if self.status != BackendStatus::Normal { - return Err(BackendError::StatusNotNormal(self.status.to_owned())); + return Err(BackendError::Status(self.status.to_owned())); } match mio::net::TcpStream::connect(self.address) { @@ -151,14 +149,14 @@ impl Backend { self.inc_connections(); Ok(tcp_stream) } - Err(mio_error) => { + Err(io_error) => { self.retry_policy.fail(); self.failures += 1; // TODO: handle EINPROGRESS. It is difficult. It is discussed here: // https://docs.rs/mio/latest/mio/net/struct.TcpStream.html#method.connect // with an example code here: // https://github.com/Thomasdezeeuw/heph/blob/0c4f1ab3eaf08bea1d65776528bfd6114c9f8374/src/net/tcp/stream.rs#L560-L622 - Err(BackendError::MioConnectionError(mio_error.to_string())) + Err(BackendError::MioConnection(io_error)) } } } @@ -275,9 +273,7 @@ impl BackendMap { address: None, }); } - return Err(BackendError::NoAvailableBackendForCluster( - cluster_id.to_owned(), - )); + return Err(BackendError::NoBackendForCluster(cluster_id.to_owned())); } }; diff --git a/lib/src/http.rs b/lib/src/http.rs index bf66ab46f..e53d413c5 100644 --- a/lib/src/http.rs +++ b/lib/src/http.rs @@ -424,7 +424,7 @@ impl L7ListenerHandler for HttpListener { Ok(tuple) => tuple, Err(parse_error) => { // parse_error contains a slice of given_host, which should NOT escape this scope - return Err(FrontendFromRequestError::HostParsingFailure { + return Err(FrontendFromRequestError::HostParse { host: host.to_owned(), error: parse_error.to_string(), }); @@ -487,7 +487,7 @@ impl HttpProxy { match self.listeners.entry(token) { Entry::Vacant(entry) => { let http_listener = HttpListener::new(config, token) - .map_err(|listener_error| ProxyError::AddListenerError(listener_error))?; + .map_err(|listener_error| ProxyError::AddListener(listener_error))?; entry.insert(Rc::new(RefCell::new(http_listener))); Ok(token) } @@ -524,7 +524,7 @@ impl HttpProxy { listener .borrow_mut() .activate(&self.registry, tcp_listener) - .map_err(|listener_error| ProxyError::ListenerActivationFailure { + .map_err(|listener_error| ProxyError::ListenerActivation { address: addr.clone(), listener_error, }) @@ -605,7 +605,7 @@ impl HttpProxy { listener .add_http_front(front) - .map_err(|listener_error| ProxyError::AddFrontendError(listener_error))?; + .map_err(|listener_error| ProxyError::AddFrontend(listener_error))?; listener.set_tags(hostname, tags); Ok(()) } @@ -629,7 +629,7 @@ impl HttpProxy { listener .remove_http_front(front) - .map_err(|listener_error| ProxyError::RemoveFrontendError(listener_error))?; + .map_err(|listener_error| ProxyError::RemoveFrontend(listener_error))?; listener.set_tags(hostname, None); Ok(()) @@ -649,7 +649,7 @@ impl HttpProxy { } if !socket_errors.is_empty() { - return Err(ProxyError::SoftStopError { + return Err(ProxyError::SoftStop { proxy_protocol: "HTTP".to_string(), error: format!("Error deregistering listen sockets: {:?}", socket_errors), }); @@ -672,7 +672,7 @@ impl HttpProxy { } if !socket_errors.is_empty() { - return Err(ProxyError::SoftStopError { + return Err(ProxyError::HardStop { proxy_protocol: "HTTP".to_string(), error: format!("Error deregistering listen sockets: {:?}", socket_errors), }); @@ -695,7 +695,7 @@ impl HttpListener { let address = config .address .parse::() - .map_err(|parse_error| ListenerError::SocketParseError { + .map_err(|parse_error| ListenerError::SocketParse { address: config.address.clone(), error: parse_error.to_string(), })?; @@ -726,7 +726,7 @@ impl HttpListener { let mut listener = match tcp_listener { Some(tcp_listener) => tcp_listener, None => server_bind(self.config.address.clone()).map_err(|server_bind_error| { - ListenerError::ActivationError { + ListenerError::Activation { address: self.config.address.clone(), error: server_bind_error.to_string(), } @@ -735,7 +735,7 @@ impl HttpListener { registry .register(&mut listener, self.token, Interest::READABLE) - .map_err(|io_error| ListenerError::SocketRegistrationFailure(io_error.to_string()))?; + .map_err(|io_error| ListenerError::SocketRegistration(io_error))?; self.listener = Some(listener); self.active = true; @@ -745,14 +745,14 @@ impl HttpListener { pub fn add_http_front(&mut self, http_front: HttpFrontend) -> Result<(), ListenerError> { self.fronts .add_http_front(&http_front) - .map_err(|router_error| ListenerError::AddFrontendError(router_error)) + .map_err(|router_error| ListenerError::AddFrontend(router_error)) } pub fn remove_http_front(&mut self, http_front: HttpFrontend) -> Result<(), ListenerError> { debug!("removing http_front {:?}", http_front); self.fronts .remove_http_front(&http_front) - .map_err(|router_error| ListenerError::RemoveFrontendError(router_error)) + .map_err(|router_error| ListenerError::RemoveFrontend(router_error)) } fn accept(&mut self) -> Result { @@ -844,8 +844,8 @@ impl ProxyConfiguration for HttpProxy { WorkerResponse::ok(request_id) } Err(proxy_error) => { - debug!("{} unsuccessful: {:#}", request_id, proxy_error); - WorkerResponse::error(request_id, format!("{proxy_error}")) + debug!("{} unsuccessful: {}", request_id, proxy_error); + WorkerResponse::error(request_id, proxy_error) } } } diff --git a/lib/src/https.rs b/lib/src/https.rs index 07fd481dc..09a0026ea 100644 --- a/lib/src/https.rs +++ b/lib/src/https.rs @@ -566,7 +566,7 @@ impl L7ListenerHandler for HttpsListener { Ok(tuple) => tuple, Err(parse_error) => { // parse_error contains a slice of given_host, which should NOT escape this scope - return Err(FrontendFromRequestError::HostParsingFailure { + return Err(FrontendFromRequestError::HostParse { host: host.to_owned(), error: parse_error.to_string(), }); @@ -598,7 +598,7 @@ impl CertificateResolver for HttpsListener { .resolver .0 .lock() - .map_err(|err| ListenerError::LockError(err.to_string())) + .map_err(|err| ListenerError::Lock(err.to_string())) .ok()?; resolver.get_certificate(fingerprint) @@ -609,11 +609,11 @@ impl CertificateResolver for HttpsListener { .resolver .0 .lock() - .map_err(|err| ListenerError::LockError(err.to_string()))?; + .map_err(|err| ListenerError::Lock(err.to_string()))?; resolver .add_certificate(opts) - .map_err(ListenerError::ResolverError) + .map_err(ListenerError::Resolver) } fn remove_certificate(&mut self, fingerprint: &Fingerprint) -> Result<(), Self::Error> { @@ -621,11 +621,11 @@ impl CertificateResolver for HttpsListener { .resolver .0 .lock() - .map_err(|err| ListenerError::LockError(err.to_string()))?; + .map_err(|err| ListenerError::Lock(err.to_string()))?; resolver .remove_certificate(fingerprint) - .map_err(ListenerError::ResolverError) + .map_err(ListenerError::Resolver) } } @@ -641,7 +641,7 @@ impl HttpsListener { let address = config .address .parse::() - .map_err(|parse_error| ListenerError::SocketParseError { + .map_err(|parse_error| ListenerError::SocketParse { address: config.address.clone(), error: parse_error.to_string(), })?; @@ -675,7 +675,7 @@ impl HttpsListener { let mut listener = match tcp_listener { Some(tcp_listener) => tcp_listener, None => server_bind(self.config.address.clone()).map_err(|server_bind_error| { - ListenerError::ActivationError { + ListenerError::Activation { address: self.config.address.clone(), error: server_bind_error.to_string(), } @@ -684,7 +684,7 @@ impl HttpsListener { registry .register(&mut listener, self.token, Interest::READABLE) - .map_err(|io_error| ListenerError::SocketRegistrationFailure(io_error.to_string()))?; + .map_err(|io_error| ListenerError::SocketRegistration(io_error))?; self.listener = Some(listener); self.active = true; @@ -742,7 +742,7 @@ impl HttpsListener { .with_cipher_suites(&ciphers[..]) .with_safe_default_kx_groups() .with_protocol_versions(&versions[..]) - .map_err(|err| ListenerError::BuildRustlsError(err.to_string()))? + .map_err(|err| ListenerError::BuildRustls(err.to_string()))? .with_no_client_auth() .with_cert_resolver(resolver); @@ -758,14 +758,14 @@ impl HttpsListener { pub fn add_https_front(&mut self, tls_front: HttpFrontend) -> Result<(), ListenerError> { self.fronts .add_http_front(&tls_front) - .map_err(|router_error| ListenerError::AddFrontendError(router_error)) + .map_err(|router_error| ListenerError::AddFrontend(router_error)) } pub fn remove_https_front(&mut self, tls_front: HttpFrontend) -> Result<(), ListenerError> { debug!("removing tls_front {:?}", tls_front); self.fronts .remove_http_front(&tls_front) - .map_err(|router_error| ListenerError::RemoveFrontendError(router_error)) + .map_err(|router_error| ListenerError::RemoveFrontend(router_error)) } fn accept(&mut self) -> Result { @@ -856,7 +856,7 @@ impl HttpsProxy { } if !socket_errors.is_empty() { - return Err(ProxyError::SoftStopError { + return Err(ProxyError::SoftStop { proxy_protocol: "HTTPS".to_string(), error: format!("Error deregistering listen sockets: {:?}", socket_errors), }); @@ -879,7 +879,7 @@ impl HttpsProxy { } if !socket_errors.is_empty() { - return Err(ProxyError::HardStopError { + return Err(ProxyError::HardStop { proxy_protocol: "HTTPS".to_string(), error: format!("Error deregistering listen sockets: {:?}", socket_errors), }); @@ -982,7 +982,7 @@ impl HttpsProxy { listener .borrow_mut() .activate(&self.registry, tcp_listener) - .map_err(|listener_error| ProxyError::ListenerActivationFailure { + .map_err(|listener_error| ProxyError::ListenerActivation { address: addr.clone(), listener_error, }) @@ -1074,7 +1074,7 @@ impl HttpsProxy { listener.set_tags(front.hostname.to_owned(), front.tags.to_owned()); listener .add_https_front(front) - .map_err(|listener_error| ProxyError::AddFrontendError(listener_error))?; + .map_err(|listener_error| ProxyError::AddFrontend(listener_error))?; Ok(None) } @@ -1099,7 +1099,7 @@ impl HttpsProxy { listener.set_tags(front.hostname.to_owned(), None); listener .remove_https_front(front) - .map_err(|listener_error| ProxyError::RemoveFrontendError(listener_error))?; + .map_err(|listener_error| ProxyError::RemoveFrontend(listener_error))?; Ok(None) } @@ -1110,7 +1110,7 @@ impl HttpsProxy { let address = add_certificate .address .parse::() - .map_err(|parse_error| ProxyError::SocketParseError { + .map_err(|parse_error| ProxyError::SocketParse { address: add_certificate.address.clone(), error: parse_error.to_string(), })?; @@ -1124,7 +1124,7 @@ impl HttpsProxy { listener .borrow_mut() .add_certificate(&add_certificate) - .map_err(|listener_error| ProxyError::AddCertificateError(listener_error))?; + .map_err(|listener_error| ProxyError::AddCertificate(listener_error))?; Ok(None) } @@ -1137,7 +1137,7 @@ impl HttpsProxy { let address = remove_certificate .address .parse::() - .map_err(|parse_error| ProxyError::SocketParseError { + .map_err(|parse_error| ProxyError::SocketParse { address: remove_certificate.address, error: parse_error.to_string(), })?; @@ -1156,7 +1156,7 @@ impl HttpsProxy { listener .borrow_mut() .remove_certificate(&fingerprint) - .map_err(|listener_error| ProxyError::AddCertificateError(listener_error))?; + .map_err(|listener_error| ProxyError::AddCertificate(listener_error))?; Ok(None) } @@ -1169,7 +1169,7 @@ impl HttpsProxy { let address = replace_certificate .address .parse::() - .map_err(|parse_error| ProxyError::SocketParseError { + .map_err(|parse_error| ProxyError::SocketParse { address: replace_certificate.address.clone(), error: parse_error.to_string(), })?; @@ -1183,7 +1183,7 @@ impl HttpsProxy { listener .borrow_mut() .replace_certificate(&replace_certificate) - .map_err(|listener_error| ProxyError::ReplaceCertificateError(listener_error))?; + .map_err(|listener_error| ProxyError::ReplaceCertificate(listener_error))?; Ok(None) } @@ -1374,8 +1374,8 @@ impl ProxyConfiguration for HttpsProxy { } } Err(proxy_error) => { - debug!("{} unsuccessful: {:#}", request_id, proxy_error); - WorkerResponse::error(request_id, format!("{proxy_error}")) + debug!("{} unsuccessful: {}", request_id, proxy_error); + WorkerResponse::error(request_id, proxy_error) } } } @@ -1634,7 +1634,7 @@ mod tests { .with_safe_default_cipher_suites() .with_safe_default_kx_groups() .with_protocol_versions(&[&rustls::version::TLS12, &rustls::version::TLS13]) - .map_err(|err| ListenerError::BuildRustlsError(err.to_string())) + .map_err(|err| ListenerError::BuildRustls(err.to_string())) .expect("could not create Rustls server config") .with_no_client_auth() .with_cert_resolver(resolver.clone()); diff --git a/lib/src/lib.rs b/lib/src/lib.rs index c0e1521d3..e4b60d6b2 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -395,7 +395,10 @@ use backends::BackendError; use mio::{net::TcpStream, Interest, Token}; use protocol::http::parser::Method; use router::RouterError; -use sozu_command::proto::command::{ListenerType, RequestHttpFrontend}; +use sozu_command::{ + proto::command::{ListenerType, RequestHttpFrontend}, + ObjectKind, +}; use sozu_command_lib::{ proto::command::Cluster, ready::Ready, request::WorkerRequest, response::WorkerResponse, state::ClusterId, @@ -405,10 +408,6 @@ use tls::GenericCertificateResolverError; use self::{backends::BackendMap, router::Route}; -/// returned by proxies when dispatching changes to their state -#[derive(thiserror::Error, Debug)] -pub enum NotifyError {} - /// Anything that can be registered in mio (subscribe to kernel events) #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Protocol { @@ -602,7 +601,7 @@ pub trait ListenerHandler { #[derive(thiserror::Error, Debug)] pub enum FrontendFromRequestError { #[error("Could not parse hostname from '{host}': {error}")] - HostParsingFailure { host: String, error: String }, + HostParse { host: String, error: String }, #[error("invalid remaining chars after hostname. Host: {0}")] InvalidCharsAfterHost(String), #[error("no cluster found")] @@ -645,16 +644,14 @@ pub enum BackendConnectAction { #[derive(thiserror::Error, Debug)] pub enum BackendConnectionError { - #[error("Found no TCP cluster")] - FoundNoTcpCluster, - #[error("Too many connections on cluster {0}")] - TooManyConnections(String), + #[error("Not found: {0:?}")] + NotFound(ObjectKind), + #[error("Too many connections on cluster {0:?}")] + MaxConnectionRetries(Option), #[error("the sessions slab has reached maximum capacity")] - SessionsMemoryAtCapacity, + MaxSessionsMemory, #[error("error from the backend: {0}")] - BackendError(BackendError), - #[error("Reached maximum attempts to connect to this backend")] - TooManyAttempts, + Backend(BackendError), #[error("failed to retrieve the cluster: {0}")] RetrieveClusterError(RetrieveClusterError), } @@ -671,7 +668,7 @@ pub enum RetrieveClusterError { #[error("unauthorized route")] UnauthorizedRoute, #[error("failed to retrieve the frontend for the request: {0}")] - FrontendFromRequestError(FrontendFromRequestError), + RetrieveFrontend(FrontendFromRequestError), } /// Used in sessions @@ -689,35 +686,35 @@ pub enum AcceptError { #[derive(thiserror::Error, Debug)] pub enum ListenerError { #[error("failed to acquire the lock, {0}")] - LockError(String), + Lock(String), #[error("failed to handle certificate request, got a resolver error, {0}")] - ResolverError(GenericCertificateResolverError), + Resolver(GenericCertificateResolverError), #[error("failed to parse pem, {0}")] - PemParseError(String), + PemParse(String), #[error("failed to build rustls context, {0}")] - BuildRustlsError(String), + BuildRustls(String), #[error("Wrong socket address")] - SocketParseError { address: String, error: String }, + SocketParse { address: String, error: String }, #[error("could not activate listener with address {address}: {error}")] - ActivationError { address: String, error: String }, + Activation { address: String, error: String }, #[error("Could not register listener socket: {0}")] - SocketRegistrationFailure(String), + SocketRegistration(std::io::Error), #[error("could not add frontend: {0}")] - AddFrontendError(RouterError), + AddFrontend(RouterError), #[error("could not remove frontend: {0}")] - RemoveFrontendError(RouterError), + RemoveFrontend(RouterError), } /// Returned by the HTTP, HTTPS and TCP proxies #[derive(thiserror::Error, Debug)] pub enum ProxyError { #[error("error while soft stopping {proxy_protocol} proxy: {error}")] - SoftStopError { + SoftStop { proxy_protocol: String, error: String, }, #[error("error while hard stopping {proxy_protocol} proxy: {error}")] - HardStopError { + HardStop { proxy_protocol: String, error: String, }, @@ -726,9 +723,9 @@ pub enum ProxyError { #[error("a listener is already present for this token")] ListenerAlreadyPresent, #[error("could not create add listener: {0}")] - AddListenerError(ListenerError), + AddListener(ListenerError), #[error("failed to activate listener with address {address:?}: {listener_error}")] - ListenerActivationFailure { + ListenerActivation { address: SocketAddr, listener_error: ListenerError, }, @@ -738,17 +735,17 @@ pub enum ProxyError { error: String, }, #[error("could not add frontend: {0}")] - AddFrontendError(ListenerError), + AddFrontend(ListenerError), #[error("could not remove frontend: {0}")] - RemoveFrontendError(ListenerError), + RemoveFrontend(ListenerError), #[error("could not add certificate: {0}")] - AddCertificateError(ListenerError), + AddCertificate(ListenerError), #[error("could not remove certificate: {0}")] - RemoveCertificateError(ListenerError), + RemoveCertificate(ListenerError), #[error("could not replace certificate: {0}")] - ReplaceCertificateError(ListenerError), + ReplaceCertificate(ListenerError), #[error("Wrong address {address}: {error}")] - SocketParseError { address: String, error: String }, + SocketParse { address: String, error: String }, #[error("wrong certificate fingerprint: {0}")] WrongCertificateFingerprint(String), #[error("this request is not supported by the proxy")] diff --git a/lib/src/metrics/local_drain.rs b/lib/src/metrics/local_drain.rs index d4bfd1f55..58dc13b18 100644 --- a/lib/src/metrics/local_drain.rs +++ b/lib/src/metrics/local_drain.rs @@ -271,7 +271,7 @@ impl LocalDrain { let raw_metrics = self .cluster_metrics .get(cluster_id) - .ok_or(MetricError::NoMetricsForCluster(cluster_id.to_owned()))?; + .ok_or(MetricError::NoMetrics(cluster_id.to_owned()))?; let cluster: BTreeMap = raw_metrics .iter() @@ -301,7 +301,7 @@ impl LocalDrain { let backend_metrics = self .cluster_metrics .get(backend_id) - .ok_or(MetricError::NoMetricsForBackend(backend_id.to_owned()))?; + .ok_or(MetricError::NoMetrics(backend_id.to_owned()))?; let filtered_backend_metrics = backend_metrics .iter() @@ -354,7 +354,7 @@ impl LocalDrain { let cluster_id = self .backend_to_cluster .get(backend_id) - .ok_or(MetricError::NoMetricsForBackend(backend_id.to_owned()))? + .ok_or(MetricError::NoMetrics(backend_id.to_owned()))? .to_owned(); let backends = vec![self.metrics_of_one_backend(backend_id, metric_names)?]; diff --git a/lib/src/metrics/mod.rs b/lib/src/metrics/mod.rs index c35a51865..617579430 100644 --- a/lib/src/metrics/mod.rs +++ b/lib/src/metrics/mod.rs @@ -27,11 +27,9 @@ pub enum MetricError { #[error("Could not parse udp address {address}: {error}")] WrongUdpAddress { address: String, error: String }, #[error("Could not bind to udp address {address}: {error}")] - UdpBindError { address: String, error: String }, - #[error("No metrics found for backend with id {0}")] - NoMetricsForBackend(String), - #[error("No metrics found for cluster with id {0}")] - NoMetricsForCluster(String), + UdpBind { address: String, error: String }, + #[error("No metrics found for object with id {0}")] + NoMetrics(String), #[error("Could not create histogram for time metric {time_metric:?}: {error}")] HistogramCreation { time_metric: MetricValue, @@ -301,7 +299,7 @@ pub fn udp_bind() -> Result { error: parse_error.to_string(), })?; - UdpSocket::bind(udp_address).map_err(|parse_error| MetricError::UdpBindError { + UdpSocket::bind(udp_address).map_err(|parse_error| MetricError::UdpBind { address: udp_address.to_string(), error: parse_error.to_string(), }) diff --git a/lib/src/protocol/kawa_h1/mod.rs b/lib/src/protocol/kawa_h1/mod.rs index 92faa52a8..b96646962 100644 --- a/lib/src/protocol/kawa_h1/mod.rs +++ b/lib/src/protocol/kawa_h1/mod.rs @@ -977,7 +977,7 @@ impl Http= CONN_RETRIES { error!("{} max connection attempt reached", self.log_context()); self.set_answer(DefaultAnswerStatus::Answer503, None); - return Err(BackendConnectionError::TooManyAttempts); + return Err(BackendConnectionError::MaxConnectionRetries(None)); } Ok(()) } @@ -1041,9 +1041,7 @@ impl Http route, Err(frontend_error) => { self.set_answer(DefaultAnswerStatus::Answer404, None); - return Err(RetrieveClusterError::FrontendFromRequestError( - frontend_error, - )); + return Err(RetrieveClusterError::RetrieveFrontend(frontend_error)); } }; @@ -1091,7 +1089,7 @@ impl Http Http { - error!("Error connecting to backend: {:#}", connection_error) + error!("Error connecting to backend: {}", connection_error) } } } else { @@ -1479,7 +1477,7 @@ impl Http { - error!("Error connecting to backend: {:#}", connection_error) + error!("Error connecting to backend: {}", connection_error) } } } diff --git a/lib/src/router/mod.rs b/lib/src/router/mod.rs index 01b15460a..c95000455 100644 --- a/lib/src/router/mod.rs +++ b/lib/src/router/mod.rs @@ -16,13 +16,13 @@ use self::pattern_trie::TrieNode; #[derive(thiserror::Error, Debug)] pub enum RouterError { #[error("Could not parse rule from frontend path {0:?}")] - UnparsablePathRule(String), + InvalidPathRule(String), #[error("parsing hostname {hostname} failed")] - UnparsableDomain { hostname: String }, + InvalidDomain { hostname: String }, #[error("Could not add route {0}")] - AddRouteFailure(String), + AddRoute(String), #[error("Could not remove route {0}")] - RemoveRouteFailure(String), + RemoveRoute(String), } pub struct Router { @@ -111,7 +111,7 @@ impl Router { pub fn add_http_front(&mut self, front: &HttpFrontend) -> Result<(), RouterError> { let path_rule = PathRule::from_config(front.path.clone()) - .ok_or(RouterError::UnparsablePathRule(front.path.to_string()))?; + .ok_or(RouterError::InvalidPathRule(front.path.to_string()))?; let method_rule = MethodRule::new(front.method.clone()); @@ -123,7 +123,7 @@ impl Router { let success = match front.position { RulePosition::Pre => { let domain = front.hostname.parse::().map_err(|_| { - RouterError::UnparsableDomain { + RouterError::InvalidDomain { hostname: front.hostname.clone(), } })?; @@ -132,7 +132,7 @@ impl Router { } RulePosition::Post => { let domain = front.hostname.parse::().map_err(|_| { - RouterError::UnparsableDomain { + RouterError::InvalidDomain { hostname: front.hostname.clone(), } })?; @@ -144,21 +144,21 @@ impl Router { } }; if !success { - return Err(RouterError::AddRouteFailure(format!("{:?}", front))); + return Err(RouterError::AddRoute(format!("{:?}", front))); } Ok(()) } pub fn remove_http_front(&mut self, front: &HttpFrontend) -> Result<(), RouterError> { let path_rule = PathRule::from_config(front.path.clone()) - .ok_or(RouterError::UnparsablePathRule(front.path.to_string()))?; + .ok_or(RouterError::InvalidPathRule(front.path.to_string()))?; let method_rule = MethodRule::new(front.method.clone()); let remove_success = match front.position { RulePosition::Pre => { let domain = front.hostname.parse::().map_err(|_| { - RouterError::UnparsableDomain { + RouterError::InvalidDomain { hostname: front.hostname.clone(), } })?; @@ -167,7 +167,7 @@ impl Router { } RulePosition::Post => { let domain = front.hostname.parse::().map_err(|_| { - RouterError::UnparsableDomain { + RouterError::InvalidDomain { hostname: front.hostname.clone(), } })?; @@ -179,7 +179,7 @@ impl Router { } }; if !remove_success { - return Err(RouterError::RemoveRouteFailure(format!("{:?}", front))); + return Err(RouterError::RemoveRoute(format!("{:?}", front))); } Ok(()) } diff --git a/lib/src/server.rs b/lib/src/server.rs index 0763bf653..7f57bd349 100644 --- a/lib/src/server.rs +++ b/lib/src/server.rs @@ -949,7 +949,7 @@ impl Server { METRICS.with(|metrics| { match (*metrics.borrow_mut()).query(query_metrics_options) { Ok(c) => push_queue(WorkerResponse::ok_with_content(message.id.clone(), c)), - Err(e) => error!("Error querying metrics: {:#}", e), + Err(e) => error!("Error querying metrics: {}", e), } }); return; @@ -962,7 +962,7 @@ impl Server { pub fn notify_proxys(&mut self, request: WorkerRequest) { if let Err(e) = self.config_state.dispatch(&request.content) { - error!("Could not execute order on config state: {:#}", e); + error!("Could not execute order on config state: {}", e); } let req_id = request.id.clone(); @@ -1087,7 +1087,7 @@ impl Server { WorkerResponse::ok(req_id) } Err(e) => { - let error = format!("Couldn't add HTTP listener: {e:#}"); + let error = format!("Couldn't add HTTP listener: {e}"); error!("{}", error); WorkerResponse::error(req_id, error) } @@ -1156,7 +1156,7 @@ impl Server { WorkerResponse::ok(req_id) } Err(e) => { - let error = format!("Couldn't add TCP listener: {e:#}"); + let error = format!("Couldn't add TCP listener: {e}"); error!("{}", error); WorkerResponse::error(req_id, error) } @@ -1193,8 +1193,8 @@ impl Server { WorkerResponse::ok(req_id) } Err(activate_error) => { - error!("Could not activate HTTP listener: {:#}", activate_error); - WorkerResponse::error(req_id, format!("{activate_error:#}")) + error!("Could not activate HTTP listener: {}", activate_error); + WorkerResponse::error(req_id, activate_error) } } } @@ -1215,8 +1215,8 @@ impl Server { WorkerResponse::ok(req_id) } Err(activate_error) => { - error!("Could not activate HTTPS listener: {:#}", activate_error); - WorkerResponse::error(req_id, format!("{activate_error:#}")) + error!("Could not activate HTTPS listener: {}", activate_error); + WorkerResponse::error(req_id, activate_error) } } } @@ -1264,11 +1264,10 @@ impl Server { { Some((token, listener)) => (token, listener), None => { - error!("Couldn't deactivate HTTP listener at address {:?}", address); - return WorkerResponse::error( - req_id, - format!("cannot deactivate HTTP listener at address {address:?}"), - ); + let error = + format!("Couldn't deactivate HTTP listener at address {address:?}"); + error!("{}", error); + return WorkerResponse::error(req_id, error); } }; @@ -1309,14 +1308,12 @@ impl Server { Some((token, listener)) => (token, listener), None => { - error!( + let error = format!( "Couldn't deactivate HTTPS listener at address {:?}", address ); - return WorkerResponse::error( - req_id, - format!("cannot deactivate HTTPS listener at address {address:?}"), - ); + error!("{}", error); + return WorkerResponse::error(req_id, error); } }; if let Err(e) = self.poll.registry().deregister(&mut listener) { @@ -1351,11 +1348,10 @@ impl Server { { Some((token, listener)) => (token, listener), None => { - error!("Couldn't deactivate TCP listener at address {:?}", address); - return WorkerResponse::error( - req_id, - format!("cannot deactivate TCP listener at address {address:?}"), - ); + let error = + format!("Couldn't deactivate TCP listener at address {:?}", address); + error!("{}", error); + return WorkerResponse::error(req_id, error); } }; diff --git a/lib/src/socket.rs b/lib/src/socket.rs index ff37cdd15..02a5b9bc5 100644 --- a/lib/src/socket.rs +++ b/lib/src/socket.rs @@ -10,19 +10,19 @@ use socket2::{Domain, Protocol, Socket, Type}; #[derive(thiserror::Error, Debug)] pub enum ServerBindError { #[error("could not set bind to socket: {0}")] - BindError(String), + BindError(std::io::Error), #[error("could not listen on socket: {0}")] - Listen(String), + Listen(std::io::Error), #[error("could not set socket to nonblocking: {0}")] - SetNonBlocking(String), + SetNonBlocking(std::io::Error), #[error("could not set reuse address: {0}")] - SetReuseAddress(String), + SetReuseAddress(std::io::Error), #[error("could not set reuse address: {0}")] - SetReusePort(String), + SetReusePort(std::io::Error), #[error("Could not create socket: {0}")] - SocketCreationError(String), - #[error("Wrong socket address '{address}': {error}")] - WrongAddress { address: String, error: String }, + SocketCreationError(std::io::Error), + #[error("Invalid socket address '{address}': {error}")] + InvalidSocketAddress { address: String, error: String }, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -378,41 +378,41 @@ impl SocketHandler for FrontRustls { } pub fn server_bind(addr: String) -> Result { - let address = - addr.parse::() - .map_err(|parse_error| ServerBindError::WrongAddress { - address: addr.clone(), - error: parse_error.to_string(), - })?; + let address = addr.parse::().map_err(|parse_error| { + ServerBindError::InvalidSocketAddress { + address: addr.clone(), + error: parse_error.to_string(), + } + })?; let sock = Socket::new( Domain::for_address(address), Type::STREAM, Some(Protocol::TCP), ) - .map_err(|io_error| ServerBindError::SocketCreationError(io_error.to_string()))?; + .map_err(|io_error| ServerBindError::SocketCreationError(io_error))?; // set so_reuseaddr, but only on unix (mirrors what libstd does) if cfg!(unix) { sock.set_reuse_address(true) - .map_err(|io_error| ServerBindError::SetReuseAddress(io_error.to_string()))?; + .map_err(|io_error| ServerBindError::SetReuseAddress(io_error))?; } sock.set_reuse_port(true) - .map_err(|io_error| ServerBindError::SetReusePort(io_error.to_string()))?; + .map_err(|io_error| ServerBindError::SetReusePort(io_error))?; // bind the socket let addr = address.into(); sock.bind(&addr) - .map_err(|io_error| ServerBindError::BindError(io_error.to_string()))?; + .map_err(|io_error| ServerBindError::BindError(io_error))?; sock.set_nonblocking(true) - .map_err(|io_error| ServerBindError::SetNonBlocking(io_error.to_string()))?; + .map_err(|io_error| ServerBindError::SetNonBlocking(io_error))?; // listen // FIXME: make the backlog configurable? sock.listen(1024) - .map_err(|io_error| ServerBindError::Listen(io_error.to_string()))?; + .map_err(|io_error| ServerBindError::Listen(io_error))?; Ok(TcpListener::from_std(sock.into())) } diff --git a/lib/src/tcp.rs b/lib/src/tcp.rs index 30de90438..cfcf856a0 100644 --- a/lib/src/tcp.rs +++ b/lib/src/tcp.rs @@ -16,7 +16,7 @@ use mio::{ }; use rusty_ulid::Ulid; use slab::Slab; -use sozu_command::proto::command::request::RequestType; +use sozu_command::{proto::command::request::RequestType, ObjectKind}; use time::{Duration, Instant}; use crate::{ @@ -585,7 +585,7 @@ impl TcpSession { } // TODO: should we return CloseSession here? Err(connection_error) => { - error!("Error connecting to backend: {:#}", connection_error) + error!("Error connecting to backend: {}", connection_error); } } } else if self.back_readiness().unwrap().event != Ready::EMPTY { @@ -607,7 +607,7 @@ impl TcpSession { return StateResult::Continue; } Err(connection_error) => { - error!("Error connecting to backend: {:#}", connection_error) + error!("Error connecting to backend: {}", connection_error) } } } @@ -669,7 +669,7 @@ impl TcpSession { return StateResult::Continue; } Err(connection_error) => { - error!("Error connecting to backend: {:#}", connection_error) + error!("Error connecting to backend: {}", connection_error) } } } @@ -826,17 +826,19 @@ impl TcpSession { .borrow() .cluster_id .clone() - .ok_or(BackendConnectionError::FoundNoTcpCluster)?; + .ok_or(BackendConnectionError::NotFound(ObjectKind::TcpCluster))?; self.cluster_id = Some(cluster_id.clone()); if self.connection_attempt >= CONN_RETRIES { error!("{} max connection attempt reached", self.log_context()); - return Err(BackendConnectionError::TooManyConnections(cluster_id)); + return Err(BackendConnectionError::MaxConnectionRetries(Some( + cluster_id, + ))); } if self.proxy.borrow().sessions.borrow().at_capacity() { - return Err(BackendConnectionError::SessionsMemoryAtCapacity); + return Err(BackendConnectionError::MaxSessionsMemory); } let (backend, mut stream) = self @@ -845,7 +847,7 @@ impl TcpSession { .backends .borrow_mut() .backend_from_cluster_id(&cluster_id) - .map_err(|backend_error| BackendConnectionError::BackendError(backend_error))?; + .map_err(|backend_error| BackendConnectionError::Backend(backend_error))?; /* this was the old error matching for backend_from_cluster_id. @@ -1107,7 +1109,7 @@ impl TcpListener { let address = config .address .parse::() - .map_err(|parse_error| ListenerError::SocketParseError { + .map_err(|parse_error| ListenerError::SocketParse { address: config.address.clone(), error: parse_error.to_string(), })?; @@ -1137,10 +1139,7 @@ impl TcpListener { let mut listener = tcp_listener.or_else(|| { server_bind(self.config.address.clone()) .map_err(|e| { - error!( - "could not create listener {:?}: {:#}", - self.config.address, e - ); + error!("could not create listener {:?}: {}", self.config.address, e); }) .ok() }); @@ -1201,7 +1200,7 @@ impl TcpProxy { match self.listeners.entry(token) { Entry::Vacant(entry) => { let tcp_listener = TcpListener::new(config, pool, token) - .map_err(|listener_error| ProxyError::AddListenerError(listener_error))?; + .map_err(|listener_error| ProxyError::AddListener(listener_error))?; entry.insert(Rc::new(RefCell::new(tcp_listener))); Ok(token) } @@ -1258,12 +1257,14 @@ impl TcpProxy { } pub fn add_tcp_front(&mut self, front: RequestTcpFrontend) -> Result<(), ProxyError> { - let address = front.address.parse::().map_err(|parse_error| { - ProxyError::SocketParseError { - address: front.address.clone(), - error: parse_error.to_string(), - } - })?; + let address = + front + .address + .parse::() + .map_err(|parse_error| ProxyError::SocketParse { + address: front.address.clone(), + error: parse_error.to_string(), + })?; let mut listener = self .listeners diff --git a/lib/src/tls.rs b/lib/src/tls.rs index 0ae873641..685da6617 100644 --- a/lib/src/tls.rs +++ b/lib/src/tls.rs @@ -153,15 +153,15 @@ impl Clone for ParsedCertificateAndKey { #[derive(thiserror::Error, Clone, Debug)] pub enum GenericCertificateResolverError { #[error("failed to parse certificate common name, {0}")] - CommonNameParseError(String), + InvalidCommonName(String), #[error("failed to parse pem certificate, {0}")] - PemParseError(String), + InvalidPem(String), #[error("failed to parse der certificate, {0}")] - DerParseError(String), + InvalidDer(String), #[error("certificate, chain or private key is invalid")] - InvalidPrivateKeyError, + InvalidPrivateKey, #[error("certificate is still in use")] - IsStillInUseError, + IsStillInUse, } // ----------------------------------------------------------------------------- @@ -244,7 +244,7 @@ impl CertificateResolver for GenericCertificateResolver { }; if self.is_required_for_domain(&names, fingerprint) { - return Err(GenericCertificateResolverError::IsStillInUseError); + return Err(GenericCertificateResolverError::IsStillInUse); } for name in &names { @@ -293,7 +293,7 @@ impl CertificateResolverHelper for GenericCertificateResolver { let x509 = pem .parse_x509() - .map_err(|err| GenericCertificateResolverError::DerParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidDer(err.to_string()))?; let mut names: HashSet = HashSet::new(); for name in x509.subject().iter_by_oid(&OID_X509_COMMON_NAME) { @@ -302,7 +302,7 @@ impl CertificateResolverHelper for GenericCertificateResolver { .as_str() .map(String::from) .map_err(|err| { - GenericCertificateResolverError::CommonNameParseError(err.to_string()) + GenericCertificateResolverError::InvalidCommonName(err.to_string()) })?, ); } @@ -313,7 +313,7 @@ impl CertificateResolverHelper for GenericCertificateResolver { .as_str() .map(String::from) .map_err(|err| { - GenericCertificateResolverError::CommonNameParseError(err.to_string()) + GenericCertificateResolverError::InvalidCommonName(err.to_string()) })?, ); } @@ -329,12 +329,12 @@ impl CertificateResolverHelper for GenericCertificateResolver { certificate_and_key: &CertificateAndKey, ) -> Result { let (_, certificate) = parse_x509_pem(certificate_and_key.certificate.as_bytes()) - .map_err(|err| GenericCertificateResolverError::PemParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidPem(err.to_string()))?; let mut chains = vec![]; for chain in &certificate_and_key.certificate_chain { let (_, chain) = parse_x509_pem(chain.as_bytes()) - .map_err(|err| GenericCertificateResolverError::PemParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidPem(err.to_string()))?; chains.push(chain); } @@ -399,7 +399,7 @@ impl CertificateResolverHelper for GenericCertificateResolver { } } - Err(GenericCertificateResolverError::InvalidPrivateKeyError) + Err(GenericCertificateResolverError::InvalidPrivateKey) } } @@ -440,7 +440,7 @@ impl GenericCertificateResolver { let x509 = parsed_certificate_and_key .certificate .parse_x509() - .map_err(|err| GenericCertificateResolverError::DerParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidDer(err.to_string()))?; // We need to know if the new certificate can replace an already existing one. let new_names = match self.get_names_override(fingerprint) { @@ -467,7 +467,7 @@ impl GenericCertificateResolver { let certificate = certificate_and_key .certificate .parse_x509() - .map_err(|err| GenericCertificateResolverError::DerParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidDer(err.to_string()))?; let certificate_names = match self.get_names_override(fingerprint) { Some(names) => names, @@ -661,7 +661,7 @@ mod tests { }; let (_, pem) = parse_x509_pem(certificate_and_key.certificate.as_bytes()) - .map_err(|err| GenericCertificateResolverError::PemParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidPem(err.to_string()))?; let fingerprint = resolver.add_certificate(&AddCertificate { address: address, @@ -675,7 +675,7 @@ mod tests { if let Err(err) = resolver.remove_certificate(&fingerprint) { match err { - GenericCertificateResolverError::IsStillInUseError => {} + GenericCertificateResolverError::IsStillInUse => {} _ => { return Err(format!("the certificate must not been removed, {err}").into()); } @@ -707,7 +707,7 @@ mod tests { }; let (_, pem) = parse_x509_pem(certificate_and_key.certificate.as_bytes()) - .map_err(|err| GenericCertificateResolverError::PemParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidPem(err.to_string()))?; let fingerprint = resolver.add_certificate(&AddCertificate { address: address, @@ -721,7 +721,7 @@ mod tests { if let Err(err) = resolver.remove_certificate(&fingerprint) { match err { - GenericCertificateResolverError::IsStillInUseError => {} + GenericCertificateResolverError::IsStillInUse => {} _ => { return Err(format!("the certificate must not been removed, {err}").into()); } @@ -766,7 +766,7 @@ mod tests { }; let (_, pem) = parse_x509_pem(certificate_and_key_1y.certificate.as_bytes()) - .map_err(|err| GenericCertificateResolverError::PemParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidPem(err.to_string()))?; let names_1y = resolver.certificate_names(&pem)?; let fingerprint_1y = resolver.add_certificate(&AddCertificate { @@ -833,7 +833,7 @@ mod tests { }; let (_, pem) = parse_x509_pem(certificate_and_key_1y.certificate.as_bytes()) - .map_err(|err| GenericCertificateResolverError::PemParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidPem(err.to_string()))?; let names_1y = resolver.certificate_names(&pem)?; let fingerprint_1y = resolver.add_certificate(&AddCertificate { @@ -930,7 +930,7 @@ mod tests { let mut fingerprints = vec![]; for certificate in &certificates { let (_, pem) = parse_x509_pem(certificate.certificate.as_bytes()) - .map_err(|err| GenericCertificateResolverError::PemParseError(err.to_string()))?; + .map_err(|err| GenericCertificateResolverError::InvalidPem(err.to_string()))?; fingerprints.push(GenericCertificateResolver::fingerprint(&pem)); }