attohttpc/request/session.rs
1use std::convert::TryInto;
2use std::sync::Arc;
3use std::time::Duration;
4
5use http::header::{HeaderValue, IntoHeaderName};
6use http::Method;
7
8#[cfg(feature = "charsets")]
9use crate::charsets::Charset;
10use crate::error::{Error, Result};
11use crate::request::proxy::ProxySettings;
12use crate::request::{BaseSettings, RequestBuilder};
13use crate::tls::Certificate;
14
15/// `Session` is a type that can carry settings over multiple requests. The settings applied to the
16/// `Session` are applied to every request created from this `Session`.
17///
18/// `Session` can be cloned cheaply and sent to other threads as it uses [std::sync::Arc] internally.
19#[derive(Clone, Debug, Default)]
20pub struct Session {
21 base_settings: Arc<BaseSettings>,
22}
23
24impl Session {
25 /// Create a new `Session` with default settings.
26 pub fn new() -> Session {
27 Session {
28 base_settings: Arc::new(BaseSettings::default()),
29 }
30 }
31
32 /// Create a new `RequestBuilder` with the GET method and this Session's settings applied on it.
33 pub fn get<U>(&self, base_url: U) -> RequestBuilder
34 where
35 U: AsRef<str>,
36 {
37 RequestBuilder::with_settings(Method::GET, base_url, self.base_settings.clone())
38 }
39
40 /// Create a new `RequestBuilder` with the POST method and this Session's settings applied on it.
41 pub fn post<U>(&self, base_url: U) -> RequestBuilder
42 where
43 U: AsRef<str>,
44 {
45 RequestBuilder::with_settings(Method::POST, base_url, self.base_settings.clone())
46 }
47
48 /// Create a new `RequestBuilder` with the PUT method and this Session's settings applied on it.
49 pub fn put<U>(&self, base_url: U) -> RequestBuilder
50 where
51 U: AsRef<str>,
52 {
53 RequestBuilder::with_settings(Method::PUT, base_url, self.base_settings.clone())
54 }
55
56 /// Create a new `RequestBuilder` with the DELETE method and this Session's settings applied on it.
57 pub fn delete<U>(&self, base_url: U) -> RequestBuilder
58 where
59 U: AsRef<str>,
60 {
61 RequestBuilder::with_settings(Method::DELETE, base_url, self.base_settings.clone())
62 }
63
64 /// Create a new `RequestBuilder` with the HEAD method and this Session's settings applied on it.
65 pub fn head<U>(&self, base_url: U) -> RequestBuilder
66 where
67 U: AsRef<str>,
68 {
69 RequestBuilder::with_settings(Method::HEAD, base_url, self.base_settings.clone())
70 }
71
72 /// Create a new `RequestBuilder` with the OPTIONS method and this Session's settings applied on it.
73 pub fn options<U>(&self, base_url: U) -> RequestBuilder
74 where
75 U: AsRef<str>,
76 {
77 RequestBuilder::with_settings(Method::OPTIONS, base_url, self.base_settings.clone())
78 }
79
80 /// Create a new `RequestBuilder` with the PATCH method and this Session's settings applied on it.
81 pub fn patch<U>(&self, base_url: U) -> RequestBuilder
82 where
83 U: AsRef<str>,
84 {
85 RequestBuilder::with_settings(Method::PATCH, base_url, self.base_settings.clone())
86 }
87
88 /// Create a new `RequestBuilder` with the TRACE method and this Session's settings applied on it.
89 pub fn trace<U>(&self, base_url: U) -> RequestBuilder
90 where
91 U: AsRef<str>,
92 {
93 RequestBuilder::with_settings(Method::TRACE, base_url, self.base_settings.clone())
94 }
95
96 //
97 // Settings
98 //
99
100 /// Modify a header for this `Session`.
101 ///
102 /// If the header is already present, the value will be replaced. If you wish to append a new header,
103 /// use `header_append`.
104 ///
105 /// # Panics
106 /// This method will panic if the value is invalid.
107 pub fn header<H, V>(&mut self, header: H, value: V)
108 where
109 H: IntoHeaderName,
110 V: TryInto<HeaderValue>,
111 Error: From<V::Error>,
112 {
113 self.try_header(header, value).expect("invalid header value");
114 }
115
116 /// Append a new header for this `Session`.
117 ///
118 /// The new header is always appended to the headers, even if the header already exists.
119 ///
120 /// # Panics
121 /// This method will panic if the value is invalid.
122 pub fn header_append<H, V>(&mut self, header: H, value: V)
123 where
124 H: IntoHeaderName,
125 V: TryInto<HeaderValue>,
126 Error: From<V::Error>,
127 {
128 self.try_header_append(header, value).expect("invalid header value");
129 }
130
131 /// Modify a header for this `Session`.
132 ///
133 /// If the header is already present, the value will be replaced. If you wish to append a new header,
134 /// use `header_append`.
135 pub fn try_header<H, V>(&mut self, header: H, value: V) -> Result<()>
136 where
137 H: IntoHeaderName,
138 V: TryInto<HeaderValue>,
139 Error: From<V::Error>,
140 {
141 self.base_settings.try_header(header, value)
142 }
143
144 /// Append a new header to this `Session`.
145 ///
146 /// The new header is always appended to the headers, even if the header already exists.
147 pub fn try_header_append<H, V>(&mut self, header: H, value: V) -> Result<()>
148 where
149 H: IntoHeaderName,
150 V: TryInto<HeaderValue>,
151 Error: From<V::Error>,
152 {
153 self.base_settings.try_header_append(header, value)
154 }
155
156 /// Set the maximum number of headers accepted in responses to requests created from this `Session`.
157 ///
158 /// The default is 100.
159 pub fn max_headers(&mut self, max_headers: usize) {
160 self.base_settings.set_max_headers(max_headers);
161 }
162
163 /// Set the maximum number of redirections the requests created from this `Session` can perform.
164 ///
165 /// The default is 5.
166 pub fn max_redirections(&mut self, max_redirections: u32) {
167 self.base_settings.set_max_redirections(max_redirections);
168 }
169
170 /// Sets if requests created from this `Session` should follow redirects, 3xx codes.
171 ///
172 /// This value defaults to true.
173 pub fn follow_redirects(&mut self, follow_redirects: bool) {
174 self.base_settings.set_follow_redirects(follow_redirects);
175 }
176
177 /// Sets a connect timeout for requests created from this `Session`.
178 ///
179 /// The default is 30 seconds.
180 pub fn connect_timeout(&mut self, connect_timeout: Duration) {
181 self.base_settings.set_connect_timeout(connect_timeout);
182 }
183
184 /// Sets a read timeout for requests created from this `Session`.
185 ///
186 /// The default is 30 seconds.
187 pub fn read_timeout(&mut self, read_timeout: Duration) {
188 self.base_settings.set_read_tmeout(read_timeout);
189 }
190
191 /// Sets a timeout for the maximum duration of requests created from this `Session`.
192 ///
193 /// Applies after a TCP connection is established. Defaults to no timeout.
194 pub fn timeout(&mut self, timeout: Duration) {
195 self.base_settings.set_timeout(Some(timeout));
196 }
197
198 /// Sets the proxy settigns for requests created from this `Session`.
199 ///
200 /// If left untouched, the defaults are to use system proxy settings found in environment variables.
201 pub fn proxy_settings(&mut self, proxy_settings: ProxySettings) {
202 self.base_settings.set_proxy_settings(proxy_settings);
203 }
204
205 /// Set the default charset to use while parsing the responses of requests created from this `Session`.
206 ///
207 /// If the response does not say which charset it uses, this charset will be used to decode the requests.
208 /// This value defaults to `None`, in which case ISO-8859-1 is used.
209 #[cfg(feature = "charsets")]
210 pub fn default_charset(&mut self, default_charset: Option<Charset>) {
211 self.base_settings.set_default_charset(default_charset);
212 }
213
214 /// Sets if requests created from this `Session` will announce that they accept compression.
215 ///
216 /// This value defaults to true. Note that this only lets the browser know that the requests support
217 /// compression, the server might choose not to compress the content.
218 #[cfg(feature = "flate2")]
219 pub fn allow_compression(&mut self, allow_compression: bool) {
220 self.base_settings.set_allow_compression(allow_compression);
221 }
222
223 /// Sets if requests created from this `Session` will accept invalid TLS certificates.
224 ///
225 /// Accepting invalid certificates implies that invalid hostnames are accepted
226 /// as well.
227 ///
228 /// The default value is `false`.
229 ///
230 /// # Danger
231 /// Use this setting with care. This will accept **any** TLS certificate valid or not.
232 /// If you are using self signed certificates, it is much safer to add their root CA
233 /// to the list of trusted root CAs by your system.
234 pub fn danger_accept_invalid_certs(&mut self, accept_invalid_certs: bool) {
235 self.base_settings.set_accept_invalid_certs(accept_invalid_certs);
236 }
237
238 /// Sets if requests created from this `Session` will accept an invalid hostname in a TLS certificate.
239 ///
240 /// The default value is `false`.
241 ///
242 /// # Danger
243 /// Use this setting with care. This will accept TLS certificates that do not match
244 /// the hostname.
245 pub fn danger_accept_invalid_hostnames(&mut self, accept_invalid_hostnames: bool) {
246 self.base_settings
247 .set_accept_invalid_hostnames(accept_invalid_hostnames);
248 }
249
250 /// Adds a root certificate that will be trusted by requests created from this `Session`.
251 pub fn add_root_certificate(&mut self, cert: Certificate) {
252 self.base_settings.add_root_certificate(cert);
253 }
254}