1#![doc(html_root_url = "https://docs.rs/mio_httpc")]
76#![crate_name = "mio_httpc"]
77
78#[macro_use]
79extern crate pest_derive;
80#[cfg(any(target_os = "ios", target_os = "macos"))]
81#[macro_use]
82extern crate core_foundation;
83#[cfg(any(target_os = "ios", target_os = "macos"))]
84extern crate core_foundation_sys;
85
86#[macro_use]
87extern crate failure;
88#[cfg(test)]
89#[macro_use]
90extern crate matches;
91
92mod api;
93mod call;
94mod connection;
95#[allow(dead_code, unused_imports)]
96mod dns_parser;
97mod httpc;
98mod resolve;
99mod tls_api;
100#[allow(dead_code, unused_variables)]
101mod types;
102
103pub use crate::api::*;
104#[cfg(feature = "native")]
105pub use native_tls::Error as TLSError;
106#[cfg(feature = "openssl")]
107pub use openssl::error::Error as OpenSSLError;
108#[cfg(feature = "openssl")]
109pub use openssl::error::ErrorStack as OpenSSLErrorStack;
110#[cfg(feature = "openssl")]
111pub use openssl::ssl::Error as TLSError;
112#[cfg(feature = "rustls")]
113pub use rustls::Error as TLSError;
114
115#[cfg(not(any(feature = "rustls", feature = "native", feature = "openssl")))]
116pub use crate::tls_api::{dummy::hash, HashType};
117#[cfg(feature = "native")]
118pub use crate::tls_api::{native::hash, HashType};
119#[cfg(feature = "openssl")]
120pub use crate::tls_api::{openssl::hash, HashType};
121#[cfg(feature = "rustls")]
122pub use crate::tls_api::{rustls::hash, HashType};
123
124pub type Result<T> = ::std::result::Result<T, Error>;
125#[derive(Debug, Fail)]
126pub enum Error {
127 #[fail(display = "IO error: {}", _0)]
128 Io(#[cause] ::std::io::Error),
129
130 #[fail(display = "Utf8 error: {}", _0)]
131 Utf8(#[cause] std::str::Utf8Error),
132
133 #[fail(display = "FromUtf8 error: {}", _0)]
134 FromUtf8(#[cause] std::string::FromUtf8Error),
135
136 #[fail(display = "AddrParseError: {}", _0)]
137 Addr(#[cause] std::net::AddrParseError),
138
139 #[fail(display = "Httparse error: {}", _0)]
140 Httparse(#[cause] httparse::Error),
141
142 #[fail(display = "WebSocket setup failed")]
143 WebSocketFail(Response),
144
145 #[fail(display = "Sync call timed out")]
146 TimeOut,
147 #[fail(
149 display = "Request structure did not contain body and CallSimple was used for POST/PUT."
150 )]
151 MissingBody,
152 #[fail(display = "Response over max_response limit")]
154 ResponseTooBig,
155 #[fail(display = "Redirects back to itself, missing or invalid location header")]
156 InvalidRedirect,
157 #[fail(display = "Connection closed")]
159 Closed,
160 #[fail(display = "No host found in request")]
162 NoHost,
163 #[fail(display = "Invalid scheme")]
165 InvalidScheme,
166
167 #[cfg(any(feature = "rustls", feature = "native", feature = "openssl"))]
168 #[fail(display = "TLS error {}", _0)]
169 Tls(#[cause] TLSError),
170
171 #[cfg(feature = "openssl")]
172 #[fail(display = "OpenSSL stack error {}", _0)]
173 OpenSSLErrorStack(#[cause] OpenSSLErrorStack),
174
175 #[cfg(feature = "openssl")]
176 #[fail(display = "OpenSSL error {}", _0)]
177 OpenSSLError(#[cause] OpenSSLError),
178 #[fail(display = "Concurrent connection limit")]
180 NoSpace,
181
182 #[fail(display = "URL parse error {}", _0)]
183 Url(#[cause] url::ParseError),
184
185 #[fail(display = "{}", _0)]
186 Other(&'static str),
187 #[fail(display = "You must pick one of the features: native, rustls, openssl")]
189 NoTls,
190 #[fail(display = "Error parsing chunked transfer")]
192 ChunkedParse,
193 #[fail(display = "Error parsing WebSocket transfer")]
195 WebSocketParse,
196 #[fail(display = "Error parsing WWW-Authenticate header")]
198 AuthenticateParse,
199
200 #[fail(display = "Pins were configured for domain and they did not match")]
201 InvalidPin,
202
203 #[fail(display = "Can not decompress gzip/deflate response")]
204 DecompressionFailure,
205
206 #[fail(
208 display = "Chunk was larger than configured CallBuilder::chunked_max_chunk. {}",
209 _0
210 )]
211 ChunkOverlimit(usize),
212}
213
214impl From<std::io::Error> for Error {
215 fn from(e: std::io::Error) -> Self {
216 Error::Io(e)
217 }
218}
219impl From<url::ParseError> for Error {
220 fn from(e: url::ParseError) -> Self {
221 Error::Url(e)
222 }
223}
224#[cfg(any(feature = "rustls", feature = "native", feature = "openssl"))]
225impl From<TLSError> for Error {
226 fn from(e: TLSError) -> Self {
227 Error::Tls(e)
228 }
229}
230#[cfg(feature = "openssl")]
231impl From<openssl::error::ErrorStack> for Error {
232 fn from(e: openssl::error::ErrorStack) -> Self {
233 Error::OpenSSLErrorStack(e)
234 }
235}
236#[cfg(feature = "openssl")]
237impl From<OpenSSLError> for Error {
238 fn from(e: OpenSSLError) -> Self {
239 Error::OpenSSLError(e)
240 }
241}
242impl From<httparse::Error> for Error {
243 fn from(e: httparse::Error) -> Self {
244 Error::Httparse(e)
245 }
246}
247impl From<std::string::FromUtf8Error> for Error {
248 fn from(e: std::string::FromUtf8Error) -> Self {
249 Error::FromUtf8(e)
250 }
251}
252
253#[cfg(test)]
254mod tests {
255 #[test]
256 fn parse_headers() {
257 let v = b"HTTP/1.1 200 OK\r\nContent-length: 100\r\nUpgrade: websocket\r\n".to_vec();
258 let mut r = crate::Response::new();
259 r.hdrs = v;
260
261 {
262 let hdrs = r.headers();
263 for h in hdrs {
264 println!("{}: {}", h.name, h.value);
265 }
266 }
267 }
268}