aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/ssl/error.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-08-11 21:01:27 -0700
committerSteven Fackler <[email protected]>2016-08-11 21:01:27 -0700
commit652326003cefe215dbfc838051e6114515cc5190 (patch)
tree22dc99a726321cd8228004c34c40ca4a0648c594 /openssl/src/ssl/error.rs
parentMerge branch 'release-v0.7.14' into release (diff)
parentRelease openssl-sys v0.7.15, openssl v0.8.0 (diff)
downloadrust-openssl-openssl-v0.8.0.tar.xz
rust-openssl-openssl-v0.8.0.zip
Merge branch 'release-v0.7.15-sys-v0.8.0' into releaseopenssl-v0.8.0openssl-sys-v0.7.15
Diffstat (limited to 'openssl/src/ssl/error.rs')
-rw-r--r--openssl/src/ssl/error.rs274
1 files changed, 10 insertions, 264 deletions
diff --git a/openssl/src/ssl/error.rs b/openssl/src/ssl/error.rs
index 2459a473..95213361 100644
--- a/openssl/src/ssl/error.rs
+++ b/openssl/src/ssl/error.rs
@@ -1,15 +1,8 @@
-pub use self::SslError::*;
-pub use self::OpensslError::*;
-
-use libc::c_ulong;
use std::error;
use std::error::Error as StdError;
use std::fmt;
-use std::ffi::CStr;
use std::io;
-use std::str;
-
-use ffi;
+use error::ErrorStack;
/// An SSL error.
#[derive(Debug)]
@@ -27,30 +20,16 @@ pub enum Error {
/// An error reported by the underlying stream.
Stream(io::Error),
/// An error in the OpenSSL library.
- Ssl(Vec<OpenSslError>),
+ Ssl(ErrorStack),
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(fmt.write_str(self.description()));
- match *self {
- Error::Stream(ref err) => write!(fmt, ": {}", err),
- Error::WantRead(ref err) => write!(fmt, ": {}", err),
- Error::WantWrite(ref err) => write!(fmt, ": {}", err),
- Error::Ssl(ref errs) => {
- let mut first = true;
- for err in errs {
- if first {
- try!(fmt.write_str(": "));
- first = false;
- } else {
- try!(fmt.write_str(", "));
- }
- try!(fmt.write_str(&err.reason()))
- }
- Ok(())
- }
- _ => Ok(()),
+ if let Some(err) = self.cause() {
+ write!(fmt, ": {}", err)
+ } else {
+ Ok(())
}
}
}
@@ -72,247 +51,14 @@ impl error::Error for Error {
Error::WantRead(ref err) => Some(err),
Error::WantWrite(ref err) => Some(err),
Error::Stream(ref err) => Some(err),
+ Error::Ssl(ref err) => Some(err),
_ => None,
}
}
}
-/// An error reported from OpenSSL.
-pub struct OpenSslError(c_ulong);
-
-impl OpenSslError {
- /// Returns the contents of the OpenSSL error stack.
- pub fn get_stack() -> Vec<OpenSslError> {
- ffi::init();
-
- let mut errs = vec![];
- loop {
- match unsafe { ffi::ERR_get_error() } {
- 0 => break,
- err => errs.push(OpenSslError(err)),
- }
- }
- errs
- }
-
- /// Returns the raw OpenSSL error code for this error.
- pub fn error_code(&self) -> c_ulong {
- self.0
- }
-
- /// Returns the name of the library reporting the error.
- pub fn library(&self) -> &'static str {
- get_lib(self.0)
- }
-
- /// Returns the name of the function reporting the error.
- pub fn function(&self) -> &'static str {
- get_func(self.0)
- }
-
- /// Returns the reason for the error.
- pub fn reason(&self) -> &'static str {
- get_reason(self.0)
- }
-}
-
-impl fmt::Debug for OpenSslError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt.debug_struct("OpenSslError")
- .field("library", &self.library())
- .field("function", &self.function())
- .field("reason", &self.reason())
- .finish()
- }
-}
-
-impl fmt::Display for OpenSslError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt.write_str(&self.reason())
- }
-}
-
-impl error::Error for OpenSslError {
- fn description(&self) -> &str {
- "An OpenSSL error"
- }
-}
-
-/// An SSL error
-#[derive(Debug)]
-pub enum SslError {
- /// The underlying stream reported an error
- StreamError(io::Error),
- /// The SSL session has been closed by the other end
- SslSessionClosed,
- /// An error in the OpenSSL library
- OpenSslErrors(Vec<OpensslError>),
-}
-
-/// An error on a nonblocking stream.
-#[derive(Debug)]
-pub enum NonblockingSslError {
- /// A standard SSL error occurred.
- SslError(SslError),
- /// The OpenSSL library wants data from the remote socket;
- /// the caller should wait for read readiness.
- WantRead,
- /// The OpenSSL library wants to send data to the remote socket;
- /// the caller should wait for write readiness.
- WantWrite,
-}
-
-impl fmt::Display for SslError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- try!(fmt.write_str(error::Error::description(self)));
- if let OpenSslErrors(ref errs) = *self {
- let mut first = true;
- for err in errs {
- if first {
- try!(fmt.write_str(": "));
- first = false;
- } else {
- try!(fmt.write_str(", "));
- }
- match *err {
- UnknownError { ref reason, .. } => try!(fmt.write_str(reason)),
- }
- }
- }
-
- Ok(())
- }
-}
-
-impl error::Error for SslError {
- fn description(&self) -> &str {
- match *self {
- StreamError(_) => "The underlying stream reported an error",
- SslSessionClosed => "The SSL session has been closed by the other end",
- OpenSslErrors(_) => "An error in the OpenSSL library",
- }
+impl From<ErrorStack> for Error {
+ fn from(e: ErrorStack) -> Error {
+ Error::Ssl(e)
}
-
- fn cause(&self) -> Option<&error::Error> {
- match *self {
- StreamError(ref err) => Some(err as &error::Error),
- _ => None,
- }
- }
-}
-
-impl fmt::Display for NonblockingSslError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt.write_str(error::Error::description(self))
- }
-}
-
-impl error::Error for NonblockingSslError {
- fn description(&self) -> &str {
- match *self {
- NonblockingSslError::SslError(ref e) => e.description(),
- NonblockingSslError::WantRead => {
- "The OpenSSL library wants data from the remote socket"
- }
- NonblockingSslError::WantWrite => {
- "The OpenSSL library want to send data to the remote socket"
- }
- }
- }
-
- fn cause(&self) -> Option<&error::Error> {
- match *self {
- NonblockingSslError::SslError(ref e) => e.cause(),
- _ => None,
- }
- }
-}
-
-impl From<SslError> for NonblockingSslError {
- fn from(e: SslError) -> NonblockingSslError {
- NonblockingSslError::SslError(e)
- }
-}
-
-/// An error from the OpenSSL library
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum OpensslError {
- /// An unknown error
- UnknownError {
- /// The library reporting the error
- library: String,
- /// The function reporting the error
- function: String,
- /// The reason for the error
- reason: String,
- },
-}
-
-impl OpensslError {
- pub fn from_error_code(err: c_ulong) -> OpensslError {
- ffi::init();
- UnknownError {
- library: get_lib(err).to_owned(),
- function: get_func(err).to_owned(),
- reason: get_reason(err).to_owned(),
- }
- }
-}
-
-fn get_lib(err: c_ulong) -> &'static str {
- unsafe {
- let cstr = ffi::ERR_lib_error_string(err);
- let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
- str::from_utf8(bytes).unwrap()
- }
-}
-
-fn get_func(err: c_ulong) -> &'static str {
- unsafe {
- let cstr = ffi::ERR_func_error_string(err);
- let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
- str::from_utf8(bytes).unwrap()
- }
-}
-
-fn get_reason(err: c_ulong) -> &'static str {
- unsafe {
- let cstr = ffi::ERR_reason_error_string(err);
- let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
- str::from_utf8(bytes).unwrap()
- }
-}
-
-impl SslError {
- /// Creates a new `OpenSslErrors` with the current contents of the error
- /// stack.
- pub fn get() -> SslError {
- let mut errs = vec![];
- loop {
- match unsafe { ffi::ERR_get_error() } {
- 0 => break,
- err => errs.push(OpensslError::from_error_code(err)),
- }
- }
- OpenSslErrors(errs)
- }
-
- /// Creates an `SslError` from the raw numeric error code.
- pub fn from_error(err: c_ulong) -> SslError {
- OpenSslErrors(vec![OpensslError::from_error_code(err)])
- }
-}
-
-#[test]
-fn test_uknown_error_should_have_correct_messages() {
- let errs = match SslError::from_error(336032784) {
- OpenSslErrors(errs) => errs,
- _ => panic!("This should always be an `OpenSslErrors` variant."),
- };
-
- let UnknownError { ref library, ref function, ref reason } = errs[0];
-
- assert_eq!(&library[..], "SSL routines");
- assert_eq!(&function[..], "SSL23_GET_SERVER_HELLO");
- assert_eq!(&reason[..], "sslv3 alert handshake failure");
}