Update OpenSSL to 0.9.
This commit is contained in:
parent
a4f1675394
commit
02f9968b0c
3 changed files with 40 additions and 44 deletions
|
@ -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
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue