Merge pull request #762 from sfackler/security-framework
Add SslClient and SslServer implementations for security-framework
This commit is contained in:
@@ -32,6 +32,10 @@ default-features = false
|
|||||||
version = "0.7"
|
version = "0.7"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
|
[dependencies.security-framework]
|
||||||
|
version = "0.1.4"
|
||||||
|
optional = true
|
||||||
|
|
||||||
[dependencies.solicit]
|
[dependencies.solicit]
|
||||||
version = "0.4"
|
version = "0.4"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ extern crate time;
|
|||||||
extern crate url;
|
extern crate url;
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
extern crate openssl;
|
extern crate openssl;
|
||||||
|
#[cfg(feature = "security-framework")]
|
||||||
|
extern crate security_framework;
|
||||||
#[cfg(feature = "serde-serialization")]
|
#[cfg(feature = "serde-serialization")]
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate cookie;
|
extern crate cookie;
|
||||||
|
|||||||
115
src/net.rs
115
src/net.rs
@@ -593,7 +593,7 @@ impl<S: SslClient> NetworkConnector for HttpsConnector<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(feature = "openssl"))]
|
#[cfg(all(not(feature = "openssl"), not(feature = "security-framework")))]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type DefaultConnector = HttpConnector;
|
pub type DefaultConnector = HttpConnector;
|
||||||
|
|
||||||
@@ -601,6 +601,9 @@ pub type DefaultConnector = HttpConnector;
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub type DefaultConnector = HttpsConnector<self::openssl::Openssl>;
|
pub type DefaultConnector = HttpsConnector<self::openssl::Openssl>;
|
||||||
|
|
||||||
|
#[cfg(all(feature = "security-framework", not(feature = "openssl")))]
|
||||||
|
pub type DefaultConnector = HttpsConnector<self::security_framework::ClientWrapper>;
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
mod openssl {
|
mod openssl {
|
||||||
use std::io;
|
use std::io;
|
||||||
@@ -702,6 +705,116 @@ mod openssl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "security-framework")]
|
||||||
|
pub mod security_framework {
|
||||||
|
use std::io;
|
||||||
|
use std::fmt;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::net::{Shutdown, SocketAddr};
|
||||||
|
use std::time::Duration;
|
||||||
|
use security_framework::secure_transport::{SslStream, ClientBuilder, ServerBuilder};
|
||||||
|
|
||||||
|
use error::Error;
|
||||||
|
use net::{SslClient, SslServer, HttpStream, NetworkStream};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ClientWrapper(ClientBuilder);
|
||||||
|
|
||||||
|
impl ClientWrapper {
|
||||||
|
pub fn new(builder: ClientBuilder) -> ClientWrapper {
|
||||||
|
ClientWrapper(builder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SslClient for ClientWrapper {
|
||||||
|
type Stream = Stream;
|
||||||
|
|
||||||
|
fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result<Stream> {
|
||||||
|
match self.0.handshake(host, stream) {
|
||||||
|
Ok(s) => Ok(Stream(Arc::new(Mutex::new(s)))),
|
||||||
|
Err(e) => Err(Error::Ssl(e.into())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ServerWrapper(Arc<ServerBuilder>);
|
||||||
|
|
||||||
|
impl ServerWrapper {
|
||||||
|
pub fn new(builder: ServerBuilder) -> ServerWrapper {
|
||||||
|
ServerWrapper(Arc::new(builder))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SslServer for ServerWrapper {
|
||||||
|
type Stream = Stream;
|
||||||
|
|
||||||
|
fn wrap_server(&self, stream: HttpStream) -> ::Result<Stream> {
|
||||||
|
match self.0.handshake(stream) {
|
||||||
|
Ok(s) => Ok(Stream(Arc::new(Mutex::new(s)))),
|
||||||
|
Err(e) => Err(Error::Ssl(e.into())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Stream(Arc<Mutex<SslStream<HttpStream>>>);
|
||||||
|
|
||||||
|
impl io::Read for Stream {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).read(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).read_to_end(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).read_to_string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).read_exact(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl io::Write for Stream {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).write_all(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(fmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkStream for Stream {
|
||||||
|
fn peer_addr(&mut self) -> io::Result<SocketAddr> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().peer_addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().set_read_timeout(dur)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().set_write_timeout(dur)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close(&mut self, how: Shutdown) -> io::Result<()> {
|
||||||
|
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().close(how)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use mock::MockStream;
|
use mock::MockStream;
|
||||||
|
|||||||
Reference in New Issue
Block a user