@@ -32,6 +32,10 @@ default-features = false
|
||||
version = "0.7"
|
||||
optional = true
|
||||
|
||||
[dependencies.security-framework]
|
||||
version = "0.1.4"
|
||||
optional = true
|
||||
|
||||
[dependencies.solicit]
|
||||
version = "0.4"
|
||||
default-features = false
|
||||
|
||||
@@ -133,6 +133,8 @@ extern crate time;
|
||||
extern crate url;
|
||||
#[cfg(feature = "openssl")]
|
||||
extern crate openssl;
|
||||
#[cfg(feature = "security-framework")]
|
||||
extern crate security_framework;
|
||||
#[cfg(feature = "serde-serialization")]
|
||||
extern crate serde;
|
||||
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)]
|
||||
pub type DefaultConnector = HttpConnector;
|
||||
|
||||
@@ -601,6 +601,9 @@ pub type DefaultConnector = HttpConnector;
|
||||
#[doc(hidden)]
|
||||
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")]
|
||||
mod openssl {
|
||||
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)]
|
||||
mod tests {
|
||||
use mock::MockStream;
|
||||
|
||||
Reference in New Issue
Block a user