Properly handle errors in write

This commit is contained in:
Steven Fackler 2015-02-16 22:38:34 -08:00
parent f0eb8e39e3
commit e52d02171b
1 changed files with 29 additions and 18 deletions

View File

@ -38,19 +38,19 @@ fn init() {
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum SslMethod { pub enum SslMethod {
#[cfg(feature = "sslv2")] #[cfg(feature = "sslv2")]
/// Only support the SSLv2 protocol, requires `feature="sslv2"` /// Only support the SSLv2 protocol, requires the `sslv2` feature.
Sslv2, Sslv2,
/// Support the SSLv2, SSLv3 and TLSv1 protocols /// Support the SSLv2, SSLv3 and TLSv1 protocols.
Sslv23, Sslv23,
/// Only support the SSLv3 protocol /// Only support the SSLv3 protocol.
Sslv3, Sslv3,
/// Only support the TLSv1 protocol /// Only support the TLSv1 protocol.
Tlsv1, Tlsv1,
#[cfg(feature = "tlsv1_1")] #[cfg(feature = "tlsv1_1")]
/// Support TLSv1.1 protocol, requires `feature="tlsv1_1"` /// Support TLSv1.1 protocol, requires the `tlsv1_1` feature.
Tlsv1_1, Tlsv1_1,
#[cfg(feature = "tlsv1_2")] #[cfg(feature = "tlsv1_2")]
/// Support TLSv1.2 protocol, requires `feature="tlsv1_2"` /// Support TLSv1.2 protocol, requires the `tlsv1_2` feature.
Tlsv1_2, Tlsv1_2,
} }
@ -552,17 +552,18 @@ impl<S: Stream> Reader for SslStream<S> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
match self.in_retry_wrapper(|ssl| { ssl.read(buf) }) { match self.in_retry_wrapper(|ssl| { ssl.read(buf) }) {
Ok(len) => Ok(len as usize), Ok(len) => Ok(len as usize),
Err(SslSessionClosed) => Err(SslSessionClosed) => {
Err(IoError { Err(IoError {
kind: EndOfFile, kind: EndOfFile,
desc: "SSL session closed", desc: "SSL session closed",
detail: None detail: None
}), })
}
Err(StreamError(e)) => Err(e), Err(StreamError(e)) => Err(e),
Err(e @ OpenSslErrors(_)) => { Err(e @ OpenSslErrors(_)) => {
Err(IoError { Err(IoError {
kind: OtherIoError, kind: OtherIoError,
desc: "SSL error", desc: "OpenSSL error",
detail: Some(format!("{}", e)), detail: Some(format!("{}", e)),
}) })
} }
@ -571,15 +572,25 @@ impl<S: Stream> Reader for SslStream<S> {
} }
impl<S: Stream> Writer for SslStream<S> { impl<S: Stream> Writer for SslStream<S> {
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> { fn write_all(&mut self, mut buf: &[u8]) -> IoResult<()> {
let mut start = 0; while !buf.is_empty() {
while start < buf.len() { match self.in_retry_wrapper(|ssl| ssl.write_all(buf)) {
let ret = self.in_retry_wrapper(|ssl| { Ok(len) => buf = &buf[len as usize..],
ssl.write_all(buf.split_at(start).1) Err(SslSessionClosed) => {
}); return Err(IoError {
match ret { kind: EndOfFile,
Ok(len) => start += len as usize, desc: "SSL session closed",
_ => unreachable!() detail: None,
});
}
Err(StreamError(e)) => return Err(e),
Err(e @ OpenSslErrors(_)) => {
return Err(IoError {
kind: OtherIoError,
desc: "OpenSSL error",
detail: Some(format!("{}", e)),
});
}
} }
try!(self.write_through()); try!(self.write_through());
} }