1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use std::any::Any;
use std::error;
use std::error::Error as StdError;
use std::fmt;
use std::io;
use error::ErrorStack;
use ssl::MidHandshakeSslStream;
#[derive(Debug)]
pub enum Error {
ZeroReturn,
WantRead(io::Error),
WantWrite(io::Error),
WantX509Lookup,
Stream(io::Error),
Ssl(ErrorStack),
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(self.description())?;
if let Some(err) = self.cause() {
write!(fmt, ": {}", err)
} else {
Ok(())
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::ZeroReturn => "The SSL session was closed by the other end",
Error::WantRead(_) => "A read attempt returned a `WouldBlock` error",
Error::WantWrite(_) => "A write attempt returned a `WouldBlock` error",
Error::WantX509Lookup => "The client certificate callback requested to be called again",
Error::Stream(_) => "The underlying stream reported an error",
Error::Ssl(_) => "The OpenSSL library reported an error",
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
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,
}
}
}
impl From<ErrorStack> for Error {
fn from(e: ErrorStack) -> Error {
Error::Ssl(e)
}
}
#[derive(Debug)]
pub struct RetryError;
impl fmt::Display for RetryError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(error::Error::description(self))
}
}
impl error::Error for RetryError {
fn description(&self) -> &str {
"operation must be retried"
}
}
#[derive(Debug)]
pub enum HandshakeError<S> {
SetupFailure(ErrorStack),
Failure(MidHandshakeSslStream<S>),
Interrupted(MidHandshakeSslStream<S>),
}
impl<S: Any + fmt::Debug> StdError for HandshakeError<S> {
fn description(&self) -> &str {
match *self {
HandshakeError::SetupFailure(_) => "stream setup failed",
HandshakeError::Failure(_) => "the handshake failed",
HandshakeError::Interrupted(_) => "the handshake was interrupted",
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
HandshakeError::SetupFailure(ref e) => Some(e),
HandshakeError::Failure(ref s) |
HandshakeError::Interrupted(ref s) => Some(s.error()),
}
}
}
impl<S: Any + fmt::Debug> fmt::Display for HandshakeError<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(StdError::description(self))?;
match *self {
HandshakeError::SetupFailure(ref e) => write!(f, ": {}", e)?,
HandshakeError::Failure(ref s) |
HandshakeError::Interrupted(ref s) => {
write!(f, ": {}", s.error())?;
if let Some(err) = s.ssl().verify_result() {
write!(f, ": {}", err)?;
}
}
}
Ok(())
}
}
impl<S> From<ErrorStack> for HandshakeError<S> {
fn from(e: ErrorStack) -> HandshakeError<S> {
HandshakeError::SetupFailure(e)
}
}