add native-tls and serde json support
This commit is contained in:
		
							
								
								
									
										15
									
								
								Cargo.toml
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Cargo.toml
									
									
									
									
									
								
							| @@ -2,14 +2,27 @@ | |||||||
| name = "reqwest" | name = "reqwest" | ||||||
| version = "0.0.0" | version = "0.0.0" | ||||||
| description = "higher level HTTP client library" | description = "higher level HTTP client library" | ||||||
|  | keywords = ["http", "request", "client"] | ||||||
| repository = "https://github.com/seanmonstar/reqwest" | repository = "https://github.com/seanmonstar/reqwest" | ||||||
| documentation = "https://docs.rs/reqwest" | documentation = "https://docs.rs/reqwest" | ||||||
| authors = ["Sean McArthur <sean.monstar@gmail.com>"] | authors = ["Sean McArthur <sean.monstar@gmail.com>"] | ||||||
| license = "MIT/Apache-2.0" | license = "MIT/Apache-2.0" | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| hyper = { version = "0.9" }#, default-features = false } | hyper = { version = "0.9" , default-features = false } | ||||||
|  | serde = "0.8" | ||||||
|  | serde_json = "0.8" | ||||||
| log = "0.3" | log = "0.3" | ||||||
|  |  | ||||||
|  | [dependencies.native-tls] | ||||||
|  | git = "https://github.com/sfackler/rust-native-tls" | ||||||
|  | optional = true | ||||||
|  |  | ||||||
|  | [features] | ||||||
|  | default = ["openssl"] | ||||||
|  | openssl = ["hyper/ssl"] | ||||||
|  | tls = ["native-tls"] | ||||||
|  |  | ||||||
| [dev-dependencies] | [dev-dependencies] | ||||||
| env_logger = "0.3" | env_logger = "0.3" | ||||||
|  | serde_derive = "0.8" | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| # request | # reqwest | ||||||
|  |  | ||||||
| An ergonomic HTTP Client for Rust | An ergonomic HTTP Client for Rust | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								examples/post.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								examples/post.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | //#![feature(proc_macro)] | ||||||
|  |  | ||||||
|  | extern crate reqwest; | ||||||
|  | extern crate env_logger; | ||||||
|  | //#[macro_use] extern crate serde_derive; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | #[derive(Serialize)] | ||||||
|  | struct Thingy { | ||||||
|  |     a: i32, | ||||||
|  |     b: bool, | ||||||
|  |     c: String, | ||||||
|  | } | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | fn main() { | ||||||
|  |     env_logger::init().unwrap(); | ||||||
|  |  | ||||||
|  |     println!("POST https://httpbin.org/post"); | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     let thingy = Thingy { | ||||||
|  |         a: 5, | ||||||
|  |         b: true, | ||||||
|  |         c: String::from("reqwest") | ||||||
|  |     }; | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     let client = reqwest::Client::new(); | ||||||
|  |     let mut res = client.post("https://httpbin.org/post") | ||||||
|  |         .body("foo=bar") | ||||||
|  |         .send().unwrap(); | ||||||
|  |  | ||||||
|  |     println!("Status: {}", res.status()); | ||||||
|  |     println!("Headers:\n{}", res.headers()); | ||||||
|  |  | ||||||
|  |     ::std::io::copy(&mut res, &mut ::std::io::stdout()).unwrap(); | ||||||
|  |  | ||||||
|  |     println!("\n\nDone."); | ||||||
|  | } | ||||||
| @@ -6,7 +6,7 @@ fn main() { | |||||||
|  |  | ||||||
|     println!("GET https://www.rust-lang.org"); |     println!("GET https://www.rust-lang.org"); | ||||||
|  |  | ||||||
|     let mut res = reqwest::get("http://www.rust-lang.org").unwrap(); |     let mut res = reqwest::get("https://www.rust-lang.org").unwrap(); | ||||||
|  |  | ||||||
|     println!("Status: {}", res.status()); |     println!("Status: {}", res.status()); | ||||||
|     println!("Headers:\n{}", res.headers()); |     println!("Headers:\n{}", res.headers()); | ||||||
|   | |||||||
							
								
								
									
										51
									
								
								src/body.rs
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								src/body.rs
									
									
									
									
									
								
							| @@ -1,8 +1,17 @@ | |||||||
| use std::io::Read; | use std::io::Read; | ||||||
|  |  | ||||||
| pub struct Body(Kind); | pub struct Body { | ||||||
|  |     reader: Kind, | ||||||
|  | } | ||||||
|  |  | ||||||
| impl Body { | impl Body { | ||||||
|  |     pub fn new<R: Read + 'static>(reader: R) -> Body { | ||||||
|  |         Body { | ||||||
|  |             reader: Kind::Reader(Box::new(reader), None), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|     pub fn sized(reader: (), len: u64) -> Body { |     pub fn sized(reader: (), len: u64) -> Body { | ||||||
|         unimplemented!() |         unimplemented!() | ||||||
|     } |     } | ||||||
| @@ -10,17 +19,20 @@ impl Body { | |||||||
|     pub fn chunked(reader: ()) -> Body { |     pub fn chunked(reader: ()) -> Body { | ||||||
|         unimplemented!() |         unimplemented!() | ||||||
|     } |     } | ||||||
|  |     */ | ||||||
| } | } | ||||||
|  |  | ||||||
| enum Kind { | enum Kind { | ||||||
|     Length, |     Reader(Box<Read>, Option<u64>), | ||||||
|     Chunked |     Bytes(Vec<u8>), | ||||||
| } | } | ||||||
|  |  | ||||||
| impl From<Vec<u8>> for Body { | impl From<Vec<u8>> for Body { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn from(v: Vec<u8>) -> Body { |     fn from(v: Vec<u8>) -> Body { | ||||||
|         unimplemented!() |         Body { | ||||||
|  |             reader: Kind::Bytes(v), | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -31,7 +43,34 @@ impl From<String> for Body { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Wraps a `std::io::Write`. |  | ||||||
| pub struct Pipe(Kind); | impl<'a> From<&'a [u8]> for Body { | ||||||
|  |     #[inline] | ||||||
|  |     fn from(s: &'a [u8]) -> Body { | ||||||
|  |         s.to_vec().into() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<'a> From<&'a str> for Body { | ||||||
|  |     #[inline] | ||||||
|  |     fn from(s: &'a str) -> Body { | ||||||
|  |         s.as_bytes().into() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Wraps a `std::io::Write`. | ||||||
|  | //pub struct Pipe(Kind); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | pub fn as_hyper_body<'a>(body: &'a Body) -> ::hyper::client::Body<'a> { | ||||||
|  |     match body.reader { | ||||||
|  |         Kind::Bytes(ref bytes) => { | ||||||
|  |             let len = bytes.len(); | ||||||
|  |             ::hyper::client::Body::BufBody(bytes, len) | ||||||
|  |         }, | ||||||
|  |         Kind::Reader(..) => unimplemented!() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,35 +1,58 @@ | |||||||
| use std::io::{self, Read}; | use std::io::{self, Read}; | ||||||
|  |  | ||||||
| use hyper::header::Headers; | use hyper::header::{Headers, ContentType, UserAgent}; | ||||||
| use hyper::method::Method; | use hyper::method::Method; | ||||||
| use hyper::status::StatusCode; | use hyper::status::StatusCode; | ||||||
| use hyper::version::HttpVersion; | use hyper::version::HttpVersion; | ||||||
| use hyper::{Url}; | use hyper::{Url}; | ||||||
|  |  | ||||||
| use ::body::Body; | use serde::Serialize; | ||||||
|  | use serde_json; | ||||||
|  |  | ||||||
|  | use ::body::{self, Body}; | ||||||
|  |  | ||||||
|  | static DEFAULT_USER_AGENT: &'static str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); | ||||||
|  |  | ||||||
|  | /// A `Client` to make Requests with. | ||||||
|  | /// | ||||||
|  | /// The Client has various configuration values to tweak, but the defaults | ||||||
|  | /// are set to what is usually the most commonly desired value. | ||||||
|  | /// | ||||||
|  | /// The `Client` holds a connection pool internally, so it is advised that | ||||||
|  | /// you create one and reuse it. | ||||||
| pub struct Client { | pub struct Client { | ||||||
|     inner: ::hyper::Client, |     inner: ::hyper::Client, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Client { | impl Client { | ||||||
|  |     /// Constructs a new `Client`. | ||||||
|     pub fn new() -> Client { |     pub fn new() -> Client { | ||||||
|         Client { |         Client { | ||||||
|             inner: ::hyper::Client::new(), |             inner: new_hyper_client() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Convenience method to make a `GET` request to a URL. | ||||||
|     pub fn get(&self, url: &str) -> RequestBuilder { |     pub fn get(&self, url: &str) -> RequestBuilder { | ||||||
|         self.request(Method::Get, Url::parse(url).unwrap()) |         self.request(Method::Get, Url::parse(url).unwrap()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Convenience method to make a `POST` request to a URL. | ||||||
|  |     pub fn post(&self, url: &str) -> RequestBuilder { | ||||||
|  |         self.request(Method::Post, Url::parse(url).unwrap()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// Start building a `Request` with the `Method` and `Url`. | ||||||
|  |     /// | ||||||
|  |     /// Returns a `RequestBuilder`, which will allow setting headers and | ||||||
|  |     /// request body before sending. | ||||||
|     pub fn request(&self, method: Method, url: Url) -> RequestBuilder { |     pub fn request(&self, method: Method, url: Url) -> RequestBuilder { | ||||||
|         debug!("request {:?} \"{}\"", method, url); |         debug!("request {:?} \"{}\"", method, url); | ||||||
|         RequestBuilder { |         RequestBuilder { | ||||||
|             client: self, |             client: self, | ||||||
|             method: method, |             method: method, | ||||||
|             url: url, |             url: url, | ||||||
|             version: HttpVersion::Http11, |             _version: HttpVersion::Http11, | ||||||
|             headers: Headers::new(), |             headers: Headers::new(), | ||||||
|  |  | ||||||
|             body: None, |             body: None, | ||||||
| @@ -37,39 +60,75 @@ impl Client { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(not(feature = "tls"))] | ||||||
|  | fn new_hyper_client() -> ::hyper::Client { | ||||||
|  |     ::hyper::Client::new() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[cfg(feature = "tls")] | ||||||
|  | fn new_hyper_client() -> ::hyper::Client { | ||||||
|  |     use tls::TlsClient; | ||||||
|  |     ::hyper::Client::with_connector( | ||||||
|  |         ::hyper::client::Pool::with_connector( | ||||||
|  |             Default::default(), | ||||||
|  |             ::hyper::net::HttpsConnector::new(TlsClient::new().unwrap()) | ||||||
|  |         ) | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// A builder to construct the properties of a `Request`. | ||||||
| pub struct RequestBuilder<'a> { | pub struct RequestBuilder<'a> { | ||||||
|     client: &'a Client, |     client: &'a Client, | ||||||
|  |  | ||||||
|     method: Method, |     method: Method, | ||||||
|     url: Url, |     url: Url, | ||||||
|     version: HttpVersion, |     _version: HttpVersion, | ||||||
|     headers: Headers, |     headers: Headers, | ||||||
|  |  | ||||||
|     body: Option<Body>, |     body: Option<Body>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> RequestBuilder<'a> { | impl<'a> RequestBuilder<'a> { | ||||||
|  |     /// Add a `Header` to this Request. | ||||||
|     pub fn header<H: ::header::Header + ::header::HeaderFormat>(mut self, header: H) -> RequestBuilder<'a> { |     pub fn header<H: ::header::Header + ::header::HeaderFormat>(mut self, header: H) -> RequestBuilder<'a> { | ||||||
|         self.headers.set(header); |         self.headers.set(header); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
|  |     /// Add a set of Headers to the existing ones on this Request. | ||||||
|  |     /// | ||||||
|  |     /// The headers will be merged in to any already set. | ||||||
|     pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder<'a> { |     pub fn headers(mut self, headers: ::header::Headers) -> RequestBuilder<'a> { | ||||||
|         self.headers.extend(headers.iter()); |         self.headers.extend(headers.iter()); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the request body. | ||||||
|     pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder<'a> { |     pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder<'a> { | ||||||
|         self.body = Some(body.into()); |         self.body = Some(body.into()); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pub fn json<T: Serialize>(mut self, json: T) -> RequestBuilder<'a> { | ||||||
|  |         let body = serde_json::to_vec(&json).expect("serde to_vec cannot fail"); | ||||||
|  |         self.headers.set(ContentType::json()); | ||||||
|  |         self.body = Some(body.into()); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// Constructs the Request and sends it the target URL, returning a Response. | ||||||
|     pub fn send(mut self) -> ::Result<Response> { |     pub fn send(mut self) -> ::Result<Response> { | ||||||
|         let req = self.client.inner.request(self.method, self.url) |         if !self.headers.has::<UserAgent>() { | ||||||
|  |             self.headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned())); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let mut req = self.client.inner.request(self.method, self.url) | ||||||
|             .headers(self.headers); |             .headers(self.headers); | ||||||
|  |  | ||||||
|         //TODO: body |         if let Some(ref b) = self.body { | ||||||
|  |             let body = body::as_hyper_body(b); | ||||||
|  |             req = req.body(body); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         let res = try!(req.send()); |         let res = try!(req.send()); | ||||||
|         Ok(Response { |         Ok(Response { | ||||||
| @@ -78,24 +137,29 @@ impl<'a> RequestBuilder<'a> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// A Response to a submitted `Request`. | ||||||
| pub struct Response { | pub struct Response { | ||||||
|     inner: ::hyper::client::Response, |     inner: ::hyper::client::Response, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl Response { | impl Response { | ||||||
|  |     /// Get the `StatusCode`. | ||||||
|     pub fn status(&self) -> &StatusCode { |     pub fn status(&self) -> &StatusCode { | ||||||
|         &self.inner.status |         &self.inner.status | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Get the `Headers`. | ||||||
|     pub fn headers(&self) -> &Headers { |     pub fn headers(&self) -> &Headers { | ||||||
|         &self.inner.headers |         &self.inner.headers | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Get the `HttpVersion`. | ||||||
|     pub fn version(&self) -> &HttpVersion { |     pub fn version(&self) -> &HttpVersion { | ||||||
|         &self.inner.version |         &self.inner.version | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Read the body of the Response. | ||||||
| impl Read for Response { | impl Read for Response { | ||||||
|     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||||||
|         self.inner.read(buf) |         self.inner.read(buf) | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
|  | /// The Errors that may occur when processing a `Request`. | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub enum Error { | pub enum Error { | ||||||
|  |     /// An HTTP error from the `hyper` crate. | ||||||
|     Http(::hyper::Error), |     Http(::hyper::Error), | ||||||
|     #[doc(hidden)] |     #[doc(hidden)] | ||||||
|     __DontMatchMe, |     __DontMatchMe, | ||||||
| @@ -11,4 +13,5 @@ impl From<::hyper::Error> for Error { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// A `Result` alias where the `Err` case is `reqwest::Error`. | ||||||
| pub type Result<T> = ::std::result::Result<T, Error>; | pub type Result<T> = ::std::result::Result<T, Error>; | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -1,9 +1,37 @@ | |||||||
| #![allow(warnings)] | #![deny(warnings)] | ||||||
|  | #![deny(missing_docs)] | ||||||
|  |  | ||||||
|  | //! # reqwest | ||||||
|  | //! | ||||||
|  | //! The `reqwest` crate provides a convenient, higher-level HTTP Client. | ||||||
|  | //! | ||||||
|  | //! It handles many of the things that most people just expect an HTTP client | ||||||
|  | //! to do for them. | ||||||
|  | //! | ||||||
|  | //! - Uses system-native TLS | ||||||
|  | //! - Plain bodies, JSON, urlencoded, multipart | ||||||
|  | //! - Customizable redirect policy | ||||||
|  | //! - Cookies | ||||||
|  | //! | ||||||
|  | //! The `reqwest::Client` is synchronous, making it a great fit for | ||||||
|  | //! applications that only require a few HTTP requests, and wish to handle | ||||||
|  | //! them synchronously. When [hyper][] releases with asynchronous support, | ||||||
|  | //! `reqwest` will be updated to use it internally, but still provide a | ||||||
|  | //! synchronous Client, for convenience. A `reqwest::async::Client` will also | ||||||
|  | //! be added. | ||||||
|  | //! | ||||||
|  | //! ## Making a GET request | ||||||
|  | //! | ||||||
|  | //! ```no_run | ||||||
|  | //! let resp = reqwest::get("https://www.rust-lang.org").unwrap(); | ||||||
|  | //! assert!(resp.status().is_success()); | ||||||
|  | //! ``` | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
|  |  | ||||||
| #[macro_use] extern crate log; | #[macro_use] extern crate log; | ||||||
|  | #[cfg(feature = "tls")] extern crate native_tls; | ||||||
|  | extern crate serde; | ||||||
|  | extern crate serde_json; | ||||||
|  |  | ||||||
| pub use hyper::header; | pub use hyper::header; | ||||||
| pub use hyper::method::Method; | pub use hyper::method::Method; | ||||||
| @@ -18,6 +46,9 @@ mod body; | |||||||
| mod client; | mod client; | ||||||
| mod error; | mod error; | ||||||
|  |  | ||||||
|  | #[cfg(feature = "tls")] mod tls; | ||||||
|  |  | ||||||
|  | /// Shortcut method to quickly make a `GET` request. | ||||||
| pub fn get(url: &str) -> ::Result<Response> { | pub fn get(url: &str) -> ::Result<Response> { | ||||||
|     let client = Client::new(); |     let client = Client::new(); | ||||||
|     client.get(url).send() |     client.get(url).send() | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								src/redirect.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/redirect.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | pub struct RedirectPolicy { | ||||||
|  |     inner: () | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl RedirectPolicy { | ||||||
|  |      | ||||||
|  | } | ||||||
							
								
								
									
										72
									
								
								src/tls.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/tls.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | use std::io::{self, Read, Write}; | ||||||
|  | use std::net::SocketAddr; | ||||||
|  | use std::time::Duration; | ||||||
|  |  | ||||||
|  | use hyper::net::{SslClient, HttpStream, NetworkStream}; | ||||||
|  | use native_tls::{ClientBuilder, TlsStream as NativeTlsStream, HandshakeError}; | ||||||
|  |  | ||||||
|  | pub struct TlsClient(ClientBuilder); | ||||||
|  |  | ||||||
|  | impl TlsClient { | ||||||
|  |     pub fn new() -> ::Result<TlsClient> { | ||||||
|  |         ClientBuilder::new() | ||||||
|  |             .map(TlsClient) | ||||||
|  |             .map_err(|e| ::Error::Http(::hyper::Error::Ssl(Box::new(e)))) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl SslClient for TlsClient { | ||||||
|  |     type Stream = TlsStream; | ||||||
|  |  | ||||||
|  |     fn wrap_client(&self, stream: HttpStream, host: &str) -> ::hyper::Result<Self::Stream> { | ||||||
|  |         self.0.handshake(host, stream).map(TlsStream).map_err(|e| { | ||||||
|  |             match e { | ||||||
|  |                 HandshakeError::Failure(e) => ::hyper::Error::Ssl(Box::new(e)), | ||||||
|  |                 HandshakeError::Interrupted(..) => { | ||||||
|  |                     // while using hyper 0.9, this won't happen, because the | ||||||
|  |                     // socket is in blocking mode. once we move to hyper 0.10, | ||||||
|  |                     // much of this `tls` module will go away anyways | ||||||
|  |                     unreachable!("TlsClient::handshake Interrupted") | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub struct TlsStream(NativeTlsStream<HttpStream>); | ||||||
|  |  | ||||||
|  | impl Read for TlsStream { | ||||||
|  |     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||||||
|  |         self.0.read(buf) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl Write for TlsStream { | ||||||
|  |     fn write(&mut self, data: &[u8]) -> io::Result<usize> { | ||||||
|  |         self.0.write(data) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn flush(&mut self) -> io::Result<()> { | ||||||
|  |         self.0.flush() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl Clone for TlsStream { | ||||||
|  |     fn clone(&self) -> TlsStream { | ||||||
|  |         unreachable!("TlsStream::clone is never used for the Client") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl NetworkStream for TlsStream { | ||||||
|  |     fn peer_addr(&mut self) -> io::Result<SocketAddr> { | ||||||
|  |         self.0.get_mut().peer_addr() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||||
|  |         self.0.get_ref().set_read_timeout(dur) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> { | ||||||
|  |         self.0.get_ref().set_write_timeout(dur) | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user