1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! `awc` is an asynchronous HTTP and WebSocket client library.
//!
//! # `GET` Requests
//! ```no_run
//! # #[actix_rt::main]
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
//! // create client
//! let mut client = awc::Client::default();
//!
//! // construct request
//! let req = client.get("http://www.rust-lang.org")
//!     .insert_header(("User-Agent", "awc/3.0"));
//!
//! // send request and await response
//! let res = req.send().await?;
//! println!("Response: {:?}", res);
//! # Ok(())
//! # }
//! ```
//!
//! # `POST` Requests
//! ## Raw Body
//! ```no_run
//! # #[actix_rt::main]
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
//! let mut client = awc::Client::default();
//! let response = client.post("http://httpbin.org/post")
//!     .send_body("Raw body contents")
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## JSON
//! ```no_run
//! # #[actix_rt::main]
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
//! let request = serde_json::json!({
//!     "lang": "rust",
//!     "body": "json"
//! });
//!
//! let mut client = awc::Client::default();
//! let response = client.post("http://httpbin.org/post")
//!     .send_json(&request)
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## URL Encoded Form
//! ```no_run
//! # #[actix_rt::main]
//! # async fn main() -> Result<(), awc::error::SendRequestError> {
//! let params = [("foo", "bar"), ("baz", "quux")];
//!
//! let mut client = awc::Client::default();
//! let response = client.post("http://httpbin.org/post")
//!     .send_form(&params)
//!     .await?;
//! # Ok(())
//! # }
//! ```
//!
//! # Response Compression
//! All [official][iana-encodings] and common content encoding codecs are supported, optionally.
//!
//! The `Accept-Encoding` header will automatically be populated with enabled codecs and added to
//! outgoing requests, allowing servers to select their `Content-Encoding` accordingly.
//!
//! Feature flags enable these codecs according to the table below. By default, all `compress-*`
//! features are enabled.
//!
//! | Feature           | Codecs        |
//! | ----------------- | ------------- |
//! | `compress-brotli` | brotli        |
//! | `compress-gzip`   | gzip, deflate |
//! | `compress-zstd`   | zstd          |
//!
//! [iana-encodings]: https://www.iana.org/assignments/http-parameters/http-parameters.xhtml#content-coding
//!
//! # WebSockets
//! ```no_run
//! # #[actix_rt::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use futures_util::{SinkExt as _, StreamExt as _};
//!
//! let (_resp, mut connection) = awc::Client::new()
//!     .ws("ws://echo.websocket.org")
//!     .connect()
//!     .await?;
//!
//! connection
//!     .send(awc::ws::Message::Text("Echo".into()))
//!     .await?;
//!
//! let response = connection.next().await.unwrap()?;
//! assert_eq!(response, awc::ws::Frame::Text("Echo".into()));
//! # Ok(())
//! # }
//! ```

#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![allow(
    clippy::type_complexity,
    clippy::borrow_interior_mutable_const,
    clippy::needless_doctest_main,
    clippy::uninlined_format_args
)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

pub use actix_http::body;

#[cfg(feature = "cookies")]
pub use cookie;

mod any_body;
mod builder;
mod client;
mod connect;
pub mod error;
mod frozen;
pub mod middleware;
mod request;
mod responses;
mod sender;
pub mod test;
pub mod ws;

pub mod http {
    //! Various HTTP related types.

    // TODO: figure out how best to expose http::Error vs actix_http::Error
    pub use actix_http::{
        header, uri, ConnectionType, Error, Method, StatusCode, Uri, Version,
    };
}

pub use self::builder::ClientBuilder;
pub use self::client::{Client, Connect, Connector};
pub use self::connect::{BoxConnectorService, BoxedSocket, ConnectRequest, ConnectResponse};
pub use self::frozen::{FrozenClientRequest, FrozenSendBuilder};
pub use self::request::ClientRequest;
#[allow(deprecated)]
pub use self::responses::{ClientResponse, JsonBody, MessageBody, ResponseBody};
pub use self::sender::SendClientRequest;

pub(crate) type BoxError = Box<dyn std::error::Error>;