put all TLS functionality behind a feature flag
The "Cargo feature" `default-tls`, which is enabled by default, is added, with all TLS support relying on it. This allows using reqwest but disabling the `native-tls` dependency, by disabling this feature. Closes #225
This commit is contained in:
		| @@ -8,6 +8,7 @@ use hyper::client::ResponseFuture; | ||||
| use header::{HeaderMap, HeaderValue, LOCATION, USER_AGENT, REFERER, ACCEPT, | ||||
|              ACCEPT_ENCODING, RANGE, TRANSFER_ENCODING, CONTENT_TYPE, CONTENT_LENGTH, CONTENT_ENCODING}; | ||||
| use mime::{self}; | ||||
| #[cfg(feature = "default-tls")] | ||||
| use native_tls::{TlsConnector, TlsConnectorBuilder}; | ||||
|  | ||||
|  | ||||
| @@ -16,7 +17,9 @@ use super::response::Response; | ||||
| use connect::Connector; | ||||
| use into_url::to_uri; | ||||
| use redirect::{self, RedirectPolicy, remove_sensitive_headers}; | ||||
| use {Certificate, Identity, IntoUrl, Method, Proxy, StatusCode, Url}; | ||||
| use {IntoUrl, Method, Proxy, StatusCode, Url}; | ||||
| #[cfg(feature = "default-tls")] | ||||
| use {Certificate, Identity}; | ||||
|  | ||||
| static DEFAULT_USER_AGENT: &'static str = | ||||
|     concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); | ||||
| @@ -41,12 +44,15 @@ pub struct ClientBuilder { | ||||
| struct Config { | ||||
|     gzip: bool, | ||||
|     headers: HeaderMap, | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     hostname_verification: bool, | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     certs_verification: bool, | ||||
|     proxies: Vec<Proxy>, | ||||
|     redirect_policy: RedirectPolicy, | ||||
|     referer: bool, | ||||
|     timeout: Option<Duration>, | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     tls: TlsConnectorBuilder, | ||||
|     dns_threads: usize, | ||||
| } | ||||
| @@ -62,12 +68,15 @@ impl ClientBuilder { | ||||
|             config: Config { | ||||
|                 gzip: true, | ||||
|                 headers: headers, | ||||
|                 #[cfg(feature = "default-tls")] | ||||
|                 hostname_verification: true, | ||||
|                 #[cfg(feature = "default-tls")] | ||||
|                 certs_verification: true, | ||||
|                 proxies: Vec::new(), | ||||
|                 redirect_policy: RedirectPolicy::default(), | ||||
|                 referer: true, | ||||
|                 timeout: None, | ||||
|                 #[cfg(feature = "default-tls")] | ||||
|                 tls: TlsConnector::builder(), | ||||
|                 dns_threads: 4, | ||||
|             }, | ||||
| @@ -80,16 +89,31 @@ impl ClientBuilder { | ||||
|     /// | ||||
|     /// This method fails if native TLS backend cannot be initialized. | ||||
|     pub fn build(self) -> ::Result<Client> { | ||||
|         let mut config = self.config; | ||||
|         let config = self.config; | ||||
|  | ||||
|         config.tls.danger_accept_invalid_hostnames(!config.hostname_verification); | ||||
|         config.tls.danger_accept_invalid_certs(!config.certs_verification); | ||||
|  | ||||
|         let tls = try_!(config.tls.build()); | ||||
|         let connector = { | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             { | ||||
|             let mut tls = config.tls; | ||||
|             tls.danger_accept_invalid_hostnames(!config.hostname_verification); | ||||
|             tls.danger_accept_invalid_certs(!config.certs_verification); | ||||
|  | ||||
|         let proxies = Arc::new(config.proxies); | ||||
|             let tls = try_!(tls.build()); | ||||
|  | ||||
|         let connector = Connector::new(config.dns_threads, tls, proxies.clone()); | ||||
|             let proxies = Arc::new(config.proxies); | ||||
|  | ||||
|             Connector::new(config.dns_threads, tls, proxies.clone()) | ||||
|             } | ||||
|  | ||||
|  | ||||
|             #[cfg(not(feature = "default-tls"))] | ||||
|             { | ||||
|             let proxies = Arc::new(config.proxies); | ||||
|  | ||||
|             Connector::new(config.dns_threads, proxies.clone()) | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         let hyper_client = ::hyper::Client::builder() | ||||
|             .build(connector); | ||||
| @@ -109,12 +133,14 @@ impl ClientBuilder { | ||||
|     /// | ||||
|     /// This can be used to connect to a server that has a self-signed | ||||
|     /// certificate for example. | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn add_root_certificate(mut self, cert: Certificate) -> ClientBuilder { | ||||
|         self.config.tls.add_root_certificate(cert.cert()); | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Sets the identity to be used for client certificate authentication. | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn identity(mut self, identity: Identity) -> ClientBuilder { | ||||
|         self.config.tls.identity(identity.pkcs12()); | ||||
|         self | ||||
| @@ -130,6 +156,7 @@ impl ClientBuilder { | ||||
|     /// hostname verification is not used, any valid certificate for any | ||||
|     /// site will be trusted for use from any other. This introduces a | ||||
|     /// significant vulnerability to man-in-the-middle attacks. | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn danger_accept_invalid_hostnames(mut self, accept_invalid_hostname: bool) -> ClientBuilder { | ||||
|         self.config.hostname_verification = !accept_invalid_hostname; | ||||
|         self | ||||
| @@ -147,6 +174,7 @@ impl ClientBuilder { | ||||
|     /// will be trusted for use. This includes expired certificates. This | ||||
|     /// introduces significant vulnerabilities, and should only be used | ||||
|     /// as a last resort. | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn danger_accept_invalid_certs(mut self, accept_invalid_certs: bool) -> ClientBuilder { | ||||
|         self.config.certs_verification = !accept_invalid_certs; | ||||
|         self | ||||
|   | ||||
| @@ -9,7 +9,9 @@ use futures::sync::{mpsc, oneshot}; | ||||
|  | ||||
| use request::{Request, RequestBuilder}; | ||||
| use response::Response; | ||||
| use {async_impl, header, Certificate, Identity, Method, IntoUrl, Proxy, RedirectPolicy, wait}; | ||||
| use {async_impl, header, Method, IntoUrl, Proxy, RedirectPolicy, wait}; | ||||
| #[cfg(feature = "default-tls")] | ||||
| use {Certificate, Identity}; | ||||
|  | ||||
| /// A `Client` to make Requests with. | ||||
| /// | ||||
| @@ -106,6 +108,7 @@ impl ClientBuilder { | ||||
|     /// # Errors | ||||
|     /// | ||||
|     /// This method fails if adding root certificate was unsuccessful. | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn add_root_certificate(self, cert: Certificate) -> ClientBuilder { | ||||
|         self.with_inner(move |inner| inner.add_root_certificate(cert)) | ||||
|     } | ||||
| @@ -133,6 +136,7 @@ impl ClientBuilder { | ||||
|     /// # Ok(()) | ||||
|     /// # } | ||||
|     /// ``` | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn identity(self, identity: Identity) -> ClientBuilder { | ||||
|         self.with_inner(move |inner| inner.identity(identity)) | ||||
|     } | ||||
| @@ -148,6 +152,7 @@ impl ClientBuilder { | ||||
|     /// hostname verification is not used, any valid certificate for any | ||||
|     /// site will be trusted for use from any other. This introduces a | ||||
|     /// significant vulnerability to man-in-the-middle attacks. | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn danger_accept_invalid_hostnames(self, accept_invalid_hostname: bool) -> ClientBuilder { | ||||
|         self.with_inner(|inner| inner.danger_accept_invalid_hostnames(accept_invalid_hostname)) | ||||
|     } | ||||
| @@ -164,6 +169,7 @@ impl ClientBuilder { | ||||
|     /// will be trusted for use. This includes expired certificates. This | ||||
|     /// introduces significant vulnerabilities, and should only be used | ||||
|     /// as a last resort. | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub fn danger_accept_invalid_certs(self, accept_invalid_certs: bool) -> ClientBuilder { | ||||
|         self.with_inner(|inner| inner.danger_accept_invalid_certs(accept_invalid_certs)) | ||||
|     } | ||||
|   | ||||
| @@ -1,34 +1,50 @@ | ||||
| use bytes::{Buf, BufMut, IntoBuf}; | ||||
| use futures::{Async, Future, Poll}; | ||||
| use bytes::{Buf, BufMut}; | ||||
| use futures::{Future, Poll}; | ||||
| use http::uri::Scheme; | ||||
| use hyper::client::{HttpConnector}; | ||||
| use hyper::client::connect::{Connect, Connected, Destination}; | ||||
| #[cfg(feature = "default-tls")] | ||||
| use hyper_tls::{HttpsConnector, MaybeHttpsStream}; | ||||
| #[cfg(feature = "default-tls")] | ||||
| use native_tls::TlsConnector; | ||||
| use tokio_io::{AsyncRead, AsyncWrite}; | ||||
| #[cfg(feature = "default-tls")] | ||||
| use connect_async::{TlsConnectorExt, TlsStream}; | ||||
|  | ||||
| use std::io::{self, Cursor, Read, Write}; | ||||
| use std::io::{self, Read, Write}; | ||||
| use std::sync::Arc; | ||||
|  | ||||
| use Proxy; | ||||
|  | ||||
| pub(crate) struct Connector { | ||||
|     https: HttpsConnector<HttpConnector>, | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     http: HttpsConnector<HttpConnector>, | ||||
|     #[cfg(not(feature = "default-tls"))] | ||||
|     http: HttpConnector, | ||||
|     proxies: Arc<Vec<Proxy>>, | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     tls: TlsConnector, | ||||
| } | ||||
|  | ||||
| impl Connector { | ||||
|     #[cfg(not(feature = "default-tls"))] | ||||
|     pub(crate) fn new(threads: usize, proxies: Arc<Vec<Proxy>>) -> Connector { | ||||
|         let http = HttpConnector::new(threads); | ||||
|         Connector { | ||||
|             http, | ||||
|             proxies, | ||||
|         } | ||||
|     } | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     pub(crate) fn new(threads: usize, tls: TlsConnector, proxies: Arc<Vec<Proxy>>) -> Connector { | ||||
|         let mut http = HttpConnector::new(threads); | ||||
|         http.enforce_http(false); | ||||
|         let https = HttpsConnector::from((http, tls.clone())); | ||||
|         let http = HttpsConnector::from((http, tls.clone())); | ||||
|  | ||||
|         Connector { | ||||
|             https: https, | ||||
|             proxies: proxies, | ||||
|             tls: tls, | ||||
|             http, | ||||
|             proxies, | ||||
|             tls, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -55,11 +71,13 @@ impl Connect for Connector { | ||||
|  | ||||
|                 ndst.set_port(puri.port()); | ||||
|  | ||||
|                 #[cfg(feature = "default-tls")] | ||||
|                 { | ||||
|                 if dst.scheme() == "https" { | ||||
|                     let host = dst.host().to_owned(); | ||||
|                     let port = dst.port().unwrap_or(443); | ||||
|                     let tls = self.tls.clone(); | ||||
|                     return Box::new(self.https.connect(ndst).and_then(move |(conn, connected)| { | ||||
|                     return Box::new(self.http.connect(ndst).and_then(move |(conn, connected)| { | ||||
|                         trace!("tunneling HTTPS over proxy"); | ||||
|                         tunnel(conn, host.clone(), port) | ||||
|                             .and_then(move |tunneled| { | ||||
| @@ -69,20 +87,27 @@ impl Connect for Connector { | ||||
|                             .map(|io| (Conn::Proxied(io), connected.proxy(true))) | ||||
|                     })); | ||||
|                 } | ||||
|                 return Box::new(self.https.connect(ndst).map(|(io, connected)| (Conn::Normal(io), connected.proxy(true)))); | ||||
|                 } | ||||
|                 return Box::new(self.http.connect(ndst).map(|(io, connected)| (Conn::Normal(io), connected.proxy(true)))); | ||||
|             } | ||||
|         } | ||||
|         Box::new(self.https.connect(dst).map(|(io, connected)| (Conn::Normal(io), connected))) | ||||
|         Box::new(self.http.connect(dst).map(|(io, connected)| (Conn::Normal(io), connected))) | ||||
|     } | ||||
| } | ||||
|  | ||||
| type HttpStream = <HttpConnector as Connect>::Transport; | ||||
| #[cfg(feature = "default-tls")] | ||||
| type HttpsStream = MaybeHttpsStream<HttpStream>; | ||||
|  | ||||
|  | ||||
| pub(crate) type Connecting = Box<Future<Item=(Conn, Connected), Error=io::Error> + Send>; | ||||
|  | ||||
| pub(crate) enum Conn { | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     Normal(HttpsStream), | ||||
|     #[cfg(not(feature = "default-tls"))] | ||||
|     Normal(HttpStream), | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     Proxied(TlsStream<MaybeHttpsStream<HttpStream>>), | ||||
| } | ||||
|  | ||||
| @@ -91,6 +116,7 @@ impl Read for Conn { | ||||
|     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||||
|         match *self { | ||||
|             Conn::Normal(ref mut s) => s.read(buf), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Conn::Proxied(ref mut s) => s.read(buf), | ||||
|         } | ||||
|     } | ||||
| @@ -101,6 +127,7 @@ impl Write for Conn { | ||||
|     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | ||||
|         match *self { | ||||
|             Conn::Normal(ref mut s) => s.write(buf), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Conn::Proxied(ref mut s) => s.write(buf), | ||||
|         } | ||||
|     } | ||||
| @@ -109,6 +136,7 @@ impl Write for Conn { | ||||
|     fn flush(&mut self) -> io::Result<()> { | ||||
|         match *self { | ||||
|             Conn::Normal(ref mut s) => s.flush(), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Conn::Proxied(ref mut s) => s.flush(), | ||||
|         } | ||||
|     } | ||||
| @@ -118,6 +146,7 @@ impl AsyncRead for Conn { | ||||
|     unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool { | ||||
|         match *self { | ||||
|             Conn::Normal(ref s) => s.prepare_uninitialized_buffer(buf), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Conn::Proxied(ref s) => s.prepare_uninitialized_buffer(buf), | ||||
|         } | ||||
|     } | ||||
| @@ -125,6 +154,7 @@ impl AsyncRead for Conn { | ||||
|     fn read_buf<B: BufMut>(&mut self, buf: &mut B) -> Poll<usize, io::Error> { | ||||
|         match *self { | ||||
|             Conn::Normal(ref mut s) => s.read_buf(buf), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Conn::Proxied(ref mut s) => s.read_buf(buf), | ||||
|         } | ||||
|     } | ||||
| @@ -134,6 +164,7 @@ impl AsyncWrite for Conn { | ||||
|     fn shutdown(&mut self) -> Poll<(), io::Error> { | ||||
|         match *self { | ||||
|             Conn::Normal(ref mut s) => s.shutdown(), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Conn::Proxied(ref mut s) => s.shutdown(), | ||||
|         } | ||||
|     } | ||||
| @@ -141,11 +172,13 @@ impl AsyncWrite for Conn { | ||||
|     fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Poll<usize, io::Error> { | ||||
|         match *self { | ||||
|             Conn::Normal(ref mut s) => s.write_buf(buf), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Conn::Proxied(ref mut s) => s.write_buf(buf), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "default-tls")] | ||||
| fn tunnel<T>(conn: T, host: String, port: u16) -> Tunnel<T> { | ||||
|      let buf = format!("\ | ||||
|         CONNECT {0}:{1} HTTP/1.1\r\n\ | ||||
| @@ -154,23 +187,26 @@ fn tunnel<T>(conn: T, host: String, port: u16) -> Tunnel<T> { | ||||
|     ", host, port).into_bytes(); | ||||
|  | ||||
|      Tunnel { | ||||
|         buf: buf.into_buf(), | ||||
|         buf: io::Cursor::new(buf), | ||||
|         conn: Some(conn), | ||||
|         state: TunnelState::Writing, | ||||
|      } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "default-tls")] | ||||
| struct Tunnel<T> { | ||||
|     buf: Cursor<Vec<u8>>, | ||||
|     buf: io::Cursor<Vec<u8>>, | ||||
|     conn: Option<T>, | ||||
|     state: TunnelState, | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "default-tls")] | ||||
| enum TunnelState { | ||||
|     Writing, | ||||
|     Reading | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "default-tls")] | ||||
| impl<T> Future for Tunnel<T> | ||||
| where T: AsyncRead + AsyncWrite { | ||||
|     type Item = T; | ||||
| @@ -194,7 +230,7 @@ where T: AsyncRead + AsyncWrite { | ||||
|                 } else if read.len() > 12 { | ||||
|                     if read.starts_with(b"HTTP/1.1 200") || read.starts_with(b"HTTP/1.0 200") { | ||||
|                         if read.ends_with(b"\r\n\r\n") { | ||||
|                             return Ok(Async::Ready(self.conn.take().unwrap())); | ||||
|                             return Ok(self.conn.take().unwrap().into()); | ||||
|                         } | ||||
|                         // else read more | ||||
|                     } else { | ||||
| @@ -206,6 +242,7 @@ where T: AsyncRead + AsyncWrite { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "default-tls")] | ||||
| #[inline] | ||||
| fn tunnel_eof() -> io::Error { | ||||
|     io::Error::new( | ||||
| @@ -214,6 +251,7 @@ fn tunnel_eof() -> io::Error { | ||||
|     ) | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "default-tls")] | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use std::io::{Read, Write}; | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| use std::io::{self, Read, Write}; | ||||
|  | ||||
| use futures::{Poll, Future, Async}; | ||||
| use native_tls; | ||||
| use native_tls::{HandshakeError, Error, TlsConnector}; | ||||
| use native_tls::{self, HandshakeError, Error, TlsConnector}; | ||||
| use tokio_io::{AsyncRead, AsyncWrite}; | ||||
|  | ||||
| /// A wrapper around an underlying raw stream which implements the TLS or SSL | ||||
| @@ -128,4 +127,4 @@ impl<S: Read + Write> Future for MidHandshake<S> { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -135,6 +135,7 @@ impl Error { | ||||
|             Kind::Hyper(ref e) => Some(e), | ||||
|             Kind::Mime(ref e) => Some(e), | ||||
|             Kind::Url(ref e) => Some(e), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Kind::Tls(ref e) => Some(e), | ||||
|             Kind::Io(ref e) => Some(e), | ||||
|             Kind::UrlEncoded(ref e) => Some(e), | ||||
| @@ -224,6 +225,7 @@ impl fmt::Display for Error { | ||||
|             Kind::Mime(ref e) => fmt::Display::fmt(e, f), | ||||
|             Kind::Url(ref e) => fmt::Display::fmt(e, f), | ||||
|             Kind::UrlBadScheme => f.write_str("URL scheme is not allowed"), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Kind::Tls(ref e) => fmt::Display::fmt(e, f), | ||||
|             Kind::Io(ref e) => fmt::Display::fmt(e, f), | ||||
|             Kind::UrlEncoded(ref e) => fmt::Display::fmt(e, f), | ||||
| @@ -250,6 +252,7 @@ impl StdError for Error { | ||||
|             Kind::Mime(ref e) => e.description(), | ||||
|             Kind::Url(ref e) => e.description(), | ||||
|             Kind::UrlBadScheme => "URL scheme is not allowed", | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Kind::Tls(ref e) => e.description(), | ||||
|             Kind::Io(ref e) => e.description(), | ||||
|             Kind::UrlEncoded(ref e) => e.description(), | ||||
| @@ -267,6 +270,7 @@ impl StdError for Error { | ||||
|             Kind::Hyper(ref e) => e.cause(), | ||||
|             Kind::Mime(ref e) => e.cause(), | ||||
|             Kind::Url(ref e) => e.cause(), | ||||
|             #[cfg(feature = "default-tls")] | ||||
|             Kind::Tls(ref e) => e.cause(), | ||||
|             Kind::Io(ref e) => e.cause(), | ||||
|             Kind::UrlEncoded(ref e) => e.cause(), | ||||
| @@ -287,6 +291,7 @@ pub(crate) enum Kind { | ||||
|     Mime(::mime::FromStrError), | ||||
|     Url(::url::ParseError), | ||||
|     UrlBadScheme, | ||||
|     #[cfg(feature = "default-tls")] | ||||
|     Tls(::native_tls::Error), | ||||
|     Io(io::Error), | ||||
|     UrlEncoded(::serde_urlencoded::ser::Error), | ||||
| @@ -347,6 +352,7 @@ impl From<::serde_json::Error> for Kind { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "default-tls")] | ||||
| impl From<::native_tls::Error> for Kind { | ||||
|     fn from(err: ::native_tls::Error) -> Kind { | ||||
|         Kind::Tls(err) | ||||
|   | ||||
							
								
								
									
										18
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -117,6 +117,16 @@ | ||||
| //! # } | ||||
| //! ``` | ||||
| //! | ||||
| //! ## Optional Features | ||||
| //! | ||||
| //! The following are a list of [Cargo features][cargo-features] that can be | ||||
| //! enabled or disabled: | ||||
| //! | ||||
| //! - **default-tls** *(enabled by default)*: Provides TLS support via the | ||||
| //!   `native-tls` library to connect over HTTPS. | ||||
| //! - **hyper-011**: Provides support for hyper's old typed headers. | ||||
| //! | ||||
| //! | ||||
| //! [hyper]: http://hyper.rs | ||||
| //! [client]: ./struct.Client.html | ||||
| //! [response]: ./struct.Response.html | ||||
| @@ -124,6 +134,7 @@ | ||||
| //! [builder]: ./struct.RequestBuilder.html | ||||
| //! [serde]: http://serde.rs | ||||
| //! [cookiejar_issue]: https://github.com/seanmonstar/reqwest/issues/14 | ||||
| //! [cargo-features]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section | ||||
|  | ||||
| extern crate base64; | ||||
| extern crate bytes; | ||||
| @@ -134,12 +145,14 @@ extern crate http; | ||||
| extern crate hyper; | ||||
| #[cfg(feature = "hyper-011")] | ||||
| pub extern crate hyper_old_types as hyper_011; | ||||
| #[cfg(feature = "default-tls")] | ||||
| extern crate hyper_tls; | ||||
| #[macro_use] | ||||
| extern crate log; | ||||
| extern crate libflate; | ||||
| extern crate mime; | ||||
| extern crate mime_guess; | ||||
| #[cfg(feature = "default-tls")] | ||||
| extern crate native_tls; | ||||
| extern crate serde; | ||||
| #[cfg(test)] | ||||
| @@ -148,7 +161,7 @@ extern crate serde_derive; | ||||
| extern crate serde_json; | ||||
| extern crate serde_urlencoded; | ||||
| extern crate tokio; | ||||
| #[macro_use] | ||||
| #[cfg_attr(feature = "default-tls", macro_use)] | ||||
| extern crate tokio_io; | ||||
| extern crate url; | ||||
| extern crate uuid; | ||||
| @@ -167,6 +180,7 @@ pub use self::proxy::Proxy; | ||||
| pub use self::redirect::{RedirectAction, RedirectAttempt, RedirectPolicy}; | ||||
| pub use self::request::{Request, RequestBuilder}; | ||||
| pub use self::response::Response; | ||||
| #[cfg(feature = "default-tls")] | ||||
| pub use self::tls::{Certificate, Identity}; | ||||
|  | ||||
|  | ||||
| @@ -176,6 +190,7 @@ mod error; | ||||
|  | ||||
| mod async_impl; | ||||
| mod connect; | ||||
| #[cfg(feature = "default-tls")] | ||||
| mod connect_async; | ||||
| mod body; | ||||
| mod client; | ||||
| @@ -184,6 +199,7 @@ mod proxy; | ||||
| mod redirect; | ||||
| mod request; | ||||
| mod response; | ||||
| #[cfg(feature = "default-tls")] | ||||
| mod tls; | ||||
| mod wait; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user