Update OpenSSL to 0.9.

This commit is contained in:
Manish Goregaokar 2017-06-19 14:11:57 -04:00 committed by Aaron Weiss
parent a4f1675394
commit 02f9968b0c
No known key found for this signature in database
GPG key ID: 0237035D9BF03AE2
3 changed files with 40 additions and 44 deletions

View file

@ -30,10 +30,13 @@ version = "1.0.8"
[dependencies.time] [dependencies.time]
version = "0.1" version = "0.1"
[dependencies.bufstream]
version = "0.1"
[dependencies.encoding] [dependencies.encoding]
version = "0.2" version = "0.2"
optional = true optional = true
[dependencies.openssl] [dependencies.openssl]
version = "0.7" version = "0.9"
optional = true optional = true

View file

@ -2,7 +2,7 @@
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
use std::error::Error as StdError; use std::error::Error as StdError;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::{BufReader, BufWriter, Cursor, Result}; use std::io::{Cursor, Result};
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
use std::io::Error; use std::io::Error;
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
@ -11,14 +11,15 @@ use std::net::TcpStream;
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
use std::result::Result as StdResult; use std::result::Result as StdResult;
use std::sync::Mutex; use std::sync::Mutex;
use bufstream::BufStream;
#[cfg(feature = "encode")] #[cfg(feature = "encode")]
use encoding::DecoderTrap; use encoding::DecoderTrap;
#[cfg(feature = "encode")] #[cfg(feature = "encode")]
use encoding::label::encoding_from_whatwg_label; use encoding::label::encoding_from_whatwg_label;
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
use openssl::ssl::{SslContext, SslMethod, SslStream}; use openssl::ssl::{SslConnectorBuilder, SslMethod, SslStream};
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
use openssl::ssl::error::SslError; use openssl::ssl::HandshakeError;
/// A connection. /// A connection.
pub trait Connection { pub trait Connection {
@ -54,67 +55,59 @@ pub trait Connection {
/// Useful internal type definitions. /// Useful internal type definitions.
type NetReader = BufReader<NetStream>; type NetBufStream = BufStream<NetStream>;
type NetWriter = BufWriter<NetStream>;
type NetReadWritePair = (NetReader, NetWriter);
/// A thread-safe connection over a buffered `NetStream`. /// A thread-safe connection over a buffered `NetStream`.
pub struct NetConnection { pub struct NetConnection {
host: Mutex<String>, host: Mutex<String>,
port: Mutex<u16>, port: Mutex<u16>,
reader: Mutex<NetReader>, stream: Mutex<NetBufStream>,
writer: Mutex<NetWriter>,
} }
impl NetConnection { impl NetConnection {
fn new(host: &str, port: u16, reader: NetReader, writer: NetWriter) -> NetConnection { fn new(host: &str, port: u16, stream: NetBufStream) -> NetConnection {
NetConnection { NetConnection {
host: Mutex::new(host.to_owned()), host: Mutex::new(host.to_owned()),
port: Mutex::new(port), port: Mutex::new(port),
reader: Mutex::new(reader), stream: Mutex::new(stream),
writer: Mutex::new(writer),
} }
} }
/// Creates a thread-safe TCP connection to the specified server. /// Creates a thread-safe TCP connection to the specified server.
pub fn connect(host: &str, port: u16) -> Result<NetConnection> { pub fn connect(host: &str, port: u16) -> Result<NetConnection> {
let (reader, writer) = try!(NetConnection::connect_internal(host, port)); let stream = try!(NetConnection::connect_internal(host, port));
Ok(NetConnection::new(host, port, reader, writer)) Ok(NetConnection::new(host, port, stream))
} }
/// connects to the specified server and returns a reader-writer pair. /// connects to the specified server and returns a reader-writer pair.
fn connect_internal(host: &str, port: u16) -> Result<NetReadWritePair> { fn connect_internal(host: &str, port: u16) -> Result<NetBufStream> {
let socket = try!(TcpStream::connect(&format!("{}:{}", host, port)[..])); let socket = try!(TcpStream::connect((host, port)));
Ok(( Ok(BufStream::new(NetStream::Unsecured(socket)))
BufReader::new(
NetStream::Unsecured(try!(socket.try_clone())),
),
BufWriter::new(NetStream::Unsecured(socket)),
))
} }
/// Creates a thread-safe TCP connection to the specified server over SSL. /// Creates a thread-safe TCP connection to the specified server over SSL.
/// If the library is compiled without SSL support, this method panics. /// If the library is compiled without SSL support, this method panics.
pub fn connect_ssl(host: &str, port: u16) -> Result<NetConnection> { pub fn connect_ssl(host: &str, port: u16) -> Result<NetConnection> {
let (reader, writer) = try!(NetConnection::connect_ssl_internal(host, port)); let stream = try!(NetConnection::connect_ssl_internal(host, port));
Ok(NetConnection::new(host, port, reader, writer)) Ok(NetConnection::new(host, port, stream))
} }
/// Connects over SSL to the specified server and returns a reader-writer pair. /// Connects over SSL to the specified server and returns a reader-writer pair.
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
fn connect_ssl_internal(host: &str, port: u16) -> Result<NetReadWritePair> { fn connect_ssl_internal(host: &str, port: u16) -> Result<NetBufStream> {
let socket = try!(TcpStream::connect(&format!("{}:{}", host, port)[..])); let domain = format!("{}:{}", host, port);
let ssl = try!(ssl_to_io(SslContext::new(SslMethod::Sslv23))); let socket = try!(TcpStream::connect((host, port)));
let ssl_socket = try!(ssl_to_io(SslStream::connect_generic(&ssl, socket))); let connector = try!(ssl_to_io(
Ok(( SslConnectorBuilder::new(SslMethod::tls())
BufReader::new(NetStream::Ssl(try!(ssl_socket.try_clone()))), .map(|c| c.build())
BufWriter::new(NetStream::Ssl(ssl_socket)), .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. /// Panics because SSL support is not compiled in.
#[cfg(not(feature = "ssl"))] #[cfg(not(feature = "ssl"))]
fn connect_ssl_internal(host: &str, port: u16) -> Result<NetReadWritePair> { fn connect_ssl_internal(host: &str, port: u16) -> Result<NetStream> {
panic!( panic!(
"Cannot connect to {}:{} over SSL without compiling with SSL support.", "Cannot connect to {}:{} over SSL without compiling with SSL support.",
host, host,
@ -123,9 +116,9 @@ impl NetConnection {
} }
} }
/// Converts a `Result<T, SslError>` into an `io::Result<T>`. /// Converts a Result<T, SslError> into an Result<T>.
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
fn ssl_to_io<T>(res: StdResult<T, SslError>) -> Result<T> { fn ssl_to_io<T>(res: StdResult<T, HandshakeError<TcpStream>>) -> Result<T> {
match res { match res {
Ok(x) => Ok(x), Ok(x) => Ok(x),
Err(e) => Err(Error::new( Err(e) => Err(Error::new(
@ -138,22 +131,22 @@ fn ssl_to_io<T>(res: StdResult<T, SslError>) -> Result<T> {
impl Connection for NetConnection { impl Connection for NetConnection {
#[cfg(feature = "encode")] #[cfg(feature = "encode")]
fn send(&self, msg: &str, encoding: &str) -> Result<()> { fn send(&self, msg: &str, encoding: &str) -> Result<()> {
imp::send(&self.writer, msg, encoding) imp::send(&self.stream, msg, encoding)
} }
#[cfg(not(feature = "encode"))] #[cfg(not(feature = "encode"))]
fn send(&self, msg: &str) -> Result<()> { fn send(&self, msg: &str) -> Result<()> {
imp::send(&self.writer, msg) imp::send(&self.stream, msg)
} }
#[cfg(feature = "encoding")] #[cfg(feature = "encoding")]
fn recv(&self, encoding: &str) -> Result<String> { fn recv(&self, encoding: &str) -> Result<String> {
imp::recv(&self.reader, encoding) imp::recv(&self.stream, encoding)
} }
#[cfg(not(feature = "encoding"))] #[cfg(not(feature = "encoding"))]
fn recv(&self) -> Result<String> { fn recv(&self) -> Result<String> {
imp::recv(&self.reader) imp::recv(&self.stream)
} }
#[cfg(feature = "encoding")] #[cfg(feature = "encoding")]
@ -167,20 +160,19 @@ impl Connection for NetConnection {
} }
fn reconnect(&self) -> Result<()> { 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, NetStream::Unsecured(_) => false,
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
NetStream::Ssl(_) => true, NetStream::Ssl(_) => true,
}; };
let host = self.host.lock().unwrap(); let host = self.host.lock().unwrap();
let port = self.port.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)) try!(NetConnection::connect_ssl_internal(&host, *port))
} else { } else {
try!(NetConnection::connect_internal(&host, *port)) try!(NetConnection::connect_internal(&host, *port))
}; };
*self.reader.lock().unwrap() = reader; *self.stream.lock().unwrap() = stream;
*self.writer.lock().unwrap() = writer;
Ok(()) Ok(())
} }
} }

View file

@ -3,6 +3,7 @@
#![warn(missing_docs)] #![warn(missing_docs)]
extern crate time; extern crate time;
extern crate bufstream;
#[cfg(feature = "encode")] #[cfg(feature = "encode")]
extern crate encoding; extern crate encoding;
extern crate serde; extern crate serde;