1use std::{convert::TryFrom, rc::Rc, time::Duration};
4
5use actix_http::{error::HttpError, header::HeaderMap, Method, RequestHead, Uri};
6use actix_rt::net::TcpStream;
7use actix_service::Service;
8pub use actix_tls::connect::{
9 ConnectError as TcpConnectError, ConnectInfo, Connection as TcpConnection,
10};
11
12use crate::{ws, BoxConnectorService, ClientBuilder, ClientRequest};
13
14mod config;
15mod connection;
16mod connector;
17mod error;
18mod h1proto;
19mod h2proto;
20mod pool;
21
22pub use self::connection::{Connection, ConnectionIo};
23pub use self::connector::{Connector, ConnectorService};
24pub use self::error::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError};
25
26#[derive(Clone)]
27pub struct Connect {
28 pub uri: Uri,
29 pub addr: Option<std::net::SocketAddr>,
30}
31
32#[derive(Clone)]
54pub struct Client(pub(crate) ClientConfig);
55
56#[derive(Clone)]
57pub(crate) struct ClientConfig {
58 pub(crate) connector: BoxConnectorService,
59 pub(crate) default_headers: Rc<HeaderMap>,
60 pub(crate) timeout: Option<Duration>,
61}
62
63impl Default for Client {
64 fn default() -> Self {
65 ClientBuilder::new().finish()
66 }
67}
68
69impl Client {
70 pub fn new() -> Client {
72 Client::default()
73 }
74
75 pub fn builder() -> ClientBuilder<
79 impl Service<
80 ConnectInfo<Uri>,
81 Response = TcpConnection<Uri, TcpStream>,
82 Error = TcpConnectError,
83 > + Clone,
84 > {
85 ClientBuilder::new()
86 }
87
88 pub fn request<U>(&self, method: Method, url: U) -> ClientRequest
90 where
91 Uri: TryFrom<U>,
92 <Uri as TryFrom<U>>::Error: Into<HttpError>,
93 {
94 let mut req = ClientRequest::new(method, url, self.0.clone());
95
96 for header in self.0.default_headers.iter() {
97 req = req.append_header(header);
98 }
99
100 req
101 }
102
103 pub fn request_from<U>(&self, url: U, head: &RequestHead) -> ClientRequest
108 where
109 Uri: TryFrom<U>,
110 <Uri as TryFrom<U>>::Error: Into<HttpError>,
111 {
112 let mut req = self.request(head.method.clone(), url);
113 for header in head.headers.iter() {
114 req = req.insert_header_if_none(header);
115 }
116 req
117 }
118
119 pub fn get<U>(&self, url: U) -> ClientRequest
121 where
122 Uri: TryFrom<U>,
123 <Uri as TryFrom<U>>::Error: Into<HttpError>,
124 {
125 self.request(Method::GET, url)
126 }
127
128 pub fn head<U>(&self, url: U) -> ClientRequest
130 where
131 Uri: TryFrom<U>,
132 <Uri as TryFrom<U>>::Error: Into<HttpError>,
133 {
134 self.request(Method::HEAD, url)
135 }
136
137 pub fn put<U>(&self, url: U) -> ClientRequest
139 where
140 Uri: TryFrom<U>,
141 <Uri as TryFrom<U>>::Error: Into<HttpError>,
142 {
143 self.request(Method::PUT, url)
144 }
145
146 pub fn post<U>(&self, url: U) -> ClientRequest
148 where
149 Uri: TryFrom<U>,
150 <Uri as TryFrom<U>>::Error: Into<HttpError>,
151 {
152 self.request(Method::POST, url)
153 }
154
155 pub fn patch<U>(&self, url: U) -> ClientRequest
157 where
158 Uri: TryFrom<U>,
159 <Uri as TryFrom<U>>::Error: Into<HttpError>,
160 {
161 self.request(Method::PATCH, url)
162 }
163
164 pub fn delete<U>(&self, url: U) -> ClientRequest
166 where
167 Uri: TryFrom<U>,
168 <Uri as TryFrom<U>>::Error: Into<HttpError>,
169 {
170 self.request(Method::DELETE, url)
171 }
172
173 pub fn options<U>(&self, url: U) -> ClientRequest
175 where
176 Uri: TryFrom<U>,
177 <Uri as TryFrom<U>>::Error: Into<HttpError>,
178 {
179 self.request(Method::OPTIONS, url)
180 }
181
182 pub fn ws<U>(&self, url: U) -> ws::WebsocketsRequest
185 where
186 Uri: TryFrom<U>,
187 <Uri as TryFrom<U>>::Error: Into<HttpError>,
188 {
189 let mut req = ws::WebsocketsRequest::new(url, self.0.clone());
190 for (key, value) in self.0.default_headers.iter() {
191 req.head.headers.insert(key.clone(), value.clone());
192 }
193 req
194 }
195
196 pub fn headers(&mut self) -> Option<&mut HeaderMap> {
201 Rc::get_mut(&mut self.0.default_headers)
202 }
203}