From 02f9968b0cdc2754a0659bcd9f83fc5e2c5cd736 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 19 Jun 2017 14:11:57 -0400 Subject: [PATCH] Update OpenSSL to 0.9. --- Cargo.toml | 5 ++- src/client/conn.rs | 78 +++++++++++++++++++++------------------------- src/lib.rs | 1 + 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1c096a3..2839b10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,10 +30,13 @@ version = "1.0.8" [dependencies.time] version = "0.1" +[dependencies.bufstream] +version = "0.1" + [dependencies.encoding] version = "0.2" optional = true [dependencies.openssl] -version = "0.7" +version = "0.9" optional = true diff --git a/src/client/conn.rs b/src/client/conn.rs index 7a61bb7..3c7b3f2 100644 --- a/src/client/conn.rs +++ b/src/client/conn.rs @@ -2,7 +2,7 @@ #[cfg(feature = "ssl")] use std::error::Error as StdError; use std::io::prelude::*; -use std::io::{BufReader, BufWriter, Cursor, Result}; +use std::io::{Cursor, Result}; #[cfg(feature = "ssl")] use std::io::Error; #[cfg(feature = "ssl")] @@ -11,14 +11,15 @@ use std::net::TcpStream; #[cfg(feature = "ssl")] use std::result::Result as StdResult; use std::sync::Mutex; +use bufstream::BufStream; #[cfg(feature = "encode")] use encoding::DecoderTrap; #[cfg(feature = "encode")] use encoding::label::encoding_from_whatwg_label; #[cfg(feature = "ssl")] -use openssl::ssl::{SslContext, SslMethod, SslStream}; +use openssl::ssl::{SslConnectorBuilder, SslMethod, SslStream}; #[cfg(feature = "ssl")] -use openssl::ssl::error::SslError; +use openssl::ssl::HandshakeError; /// A connection. pub trait Connection { @@ -54,67 +55,59 @@ pub trait Connection { /// Useful internal type definitions. -type NetReader = BufReader; -type NetWriter = BufWriter; -type NetReadWritePair = (NetReader, NetWriter); +type NetBufStream = BufStream; /// A thread-safe connection over a buffered `NetStream`. pub struct NetConnection { host: Mutex, port: Mutex, - reader: Mutex, - writer: Mutex, + stream: Mutex, } - impl NetConnection { - fn new(host: &str, port: u16, reader: NetReader, writer: NetWriter) -> NetConnection { + fn new(host: &str, port: u16, stream: NetBufStream) -> NetConnection { NetConnection { host: Mutex::new(host.to_owned()), port: Mutex::new(port), - reader: Mutex::new(reader), - writer: Mutex::new(writer), + stream: Mutex::new(stream), } } /// Creates a thread-safe TCP connection to the specified server. pub fn connect(host: &str, port: u16) -> Result { - let (reader, writer) = try!(NetConnection::connect_internal(host, port)); - Ok(NetConnection::new(host, port, reader, writer)) + let stream = try!(NetConnection::connect_internal(host, port)); + Ok(NetConnection::new(host, port, stream)) } /// connects to the specified server and returns a reader-writer pair. - fn connect_internal(host: &str, port: u16) -> Result { - let socket = try!(TcpStream::connect(&format!("{}:{}", host, port)[..])); - Ok(( - BufReader::new( - NetStream::Unsecured(try!(socket.try_clone())), - ), - BufWriter::new(NetStream::Unsecured(socket)), - )) + fn connect_internal(host: &str, port: u16) -> Result { + let socket = try!(TcpStream::connect((host, port))); + Ok(BufStream::new(NetStream::Unsecured(socket))) } /// Creates a thread-safe TCP connection to the specified server over SSL. /// If the library is compiled without SSL support, this method panics. pub fn connect_ssl(host: &str, port: u16) -> Result { - let (reader, writer) = try!(NetConnection::connect_ssl_internal(host, port)); - Ok(NetConnection::new(host, port, reader, writer)) + let stream = try!(NetConnection::connect_ssl_internal(host, port)); + Ok(NetConnection::new(host, port, stream)) } /// Connects over SSL to the specified server and returns a reader-writer pair. #[cfg(feature = "ssl")] - fn connect_ssl_internal(host: &str, port: u16) -> Result { - let socket = try!(TcpStream::connect(&format!("{}:{}", host, port)[..])); - let ssl = try!(ssl_to_io(SslContext::new(SslMethod::Sslv23))); - let ssl_socket = try!(ssl_to_io(SslStream::connect_generic(&ssl, socket))); - Ok(( - BufReader::new(NetStream::Ssl(try!(ssl_socket.try_clone()))), - BufWriter::new(NetStream::Ssl(ssl_socket)), - )) + fn connect_ssl_internal(host: &str, port: u16) -> Result { + let domain = format!("{}:{}", host, port); + let socket = try!(TcpStream::connect((host, port))); + let connector = try!(ssl_to_io( + SslConnectorBuilder::new(SslMethod::tls()) + .map(|c| c.build()) + .map_err(Into::into), + )); + let stream = try!(ssl_to_io(connector.connect(&domain, socket))); + Ok(BufStream::new(NetStream::Ssl(stream))) } /// Panics because SSL support is not compiled in. #[cfg(not(feature = "ssl"))] - fn connect_ssl_internal(host: &str, port: u16) -> Result { + fn connect_ssl_internal(host: &str, port: u16) -> Result { panic!( "Cannot connect to {}:{} over SSL without compiling with SSL support.", host, @@ -123,9 +116,9 @@ impl NetConnection { } } -/// Converts a `Result` into an `io::Result`. +/// Converts a Result into an Result. #[cfg(feature = "ssl")] -fn ssl_to_io(res: StdResult) -> Result { +fn ssl_to_io(res: StdResult>) -> Result { match res { Ok(x) => Ok(x), Err(e) => Err(Error::new( @@ -138,22 +131,22 @@ fn ssl_to_io(res: StdResult) -> Result { impl Connection for NetConnection { #[cfg(feature = "encode")] fn send(&self, msg: &str, encoding: &str) -> Result<()> { - imp::send(&self.writer, msg, encoding) + imp::send(&self.stream, msg, encoding) } #[cfg(not(feature = "encode"))] fn send(&self, msg: &str) -> Result<()> { - imp::send(&self.writer, msg) + imp::send(&self.stream, msg) } #[cfg(feature = "encoding")] fn recv(&self, encoding: &str) -> Result { - imp::recv(&self.reader, encoding) + imp::recv(&self.stream, encoding) } #[cfg(not(feature = "encoding"))] fn recv(&self) -> Result { - imp::recv(&self.reader) + imp::recv(&self.stream) } #[cfg(feature = "encoding")] @@ -167,20 +160,19 @@ impl Connection for NetConnection { } fn reconnect(&self) -> Result<()> { - let use_ssl = match *self.reader.lock().unwrap().get_ref() { + let use_ssl = match *self.stream.lock().unwrap().get_ref() { NetStream::Unsecured(_) => false, #[cfg(feature = "ssl")] NetStream::Ssl(_) => true, }; let host = self.host.lock().unwrap(); let port = self.port.lock().unwrap(); - let (reader, writer) = if use_ssl { + let stream = if use_ssl { try!(NetConnection::connect_ssl_internal(&host, *port)) } else { try!(NetConnection::connect_internal(&host, *port)) }; - *self.reader.lock().unwrap() = reader; - *self.writer.lock().unwrap() = writer; + *self.stream.lock().unwrap() = stream; Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index 83b0e29..30a6c43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ #![warn(missing_docs)] extern crate time; +extern crate bufstream; #[cfg(feature = "encode")] extern crate encoding; extern crate serde;