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