feat(client): redesign the Connect trait
				
					
				
			The original `Connect` trait had some limitations: - There was no way to provide more details to the connector about how to connect, other than the `Uri`. - There was no way for the connector to return any extra information about the connected transport. - The `Error` was forced to be an `std::io::Error`. - The transport and future had `'static` requirements. As hyper gains HTTP/2 support, some of these things needed to be changed. We want to allow the user to configure whether they hope to us ALPN to start an HTTP/2 connection, and the connector needs to be able to return back to hyper if it did so. The new `Connect` trait is meant to solve this. - The `connect` method now receives a `Destination` type, instead of a `Uri`. This allows us to include additional data about how to connect. - The `Future` returned from `connect` now must be a tuple of the transport, and a `Connected` metadata value. The `Connected` includes possibly extra data about what happened when connecting. BREAKING CHANGE: Custom connectors should now implement `Connect` directly, instead of `Service`. Calls to `connect` no longer take `Uri`s, but `Destination`. There are `scheme`, `host`, and `port` methods to query relevant information. The returned future must be a tuple of the transport and `Connected`. If no relevant extra information is needed, simply return `Connected::new()`. Closes #1428
This commit is contained in:
		
							
								
								
									
										27
									
								
								src/mock.rs
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/mock.rs
									
									
									
									
									
								
							| @@ -8,9 +8,8 @@ use bytes::Buf; | ||||
| use futures::{Async, Poll}; | ||||
| use futures::task::{self, Task}; | ||||
| use tokio_io::{AsyncRead, AsyncWrite}; | ||||
| use tokio_service::Service; | ||||
|  | ||||
| use ::Uri; | ||||
| use ::client::connect::{Connect, Connected, Destination}; | ||||
|  | ||||
| #[derive(Debug)] | ||||
| pub struct MockCursor { | ||||
| @@ -410,19 +409,23 @@ impl MockConnector { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Service for MockConnector { | ||||
|     type Request = Uri; | ||||
|     type Response = Duplex; | ||||
| impl Connect for MockConnector { | ||||
|     type Transport = Duplex; | ||||
|     type Error = io::Error; | ||||
|     type Future = ::futures::future::FutureResult<Self::Response, Self::Error>; | ||||
|     type Future = ::futures::future::FutureResult<(Self::Transport, Connected), Self::Error>; | ||||
|  | ||||
|     fn call(&self, uri: Uri) -> Self::Future { | ||||
|     fn connect(&self, dst: Destination) -> Self::Future { | ||||
|         use futures::future; | ||||
|         trace!("mock connect: {}", uri); | ||||
|         trace!("mock connect: {:?}", dst); | ||||
|         let key = format!("{}://{}{}", dst.scheme(), dst.host(), if let Some(port) = dst.port() { | ||||
|             format!(":{}", port) | ||||
|         } else { | ||||
|             "".to_owned() | ||||
|         }); | ||||
|         let mut mocks = self.mocks.borrow_mut(); | ||||
|         let mocks = mocks.get_mut(&uri.to_string()) | ||||
|             .expect(&format!("unknown mocks uri: {}", uri)); | ||||
|         assert!(!mocks.is_empty(), "no additional mocks for {}", uri); | ||||
|         future::ok(mocks.remove(0)) | ||||
|         let mocks = mocks.get_mut(&key) | ||||
|             .expect(&format!("unknown mocks uri: {}", key)); | ||||
|         assert!(!mocks.is_empty(), "no additional mocks for {}", key); | ||||
|         future::ok((mocks.remove(0), Connected::new())) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user