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