Skip to content

Commit

Permalink
feat(net): add set_ssl_verifier method to NetworkConnector trait
Browse files Browse the repository at this point in the history
The commit includes an implementation of the new trait method for all
existing trait impls.

BREAKING CHANGE: Adding a new required method to a public trait is a
breaking change.
  • Loading branch information
mlalic committed May 9, 2015
1 parent 38f40c7 commit a5d632b
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 5 deletions.
5 changes: 4 additions & 1 deletion benches/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::fmt;
use std::io::{self, Read, Write, Cursor};
use std::net::SocketAddr;

use hyper::net;
use hyper::net::{self, ContextVerifier};

static README: &'static [u8] = include_bytes!("../README.md");

Expand Down Expand Up @@ -83,6 +83,9 @@ impl net::NetworkConnector for MockConnector {
Ok(MockStream::new())
}

fn set_ssl_verifier(&mut self, _verifier: ContextVerifier) {
// pass
}
}

#[bench]
Expand Down
8 changes: 8 additions & 0 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ impl<C: NetworkConnector<Stream=S> + Send, S: NetworkStream + Send> NetworkConne
-> ::Result<Box<NetworkStream + Send>> {
Ok(try!(self.0.connect(host, port, scheme)).into())
}
#[inline]
fn set_ssl_verifier(&mut self, verifier: ContextVerifier) {
self.0.set_ssl_verifier(verifier);
}
}

struct Connector(Box<NetworkConnector<Stream=Box<NetworkStream + Send>> + Send>);
Expand All @@ -158,6 +162,10 @@ impl NetworkConnector for Connector {
-> ::Result<Box<NetworkStream + Send>> {
Ok(try!(self.0.connect(host, port, scheme)).into())
}
#[inline]
fn set_ssl_verifier(&mut self, verifier: ContextVerifier) {
self.0.set_ssl_verifier(verifier);
}
}

/// Options for an individual Request.
Expand Down
23 changes: 21 additions & 2 deletions src/client/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::io::{self, Read, Write};
use std::net::{SocketAddr, Shutdown};
use std::sync::{Arc, Mutex};

use net::{NetworkConnector, NetworkStream, HttpConnector};
use net::{NetworkConnector, NetworkStream, HttpConnector, ContextVerifier};

/// The `NetworkConnector` that behaves as a connection pool used by hyper's `Client`.
pub struct Pool<C: NetworkConnector> {
Expand Down Expand Up @@ -119,6 +119,10 @@ impl<C: NetworkConnector<Stream=S>, S: NetworkStream + Send> NetworkConnector fo
pool: self.inner.clone()
})
}
#[inline]
fn set_ssl_verifier(&mut self, verifier: ContextVerifier) {
self.connector.set_ssl_verifier(verifier);
}
}

/// A Stream that will try to be returned to the Pool when dropped.
Expand Down Expand Up @@ -184,8 +188,9 @@ impl<S> Drop for PooledStream<S> {
#[cfg(test)]
mod tests {
use std::net::Shutdown;
use mock::MockConnector;
use mock::{MockConnector, ChannelMockConnector};
use net::{NetworkConnector, NetworkStream};
use std::sync::mpsc;

use super::{Pool, key};

Expand Down Expand Up @@ -223,5 +228,19 @@ mod tests {
assert_eq!(locked.conns.len(), 0);
}

/// Tests that the `Pool::set_ssl_verifier` method sets the SSL verifier of
/// the underlying `Connector` instance that it uses.
#[test]
fn test_set_ssl_verifier_delegates_to_connector() {
let (tx, rx) = mpsc::channel();
let mut pool = Pool::with_connector(
Default::default(), ChannelMockConnector::new(tx));

pool.set_ssl_verifier(Box::new(|_| { }));

match rx.try_recv() {
Ok(meth) => assert_eq!(meth, "set_ssl_verifier"),
_ => panic!("Expected a call to `set_ssl_verifier`"),
};
}
}
39 changes: 38 additions & 1 deletion src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::fmt;
use std::io::{self, Read, Write, Cursor};
use std::net::SocketAddr;
use std::sync::mpsc::Sender;

use net::{NetworkStream, NetworkConnector};
use net::{NetworkStream, NetworkConnector, ContextVerifier};

pub struct MockStream {
pub read: Cursor<Vec<u8>>,
Expand Down Expand Up @@ -76,6 +77,39 @@ impl NetworkConnector for MockConnector {
fn connect(&mut self, _host: &str, _port: u16, _scheme: &str) -> ::Result<MockStream> {
Ok(MockStream::new())
}

fn set_ssl_verifier(&mut self, _verifier: ContextVerifier) {
// pass
}
}

/// A mock implementation of the `NetworkConnector` trait that keeps track of all calls to its
/// methods by sending corresponding messages onto a channel.
///
/// Otherwise, it behaves the same as `MockConnector`.
pub struct ChannelMockConnector {
calls: Sender<String>,
}

impl ChannelMockConnector {
pub fn new(calls: Sender<String>) -> ChannelMockConnector {
ChannelMockConnector { calls: calls }
}
}

impl NetworkConnector for ChannelMockConnector {
type Stream = MockStream;
#[inline]
fn connect(&mut self, _host: &str, _port: u16, _scheme: &str)
-> ::Result<MockStream> {
self.calls.send("connect".into()).unwrap();
Ok(MockStream::new())
}

#[inline]
fn set_ssl_verifier(&mut self, _verifier: ContextVerifier) {
self.calls.send("set_ssl_verifier".into()).unwrap();
}
}

/// new connectors must be created if you wish to intercept requests.
Expand Down Expand Up @@ -107,6 +141,9 @@ macro_rules! mock_connector (
}
}

fn set_ssl_verifier(&mut self, _verifier: ::net::ContextVerifier) {
// pass
}
}

)
Expand Down
16 changes: 15 additions & 1 deletion src/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ pub trait NetworkConnector {
type Stream: Into<Box<NetworkStream + Send>>;
/// Connect to a remote address.
fn connect(&mut self, host: &str, port: u16, scheme: &str) -> ::Result<Self::Stream>;
/// Sets the given `ContextVerifier` to be used when verifying the SSL context
/// on the establishment of a new connection.
fn set_ssl_verifier(&mut self, verifier: ContextVerifier);
}

impl<T: NetworkStream + Send> From<T> for Box<NetworkStream + Send> {
Expand Down Expand Up @@ -344,12 +347,15 @@ impl NetworkConnector for HttpConnector {
}
}))
}
fn set_ssl_verifier(&mut self, verifier: ContextVerifier) {
self.0 = Some(verifier);
}
}

#[cfg(test)]
mod tests {
use mock::MockStream;
use super::NetworkStream;
use super::{NetworkStream, HttpConnector, NetworkConnector};

#[test]
fn test_downcast_box_stream() {
Expand All @@ -371,4 +377,12 @@ mod tests {

}

#[test]
fn test_http_connector_set_ssl_verifier() {
let mut connector = HttpConnector(None);

connector.set_ssl_verifier(Box::new(|_| {}));

assert!(connector.0.is_some());
}
}

0 comments on commit a5d632b

Please sign in to comment.