trying to flesh out Transport and the SslTransport implementation of it
This commit is contained in:
parent
12cbd17da7
commit
e5d549d1fe
2 changed files with 62 additions and 5 deletions
|
@ -6,10 +6,12 @@ use openssl::ssl::HandshakeError;
|
|||
use openssl::error::ErrorStack;
|
||||
|
||||
use xml::reader::Error as XmlError;
|
||||
use xml::writer::Error as EmitterError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
XmlError(XmlError),
|
||||
EmitterError(EmitterError),
|
||||
IoError(io::Error),
|
||||
HandshakeError(HandshakeError<TcpStream>),
|
||||
OpenSslErrorStack(ErrorStack),
|
||||
|
@ -22,6 +24,12 @@ impl From<XmlError> for Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<EmitterError> for Error {
|
||||
fn from(err: EmitterError) -> Error {
|
||||
Error::EmitterError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(err: io::Error) -> Error {
|
||||
Error::IoError(err)
|
||||
|
|
|
@ -3,7 +3,10 @@ use std::io;
|
|||
|
||||
use std::net::{SocketAddr, TcpStream};
|
||||
|
||||
use xml::reader::{EventReader, XmlEvent};
|
||||
use xml::reader::{EventReader, XmlEvent as XmlReaderEvent};
|
||||
use xml::writer::{EventWriter, XmlEvent as XmlWriterEvent};
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use ns;
|
||||
|
||||
|
@ -11,8 +14,50 @@ use error::Error;
|
|||
|
||||
use openssl::ssl::{SslMethod, SslConnectorBuilder, SslStream};
|
||||
|
||||
pub trait Transport {
|
||||
fn write_event<'a, E: Into<XmlWriterEvent<'a>>>(&mut self, event: E) -> Result<(), Error>;
|
||||
fn read_event(&mut self) -> Result<XmlReaderEvent, Error>;
|
||||
}
|
||||
|
||||
struct LockedWrite<W: Write>(Arc<Mutex<W>>);
|
||||
|
||||
impl<W: Write> io::Write for LockedWrite<W> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let mut inner = self.0.lock().unwrap(); // TODO: make safer
|
||||
inner.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
let mut inner = self.0.lock().unwrap(); // TODO: make safer
|
||||
inner.flush()
|
||||
}
|
||||
}
|
||||
|
||||
struct LockedRead<R: Read>(Arc<Mutex<R>>);
|
||||
|
||||
impl<R: Read> io::Read for LockedRead<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let mut inner = self.0.lock().unwrap(); // TODO: make safer
|
||||
inner.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SslTransport {
|
||||
inner: SslStream<TcpStream>,
|
||||
inner: Arc<Mutex<SslStream<TcpStream>>>, // TODO: this feels rather ugly
|
||||
reader: EventReader<LockedRead<SslStream<TcpStream>>>, // TODO: especially feels ugly because
|
||||
// this read would keep the lock
|
||||
// held very long (potentially)
|
||||
writer: EventWriter<LockedWrite<SslStream<TcpStream>>>,
|
||||
}
|
||||
|
||||
impl Transport for SslTransport {
|
||||
fn write_event<'a, E: Into<XmlWriterEvent<'a>>>(&mut self, event: E) -> Result<(), Error> {
|
||||
Ok(self.writer.write(event)?)
|
||||
}
|
||||
|
||||
fn read_event(&mut self) -> Result<XmlReaderEvent, Error> {
|
||||
Ok(self.reader.next()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl SslTransport {
|
||||
|
@ -26,7 +71,7 @@ impl SslTransport {
|
|||
let mut parser = EventReader::new(stream);
|
||||
loop { // TODO: possibly a timeout?
|
||||
match parser.next()? {
|
||||
XmlEvent::StartElement { name, namespace, .. } => {
|
||||
XmlReaderEvent::StartElement { name, namespace, .. } => {
|
||||
if let Some(ns) = name.namespace {
|
||||
if ns == ns::TLS && name.local_name == "proceed" {
|
||||
break;
|
||||
|
@ -41,9 +86,13 @@ impl SslTransport {
|
|||
}
|
||||
let stream = parser.into_inner();
|
||||
let ssl_connector = SslConnectorBuilder::new(SslMethod::tls())?.build();
|
||||
let ssl_stream = ssl_connector.connect(host, stream)?;
|
||||
let ssl_stream = Arc::new(Mutex::new(ssl_connector.connect(host, stream)?));
|
||||
let reader = EventReader::new(LockedRead(ssl_stream.clone()));
|
||||
let writer = EventWriter::new(LockedWrite(ssl_stream.clone()));
|
||||
Ok(SslTransport {
|
||||
inner: ssl_stream
|
||||
inner: ssl_stream,
|
||||
reader: reader,
|
||||
writer: writer,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue