Skip to content

Commit 2f48612

Browse files
committed
feat(lib): remove SSL dependencies
BREAKING CHANGE: hyper will no longer provide OpenSSL support out of the box. The `hyper::net::Openssl` and related types are gone. The `Client` now uses an `HttpConnector` by default, which will error trying to access HTTPS URLs. TLS support should be added in from other crates, such as hyper-openssl, or similar using different TLS implementations.
1 parent 14a4f1c commit 2f48612

File tree

4 files changed

+1
-337
lines changed

4 files changed

+1
-337
lines changed

Cargo.toml

+1-15
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,9 @@ unicase = "1.0"
2525
url = "1.0"
2626

2727
[dependencies.cookie]
28-
version = "0.2"
28+
version = "0.5"
2929
default-features = false
3030

31-
[dependencies.openssl]
32-
version = "0.7"
33-
optional = true
34-
35-
[dependencies.openssl-verify]
36-
version = "0.1"
37-
optional = true
38-
39-
[dependencies.security-framework]
40-
version = "0.1.4"
41-
optional = true
42-
4331
[dependencies.solicit]
4432
version = "0.4"
4533
default-features = false
@@ -52,7 +40,5 @@ optional = true
5240
env_logger = "0.3"
5341

5442
[features]
55-
default = ["ssl"]
56-
ssl = ["openssl", "openssl-verify", "cookie/secure"]
5743
serde-serialization = ["serde", "mime/serde"]
5844
nightly = []

src/client/proxy.rs

-19
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,6 @@ use client::scheme::Scheme;
77
use method::Method;
88
use net::{NetworkConnector, HttpConnector, NetworkStream, SslClient};
99

10-
#[cfg(all(feature = "openssl", not(feature = "security-framework")))]
11-
pub fn tunnel(proxy: (Scheme, Cow<'static, str>, u16)) -> Proxy<HttpConnector, ::net::Openssl> {
12-
Proxy {
13-
connector: HttpConnector,
14-
proxy: proxy,
15-
ssl: Default::default()
16-
}
17-
}
18-
19-
#[cfg(feature = "security-framework")]
20-
pub fn tunnel(proxy: (Scheme, Cow<'static, str>, u16)) -> Proxy<HttpConnector, ::net::ClientWrapper> {
21-
Proxy {
22-
connector: HttpConnector,
23-
proxy: proxy,
24-
ssl: Default::default()
25-
}
26-
}
27-
28-
#[cfg(not(any(feature = "openssl", feature = "security-framework")))]
2910
pub fn tunnel(proxy: (Scheme, Cow<'static, str>, u16)) -> Proxy<HttpConnector, self::no_ssl::Plaintext> {
3011
Proxy {
3112
connector: HttpConnector,

src/lib.rs

-6
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,6 @@
131131
extern crate rustc_serialize as serialize;
132132
extern crate time;
133133
#[macro_use] extern crate url;
134-
#[cfg(feature = "openssl")]
135-
extern crate openssl;
136-
#[cfg(feature = "openssl-verify")]
137-
extern crate openssl_verify;
138-
#[cfg(feature = "security-framework")]
139-
extern crate security_framework;
140134
#[cfg(feature = "serde-serialization")]
141135
extern crate serde;
142136
extern crate cookie;

src/net.rs

-297
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ use std::io::{self, ErrorKind, Read, Write};
55
use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener, Shutdown};
66
use std::mem;
77

8-
#[cfg(feature = "openssl")]
9-
pub use self::openssl::{Openssl, OpensslClient};
10-
11-
#[cfg(feature = "security-framework")]
12-
pub use self::security_framework::ClientWrapper;
13-
148
use std::time::Duration;
159

1610
use typeable::Typeable;
@@ -413,18 +407,6 @@ impl<F> NetworkConnector for F where F: Fn(&str, u16, &str) -> io::Result<TcpStr
413407
}
414408
}
415409

416-
/// Deprecated
417-
///
418-
/// Use `SslClient` and `SslServer` instead.
419-
pub trait Ssl {
420-
/// The protected stream.
421-
type Stream: NetworkStream + Send + Clone;
422-
/// Wrap a client stream with SSL.
423-
fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result<Self::Stream>;
424-
/// Wrap a server stream with SSL.
425-
fn wrap_server(&self, stream: HttpStream) -> ::Result<Self::Stream>;
426-
}
427-
428410
/// An abstraction to allow any SSL implementation to be used with client-side HttpsStreams.
429411
pub trait SslClient<T: NetworkStream + Send + Clone = HttpStream> {
430412
/// The protected stream.
@@ -441,22 +423,6 @@ pub trait SslServer<T: NetworkStream + Send + Clone = HttpStream> {
441423
fn wrap_server(&self, stream: T) -> ::Result<Self::Stream>;
442424
}
443425

444-
impl<S: Ssl> SslClient<HttpStream> for S {
445-
type Stream = <S as Ssl>::Stream;
446-
447-
fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result<Self::Stream> {
448-
Ssl::wrap_client(self, stream, host)
449-
}
450-
}
451-
452-
impl<S: Ssl> SslServer<HttpStream> for S {
453-
type Stream = <S as Ssl>::Stream;
454-
455-
fn wrap_server(&self, stream: HttpStream) -> ::Result<Self::Stream> {
456-
Ssl::wrap_server(self, stream)
457-
}
458-
}
459-
460426
/// A stream over the HTTP protocol, possibly protected by SSL.
461427
#[derive(Debug, Clone)]
462428
pub enum HttpsStream<S: NetworkStream> {
@@ -603,272 +569,9 @@ impl<S: SslClient, C: NetworkConnector<Stream=HttpStream>> NetworkConnector for
603569
}
604570

605571

606-
#[cfg(all(not(feature = "openssl"), not(feature = "security-framework")))]
607572
#[doc(hidden)]
608573
pub type DefaultConnector = HttpConnector;
609574

610-
#[cfg(feature = "openssl")]
611-
#[doc(hidden)]
612-
pub type DefaultConnector = HttpsConnector<self::openssl::OpensslClient>;
613-
614-
#[cfg(all(feature = "security-framework", not(feature = "openssl")))]
615-
pub type DefaultConnector = HttpsConnector<self::security_framework::ClientWrapper>;
616-
617-
#[cfg(feature = "openssl")]
618-
mod openssl {
619-
use std::io;
620-
use std::net::{SocketAddr, Shutdown};
621-
use std::path::Path;
622-
use std::sync::Arc;
623-
use std::time::Duration;
624-
625-
use openssl::ssl::{Ssl, SslContext, SslStream, SslMethod, SSL_VERIFY_NONE, SSL_VERIFY_PEER, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_OP_NO_COMPRESSION};
626-
use openssl::ssl::error::StreamError as SslIoError;
627-
use openssl::ssl::error::SslError;
628-
use openssl::x509::X509FileType;
629-
use super::{NetworkStream, HttpStream};
630-
631-
/// An implementation of `Ssl` for OpenSSL.
632-
///
633-
/// # Example
634-
///
635-
/// ```no_run
636-
/// use hyper::Server;
637-
/// use hyper::net::Openssl;
638-
///
639-
/// let ssl = Openssl::with_cert_and_key("/home/foo/cert", "/home/foo/key").unwrap();
640-
/// Server::https("0.0.0.0:443", ssl).unwrap();
641-
/// ```
642-
///
643-
/// For complete control, create a `SslContext` with the options you desire
644-
/// and then create `Openssl { context: ctx }
645-
#[derive(Debug, Clone)]
646-
pub struct Openssl {
647-
/// The `SslContext` from openssl crate.
648-
pub context: Arc<SslContext>
649-
}
650-
651-
/// A client-specific implementation of OpenSSL.
652-
#[derive(Debug, Clone)]
653-
pub struct OpensslClient(SslContext);
654-
655-
impl Default for OpensslClient {
656-
fn default() -> OpensslClient {
657-
let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
658-
ctx.set_default_verify_paths().unwrap();
659-
ctx.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
660-
// cipher list taken from curl:
661-
// https://github.com/curl/curl/blob/5bf5f6ebfcede78ef7c2b16daa41c4b7ba266087/lib/vtls/openssl.h#L120
662-
ctx.set_cipher_list("ALL!EXPORT!EXPORT40!EXPORT56!aNULL!LOW!RC4@STRENGTH").unwrap();
663-
OpensslClient::new(ctx)
664-
}
665-
}
666-
667-
impl OpensslClient {
668-
/// Creates a new OpensslClient with a custom SslContext
669-
pub fn new(ctx: SslContext) -> OpensslClient {
670-
OpensslClient(ctx)
671-
}
672-
}
673-
674-
impl<T: NetworkStream + Send + Clone> super::SslClient<T> for OpensslClient {
675-
type Stream = SslStream<T>;
676-
677-
#[cfg(not(windows))]
678-
fn wrap_client(&self, stream: T, host: &str) -> ::Result<Self::Stream> {
679-
let mut ssl = try!(Ssl::new(&self.0));
680-
try!(ssl.set_hostname(host));
681-
let host = host.to_owned();
682-
ssl.set_verify_callback(SSL_VERIFY_PEER, move |p, x| ::openssl_verify::verify_callback(&host, p, x));
683-
SslStream::connect(ssl, stream).map_err(From::from)
684-
}
685-
686-
687-
#[cfg(windows)]
688-
fn wrap_client(&self, stream: T, host: &str) -> ::Result<Self::Stream> {
689-
let mut ssl = try!(Ssl::new(&self.0));
690-
try!(ssl.set_hostname(host));
691-
SslStream::connect(ssl, stream).map_err(From::from)
692-
}
693-
}
694-
695-
impl Default for Openssl {
696-
fn default() -> Openssl {
697-
Openssl {
698-
context: Arc::new(SslContext::new(SslMethod::Sslv23).unwrap_or_else(|e| {
699-
// if we cannot create a SslContext, that's because of a
700-
// serious problem. just crash.
701-
panic!("{}", e)
702-
}))
703-
}
704-
}
705-
}
706-
707-
impl Openssl {
708-
/// Ease creating an `Openssl` with a certificate and key.
709-
pub fn with_cert_and_key<C, K>(cert: C, key: K) -> Result<Openssl, SslError>
710-
where C: AsRef<Path>, K: AsRef<Path> {
711-
let mut ctx = try!(SslContext::new(SslMethod::Sslv23));
712-
try!(ctx.set_cipher_list("DEFAULT"));
713-
try!(ctx.set_certificate_chain_file(cert.as_ref(), X509FileType::PEM));
714-
try!(ctx.set_private_key_file(key.as_ref(), X509FileType::PEM));
715-
ctx.set_verify(SSL_VERIFY_NONE, None);
716-
Ok(Openssl { context: Arc::new(ctx) })
717-
}
718-
}
719-
720-
impl super::Ssl for Openssl {
721-
type Stream = SslStream<HttpStream>;
722-
723-
fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result<Self::Stream> {
724-
let ssl = try!(Ssl::new(&self.context));
725-
try!(ssl.set_hostname(host));
726-
SslStream::connect(ssl, stream).map_err(From::from)
727-
}
728-
729-
fn wrap_server(&self, stream: HttpStream) -> ::Result<Self::Stream> {
730-
match SslStream::accept(&*self.context, stream) {
731-
Ok(ssl_stream) => Ok(ssl_stream),
732-
Err(SslIoError(e)) => {
733-
Err(io::Error::new(io::ErrorKind::ConnectionAborted, e).into())
734-
},
735-
Err(e) => Err(e.into())
736-
}
737-
}
738-
}
739-
740-
impl<S: NetworkStream> NetworkStream for SslStream<S> {
741-
#[inline]
742-
fn peer_addr(&mut self) -> io::Result<SocketAddr> {
743-
self.get_mut().peer_addr()
744-
}
745-
746-
#[inline]
747-
fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
748-
self.get_ref().set_read_timeout(dur)
749-
}
750-
751-
#[inline]
752-
fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
753-
self.get_ref().set_write_timeout(dur)
754-
}
755-
756-
fn close(&mut self, how: Shutdown) -> io::Result<()> {
757-
self.get_mut().close(how)
758-
}
759-
}
760-
}
761-
762-
#[cfg(feature = "security-framework")]
763-
pub mod security_framework {
764-
use std::io;
765-
use std::fmt;
766-
use std::sync::{Arc, Mutex};
767-
use std::net::{Shutdown, SocketAddr};
768-
use std::time::Duration;
769-
use security_framework::secure_transport::{SslStream, ClientBuilder, ServerBuilder};
770-
771-
use error::Error;
772-
use net::{SslClient, SslServer, HttpStream, NetworkStream};
773-
774-
#[derive(Default)]
775-
pub struct ClientWrapper(ClientBuilder);
776-
777-
impl ClientWrapper {
778-
pub fn new(builder: ClientBuilder) -> ClientWrapper {
779-
ClientWrapper(builder)
780-
}
781-
}
782-
783-
impl SslClient for ClientWrapper {
784-
type Stream = Stream;
785-
786-
fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result<Stream> {
787-
match self.0.handshake(host, stream) {
788-
Ok(s) => Ok(Stream(Arc::new(Mutex::new(s)))),
789-
Err(e) => Err(Error::Ssl(e.into())),
790-
}
791-
}
792-
}
793-
794-
#[derive(Clone)]
795-
pub struct ServerWrapper(Arc<ServerBuilder>);
796-
797-
impl ServerWrapper {
798-
pub fn new(builder: ServerBuilder) -> ServerWrapper {
799-
ServerWrapper(Arc::new(builder))
800-
}
801-
}
802-
803-
impl SslServer for ServerWrapper {
804-
type Stream = Stream;
805-
806-
fn wrap_server(&self, stream: HttpStream) -> ::Result<Stream> {
807-
match self.0.handshake(stream) {
808-
Ok(s) => Ok(Stream(Arc::new(Mutex::new(s)))),
809-
Err(e) => Err(Error::Ssl(e.into())),
810-
}
811-
}
812-
}
813-
814-
#[derive(Clone)]
815-
pub struct Stream(Arc<Mutex<SslStream<HttpStream>>>);
816-
817-
impl io::Read for Stream {
818-
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
819-
self.0.lock().unwrap_or_else(|e| e.into_inner()).read(buf)
820-
}
821-
822-
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
823-
self.0.lock().unwrap_or_else(|e| e.into_inner()).read_to_end(buf)
824-
}
825-
826-
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
827-
self.0.lock().unwrap_or_else(|e| e.into_inner()).read_to_string(buf)
828-
}
829-
830-
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
831-
self.0.lock().unwrap_or_else(|e| e.into_inner()).read_exact(buf)
832-
}
833-
}
834-
835-
impl io::Write for Stream {
836-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
837-
self.0.lock().unwrap_or_else(|e| e.into_inner()).write(buf)
838-
}
839-
840-
fn flush(&mut self) -> io::Result<()> {
841-
self.0.lock().unwrap_or_else(|e| e.into_inner()).flush()
842-
}
843-
844-
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
845-
self.0.lock().unwrap_or_else(|e| e.into_inner()).write_all(buf)
846-
}
847-
848-
fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
849-
self.0.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(fmt)
850-
}
851-
}
852-
853-
impl NetworkStream for Stream {
854-
fn peer_addr(&mut self) -> io::Result<SocketAddr> {
855-
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().peer_addr()
856-
}
857-
858-
fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
859-
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().set_read_timeout(dur)
860-
}
861-
862-
fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
863-
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().set_write_timeout(dur)
864-
}
865-
866-
fn close(&mut self, how: Shutdown) -> io::Result<()> {
867-
self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().close(how)
868-
}
869-
}
870-
}
871-
872575
#[cfg(test)]
873576
mod tests {
874577
use mock::MockStream;

0 commit comments

Comments
 (0)