async_curl/
curl.rs

1use std::{path::Path, time::Duration};
2
3use curl::easy::{
4    Auth, Easy2, Form, Handler, HttpVersion, IpResolve, List, NetRc, ProxyType, SslOpt, SslVersion,
5    TimeCondition,
6};
7
8use crate::{
9    actor::{Actor, CurlActor},
10    error::Error,
11};
12
13/// A type-state struct in building the HttpClient.
14pub struct Build;
15/// A type-state struct in building the HttpClient.
16pub struct Perform;
17
18/// The HTTP Client struct that wraps curl Easy2.
19pub struct AsyncCurl<C, S>
20where
21    C: Handler + std::fmt::Debug + Send + 'static,
22{
23    curl: CurlActor<C>,
24    easy: Easy2<C>,
25    _state: S,
26}
27
28impl<C> AsyncCurl<C, Build>
29where
30    C: Handler + std::fmt::Debug + Send + 'static,
31{
32    /// Creates a new HTTP Client.
33    ///
34    /// The [`CurlActor`](https://docs.rs/async-curl/latest/async_curl/actor/struct.CurlActor.html) is the actor handler that can be cloned to be able to handle multiple request sender
35    /// and a single consumer that is spawned in the background upon creation of this object to be able to achieve
36    /// non-blocking I/O during curl perform.
37    pub fn new(curl: CurlActor<C>, collector: C) -> Self {
38        Self {
39            curl,
40            easy: Easy2::new(collector),
41            _state: Build,
42        }
43    }
44
45    // =========================================================================
46    // Behavior options
47
48    /// Configures this handle to have verbose output to help debug protocol
49    /// information.
50    ///
51    /// By default output goes to stderr, but the `stderr` function on this type
52    /// can configure that. You can also use the `debug_function` method to get
53    /// all protocol data sent and received.
54    ///
55    /// By default, this option is `false`.
56    pub fn verbose(mut self, verbose: bool) -> Result<Self, Error<C>> {
57        self.easy.verbose(verbose).map_err(|err| {
58            log::trace!("{err}");
59            Error::Curl(err)
60        })?;
61        Ok(self)
62    }
63
64    /// Indicates whether header information is streamed to the output body of
65    /// this request.
66    ///
67    /// This option is only relevant for protocols which have header metadata
68    /// (like http or ftp). It's not generally possible to extract headers
69    /// from the body if using this method, that use case should be intended for
70    /// the `header_function` method.
71    ///
72    /// To set HTTP headers, use the `http_header` method.
73    ///
74    /// By default, this option is `false` and corresponds to
75    /// `CURLOPT_HEADER`.
76    pub fn show_header(mut self, show: bool) -> Result<Self, Error<C>> {
77        self.easy.show_header(show).map_err(|err| {
78            log::trace!("{err}");
79            Error::Curl(err)
80        })?;
81        Ok(self)
82    }
83
84    /// Indicates whether a progress meter will be shown for requests done with
85    /// this handle.
86    ///
87    /// This will also prevent the `progress_function` from being called.
88    ///
89    /// By default this option is `false` and corresponds to
90    /// `CURLOPT_NOPROGRESS`.
91    pub fn progress(mut self, progress: bool) -> Result<Self, Error<C>> {
92        self.easy.progress(progress).map_err(|err| {
93            log::trace!("{err}");
94            Error::Curl(err)
95        })?;
96        Ok(self)
97    }
98
99    /// Inform libcurl whether or not it should install signal handlers or
100    /// attempt to use signals to perform library functions.
101    ///
102    /// If this option is disabled then timeouts during name resolution will not
103    /// work unless libcurl is built against c-ares. Note that enabling this
104    /// option, however, may not cause libcurl to work with multiple threads.
105    ///
106    /// By default this option is `false` and corresponds to `CURLOPT_NOSIGNAL`.
107    /// Note that this default is **different than libcurl** as it is intended
108    /// that this library is threadsafe by default. See the [libcurl docs] for
109    /// some more information.
110    ///
111    /// [libcurl docs]: https://curl.haxx.se/libcurl/c/threadsafe.html
112    pub fn signal(mut self, signal: bool) -> Result<Self, Error<C>> {
113        self.easy.signal(signal).map_err(|err| {
114            log::trace!("{err}");
115            Error::Curl(err)
116        })?;
117        Ok(self)
118    }
119
120    /// Indicates whether multiple files will be transferred based on the file
121    /// name pattern.
122    ///
123    /// The last part of a filename uses fnmatch-like pattern matching.
124    ///
125    /// By default this option is `false` and corresponds to
126    /// `CURLOPT_WILDCARDMATCH`.
127    pub fn wildcard_match(mut self, m: bool) -> Result<Self, Error<C>> {
128        self.easy.wildcard_match(m).map_err(|err| {
129            log::trace!("{err}");
130            Error::Curl(err)
131        })?;
132        Ok(self)
133    }
134
135    /// Provides the Unix domain socket which this handle will work with.
136    ///
137    /// The string provided must be a path to a Unix domain socket encoded with
138    /// the format:
139    ///
140    /// ```text
141    /// /path/file.sock
142    /// ```
143    ///
144    /// By default this option is not set and corresponds to
145    /// [`CURLOPT_UNIX_SOCKET_PATH`](https://curl.haxx.se/libcurl/c/CURLOPT_UNIX_SOCKET_PATH.html).
146    pub fn unix_socket(mut self, unix_domain_socket: &str) -> Result<Self, Error<C>> {
147        self.easy.unix_socket(unix_domain_socket).map_err(|err| {
148            log::trace!("{err}");
149            Error::Curl(err)
150        })?;
151        Ok(self)
152    }
153
154    /// Provides the Unix domain socket which this handle will work with.
155    ///
156    /// The string provided must be a path to a Unix domain socket encoded with
157    /// the format:
158    ///
159    /// ```text
160    /// /path/file.sock
161    /// ```
162    ///
163    /// This function is an alternative to [`Easy2::unix_socket`] that supports
164    /// non-UTF-8 paths and also supports disabling Unix sockets by setting the
165    /// option to `None`.
166    ///
167    /// By default this option is not set and corresponds to
168    /// [`CURLOPT_UNIX_SOCKET_PATH`](https://curl.haxx.se/libcurl/c/CURLOPT_UNIX_SOCKET_PATH.html).
169    pub fn unix_socket_path<P: AsRef<Path>>(mut self, path: Option<P>) -> Result<Self, Error<C>> {
170        self.easy.unix_socket_path(path).map_err(|err| {
171            log::trace!("{err}");
172            Error::Curl(err)
173        })?;
174        Ok(self)
175    }
176
177    // =========================================================================
178    // Error options
179
180    // TODO: error buffer and stderr
181
182    /// Indicates whether this library will fail on HTTP response codes >= 400.
183    ///
184    /// This method is not fail-safe especially when authentication is involved.
185    ///
186    /// By default this option is `false` and corresponds to
187    /// `CURLOPT_FAILONERROR`.
188    pub fn fail_on_error(mut self, fail: bool) -> Result<Self, Error<C>> {
189        self.easy.fail_on_error(fail).map_err(|err| {
190            log::trace!("{err}");
191            Error::Curl(err)
192        })?;
193        Ok(self)
194    }
195
196    // =========================================================================
197    // Network options
198
199    /// Provides the URL which this handle will work with.
200    ///
201    /// The string provided must be URL-encoded with the format:
202    ///
203    /// ```text
204    /// scheme://host:port/path
205    /// ```
206    ///
207    /// The syntax is not validated as part of this function and that is
208    /// deferred until later.
209    ///
210    /// By default this option is not set and `perform` will not work until it
211    /// is set. This option corresponds to `CURLOPT_URL`.
212    pub fn url(mut self, url: &str) -> Result<Self, Error<C>> {
213        self.easy.url(url).map_err(|err| {
214            log::trace!("{err}");
215            Error::Curl(err)
216        })?;
217        Ok(self)
218    }
219
220    /// Configures the port number to connect to, instead of the one specified
221    /// in the URL or the default of the protocol.
222    pub fn port(mut self, port: u16) -> Result<Self, Error<C>> {
223        self.easy.port(port).map_err(|err| {
224            log::trace!("{err}");
225            Error::Curl(err)
226        })?;
227        Ok(self)
228    }
229
230    /// Connect to a specific host and port.
231    ///
232    /// Each single string should be written using the format
233    /// `HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT` where `HOST` is the host of
234    /// the request, `PORT` is the port of the request, `CONNECT-TO-HOST` is the
235    /// host name to connect to, and `CONNECT-TO-PORT` is the port to connect
236    /// to.
237    ///
238    /// The first string that matches the request's host and port is used.
239    ///
240    /// By default, this option is empty and corresponds to
241    /// [`CURLOPT_CONNECT_TO`](https://curl.haxx.se/libcurl/c/CURLOPT_CONNECT_TO.html).
242    pub fn connect_to(mut self, list: List) -> Result<Self, Error<C>> {
243        self.easy.connect_to(list).map_err(|err| {
244            log::trace!("{err}");
245            Error::Curl(err)
246        })?;
247        Ok(self)
248    }
249
250    /// Indicates whether sequences of `/../` and `/./` will be squashed or not.
251    ///
252    /// By default this option is `false` and corresponds to
253    /// `CURLOPT_PATH_AS_IS`.
254    pub fn path_as_is(mut self, as_is: bool) -> Result<Self, Error<C>> {
255        self.easy.path_as_is(as_is).map_err(|err| {
256            log::trace!("{err}");
257            Error::Curl(err)
258        })?;
259        Ok(self)
260    }
261
262    /// Provide the URL of a proxy to use.
263    ///
264    /// By default this option is not set and corresponds to `CURLOPT_PROXY`.
265    pub fn proxy(mut self, url: &str) -> Result<Self, Error<C>> {
266        self.easy.proxy(url).map_err(|err| {
267            log::trace!("{err}");
268            Error::Curl(err)
269        })?;
270        Ok(self)
271    }
272
273    /// Provide port number the proxy is listening on.
274    ///
275    /// By default this option is not set (the default port for the proxy
276    /// protocol is used) and corresponds to `CURLOPT_PROXYPORT`.
277    pub fn proxy_port(mut self, port: u16) -> Result<Self, Error<C>> {
278        self.easy.proxy_port(port).map_err(|err| {
279            log::trace!("{err}");
280            Error::Curl(err)
281        })?;
282        Ok(self)
283    }
284
285    /// Set CA certificate to verify peer against for proxy.
286    ///
287    /// By default this value is not set and corresponds to
288    /// `CURLOPT_PROXY_CAINFO`.
289    pub fn proxy_cainfo(mut self, cainfo: &str) -> Result<Self, Error<C>> {
290        self.easy.proxy_cainfo(cainfo).map_err(|err| {
291            log::trace!("{err}");
292            Error::Curl(err)
293        })?;
294        Ok(self)
295    }
296
297    /// Specify a directory holding CA certificates for proxy.
298    ///
299    /// The specified directory should hold multiple CA certificates to verify
300    /// the HTTPS proxy with. If libcurl is built against OpenSSL, the
301    /// certificate directory must be prepared using the OpenSSL `c_rehash`
302    /// utility.
303    ///
304    /// By default this value is not set and corresponds to
305    /// `CURLOPT_PROXY_CAPATH`.
306    pub fn proxy_capath<P: AsRef<Path>>(mut self, path: P) -> Result<Self, Error<C>> {
307        self.easy.proxy_capath(path).map_err(|err| {
308            log::trace!("{err}");
309            Error::Curl(err)
310        })?;
311        Ok(self)
312    }
313
314    /// Set client certificate for proxy.
315    ///
316    /// By default this value is not set and corresponds to
317    /// `CURLOPT_PROXY_SSLCERT`.
318    pub fn proxy_sslcert(mut self, sslcert: &str) -> Result<Self, Error<C>> {
319        self.easy.proxy_sslcert(sslcert).map_err(|err| {
320            log::trace!("{err}");
321            Error::Curl(err)
322        })?;
323        Ok(self)
324    }
325
326    /// Specify type of the client SSL certificate for HTTPS proxy.
327    ///
328    /// The string should be the format of your certificate. Supported formats
329    /// are "PEM" and "DER", except with Secure Transport. OpenSSL (versions
330    /// 0.9.3 and later) and Secure Transport (on iOS 5 or later, or OS X 10.7
331    /// or later) also support "P12" for PKCS#12-encoded files.
332    ///
333    /// By default this option is "PEM" and corresponds to
334    /// `CURLOPT_PROXY_SSLCERTTYPE`.
335    pub fn proxy_sslcert_type(mut self, kind: &str) -> Result<Self, Error<C>> {
336        self.easy.proxy_sslcert_type(kind).map_err(|err| {
337            log::trace!("{err}");
338            Error::Curl(err)
339        })?;
340        Ok(self)
341    }
342
343    /// Set the client certificate for the proxy using an in-memory blob.
344    ///
345    /// The specified byte buffer should contain the binary content of the
346    /// certificate, which will be copied into the handle.
347    ///
348    /// By default this option is not set and corresponds to
349    /// `CURLOPT_PROXY_SSLCERT_BLOB`.
350    pub fn proxy_sslcert_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
351        self.easy.proxy_sslcert_blob(blob).map_err(|err| {
352            log::trace!("{err}");
353            Error::Curl(err)
354        })?;
355        Ok(self)
356    }
357
358    /// Set private key for HTTPS proxy.
359    ///
360    /// By default this value is not set and corresponds to
361    /// `CURLOPT_PROXY_SSLKEY`.
362    pub fn proxy_sslkey(mut self, sslkey: &str) -> Result<Self, Error<C>> {
363        self.easy.proxy_sslkey(sslkey).map_err(|err| {
364            log::trace!("{err}");
365            Error::Curl(err)
366        })?;
367        Ok(self)
368    }
369
370    /// Set type of the private key file for HTTPS proxy.
371    ///
372    /// The string should be the format of your private key. Supported formats
373    /// are "PEM", "DER" and "ENG".
374    ///
375    /// The format "ENG" enables you to load the private key from a crypto
376    /// engine. In this case `ssl_key` is used as an identifier passed to
377    /// the engine. You have to set the crypto engine with `ssl_engine`.
378    /// "DER" format key file currently does not work because of a bug in
379    /// OpenSSL.
380    ///
381    /// By default this option is "PEM" and corresponds to
382    /// `CURLOPT_PROXY_SSLKEYTYPE`.
383    pub fn proxy_sslkey_type(mut self, kind: &str) -> Result<Self, Error<C>> {
384        self.easy.proxy_sslkey_type(kind).map_err(|err| {
385            log::trace!("{err}");
386            Error::Curl(err)
387        })?;
388        Ok(self)
389    }
390
391    /// Set the private key for the proxy using an in-memory blob.
392    ///
393    /// The specified byte buffer should contain the binary content of the
394    /// private key, which will be copied into the handle.
395    ///
396    /// By default this option is not set and corresponds to
397    /// `CURLOPT_PROXY_SSLKEY_BLOB`.
398    pub fn proxy_sslkey_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
399        self.easy.proxy_sslkey_blob(blob).map_err(|err| {
400            log::trace!("{err}");
401            Error::Curl(err)
402        })?;
403        Ok(self)
404    }
405
406    /// Set passphrase to private key for HTTPS proxy.
407    ///
408    /// This will be used as the password required to use the `ssl_key`.
409    /// You never needed a pass phrase to load a certificate but you need one to
410    /// load your private key.
411    ///
412    /// By default this option is not set and corresponds to
413    /// `CURLOPT_PROXY_KEYPASSWD`.
414    pub fn proxy_key_password(mut self, password: &str) -> Result<Self, Error<C>> {
415        self.easy.proxy_key_password(password).map_err(|err| {
416            log::trace!("{err}");
417            Error::Curl(err)
418        })?;
419        Ok(self)
420    }
421
422    /// Indicates the type of proxy being used.
423    ///
424    /// By default this option is `ProxyType::Http` and corresponds to
425    /// `CURLOPT_PROXYTYPE`.
426    pub fn proxy_type(mut self, kind: ProxyType) -> Result<Self, Error<C>> {
427        self.easy.proxy_type(kind).map_err(|err| {
428            log::trace!("{err}");
429            Error::Curl(err)
430        })?;
431        Ok(self)
432    }
433
434    /// Provide a list of hosts that should not be proxied to.
435    ///
436    /// This string is a comma-separated list of hosts which should not use the
437    /// proxy specified for connections. A single `*` character is also accepted
438    /// as a wildcard for all hosts.
439    ///
440    /// By default this option is not set and corresponds to
441    /// `CURLOPT_NOPROXY`.
442    pub fn noproxy(mut self, skip: &str) -> Result<Self, Error<C>> {
443        self.easy.noproxy(skip).map_err(|err| {
444            log::trace!("{err}");
445            Error::Curl(err)
446        })?;
447        Ok(self)
448    }
449
450    /// Inform curl whether it should tunnel all operations through the proxy.
451    ///
452    /// This essentially means that a `CONNECT` is sent to the proxy for all
453    /// outbound requests.
454    ///
455    /// By default this option is `false` and corresponds to
456    /// `CURLOPT_HTTPPROXYTUNNEL`.
457    pub fn http_proxy_tunnel(mut self, tunnel: bool) -> Result<Self, Error<C>> {
458        self.easy.http_proxy_tunnel(tunnel).map_err(|err| {
459            log::trace!("{err}");
460            Error::Curl(err)
461        })?;
462        Ok(self)
463    }
464
465    /// Tell curl which interface to bind to for an outgoing network interface.
466    ///
467    /// The interface name, IP address, or host name can be specified here.
468    ///
469    /// By default this option is not set and corresponds to
470    /// `CURLOPT_INTERFACE`.
471    pub fn interface(mut self, interface: &str) -> Result<Self, Error<C>> {
472        self.easy.interface(interface).map_err(|err| {
473            log::trace!("{err}");
474            Error::Curl(err)
475        })?;
476        Ok(self)
477    }
478
479    /// Indicate which port should be bound to locally for this connection.
480    ///
481    /// By default this option is 0 (any port) and corresponds to
482    /// `CURLOPT_LOCALPORT`.
483    pub fn set_local_port(mut self, port: u16) -> Result<Self, Error<C>> {
484        self.easy.set_local_port(port).map_err(|err| {
485            log::trace!("{err}");
486            Error::Curl(err)
487        })?;
488        Ok(self)
489    }
490
491    /// Indicates the number of attempts libcurl will perform to find a working
492    /// port number.
493    ///
494    /// By default this option is 1 and corresponds to
495    /// `CURLOPT_LOCALPORTRANGE`.
496    pub fn local_port_range(mut self, range: u16) -> Result<Self, Error<C>> {
497        self.easy.local_port_range(range).map_err(|err| {
498            log::trace!("{err}");
499            Error::Curl(err)
500        })?;
501        Ok(self)
502    }
503
504    /// Sets the DNS servers that wil be used.
505    ///
506    /// Provide a comma separated list, for example: `8.8.8.8,8.8.4.4`.
507    ///
508    /// By default this option is not set and the OS's DNS resolver is used.
509    /// This option can only be used if libcurl is linked against
510    /// [c-ares](https://c-ares.haxx.se), otherwise setting it will return
511    /// an error.
512    pub fn dns_servers(mut self, servers: &str) -> Result<Self, Error<C>> {
513        self.easy.dns_servers(servers).map_err(|err| {
514            log::trace!("{err}");
515            Error::Curl(err)
516        })?;
517        Ok(self)
518    }
519
520    /// Sets the timeout of how long name resolves will be kept in memory.
521    ///
522    /// This is distinct from DNS TTL options and is entirely speculative.
523    ///
524    /// By default this option is 60s and corresponds to
525    /// `CURLOPT_DNS_CACHE_TIMEOUT`.
526    pub fn dns_cache_timeout(mut self, dur: Duration) -> Result<Self, Error<C>> {
527        self.easy.dns_cache_timeout(dur).map_err(|err| {
528            log::trace!("{err}");
529            Error::Curl(err)
530        })?;
531        Ok(self)
532    }
533
534    /// Provide the DNS-over-HTTPS URL.
535    ///
536    /// The parameter must be URL-encoded in the following format:
537    /// `https://host:port/path`. It **must** specify a HTTPS URL.
538    ///
539    /// libcurl does not validate the syntax or use this variable until the
540    /// transfer is issued. Even if you set a crazy value here, this method will
541    /// still return [`Ok`].
542    ///
543    /// curl sends `POST` requests to the given DNS-over-HTTPS URL.
544    ///
545    /// To find the DoH server itself, which might be specified using a name,
546    /// libcurl will use the default name lookup function. You can bootstrap
547    /// that by providing the address for the DoH server with
548    /// [`Easy2::resolve`].
549    ///
550    /// Disable DoH use again by setting this option to [`None`].
551    ///
552    /// By default this option is not set and corresponds to `CURLOPT_DOH_URL`.
553    pub fn doh_url(mut self, url: Option<&str>) -> Result<Self, Error<C>> {
554        self.easy.doh_url(url).map_err(|err| {
555            log::trace!("{err}");
556            Error::Curl(err)
557        })?;
558        Ok(self)
559    }
560
561    /// This option tells curl to verify the authenticity of the DoH
562    /// (DNS-over-HTTPS) server's certificate. A value of `true` means curl
563    /// verifies; `false` means it does not.
564    ///
565    /// This option is the DoH equivalent of [`Easy2::ssl_verify_peer`] and only
566    /// affects requests to the DoH server.
567    ///
568    /// When negotiating a TLS or SSL connection, the server sends a certificate
569    /// indicating its identity. Curl verifies whether the certificate is
570    /// authentic, i.e. that you can trust that the server is who the
571    /// certificate says it is. This trust is based on a chain of digital
572    /// signatures, rooted in certification authority (CA) certificates you
573    /// supply. curl uses a default bundle of CA certificates (the path for that
574    /// is determined at build time) and you can specify alternate certificates
575    /// with the [`Easy2::cainfo`] option or the [`Easy2::capath`] option.
576    ///
577    /// When `doh_ssl_verify_peer` is enabled, and the verification fails to
578    /// prove that the certificate is authentic, the connection fails. When the
579    /// option is zero, the peer certificate verification succeeds regardless.
580    ///
581    /// Authenticating the certificate is not enough to be sure about the
582    /// server. You typically also want to ensure that the server is the server
583    /// you mean to be talking to. Use [`Easy2::doh_ssl_verify_host`] for that.
584    /// The check that the host name in the certificate is valid for the host
585    /// name you are connecting to is done independently of the
586    /// `doh_ssl_verify_peer` option.
587    ///
588    /// **WARNING:** disabling verification of the certificate allows bad guys
589    /// to man-in-the-middle the communication without you knowing it. Disabling
590    /// verification makes the communication insecure. Just having encryption on
591    /// a transfer is not enough as you cannot be sure that you are
592    /// communicating with the correct end-point.
593    ///
594    /// By default this option is set to `true` and corresponds to
595    /// `CURLOPT_DOH_SSL_VERIFYPEER`.
596    pub fn doh_ssl_verify_peer(mut self, verify: bool) -> Result<Self, Error<C>> {
597        self.easy.doh_ssl_verify_peer(verify).map_err(|err| {
598            log::trace!("{err}");
599            Error::Curl(err)
600        })?;
601        Ok(self)
602    }
603
604    /// Tells curl to verify the DoH (DNS-over-HTTPS) server's certificate name
605    /// fields against the host name.
606    ///
607    /// This option is the DoH equivalent of [`Easy2::ssl_verify_host`] and only
608    /// affects requests to the DoH server.
609    ///
610    /// When `doh_ssl_verify_host` is `true`, the SSL certificate provided by
611    /// the DoH server must indicate that the server name is the same as the
612    /// server name to which you meant to connect to, or the connection fails.
613    ///
614    /// Curl considers the DoH server the intended one when the Common Name
615    /// field or a Subject Alternate Name field in the certificate matches the
616    /// host name in the DoH URL to which you told Curl to connect.
617    ///
618    /// When the verify value is set to `false`, the connection succeeds
619    /// regardless of the names used in the certificate. Use that ability with
620    /// caution!
621    ///
622    /// See also [`Easy2::doh_ssl_verify_peer`] to verify the digital signature
623    /// of the DoH server certificate. If libcurl is built against NSS and
624    /// [`Easy2::doh_ssl_verify_peer`] is `false`, `doh_ssl_verify_host` is also
625    /// set to `false` and cannot be overridden.
626    ///
627    /// By default this option is set to `true` and corresponds to
628    /// `CURLOPT_DOH_SSL_VERIFYHOST`.
629    pub fn doh_ssl_verify_host(mut self, verify: bool) -> Result<Self, Error<C>> {
630        self.easy.doh_ssl_verify_host(verify).map_err(|err| {
631            log::trace!("{err}");
632            Error::Curl(err)
633        })?;
634        Ok(self)
635    }
636
637    /// Pass a long as parameter set to 1 to enable or 0 to disable.
638    ///
639    /// This option determines whether libcurl verifies the status of the DoH
640    /// (DNS-over-HTTPS) server cert using the "Certificate Status Request" TLS
641    /// extension (aka. OCSP stapling).
642    ///
643    /// This option is the DoH equivalent of CURLOPT_SSL_VERIFYSTATUS and only
644    /// affects requests to the DoH server.
645    ///
646    /// Note that if this option is enabled but the server does not support the
647    /// TLS extension, the verification will fail.
648    ///
649    /// By default this option is set to `false` and corresponds to
650    /// `CURLOPT_DOH_SSL_VERIFYSTATUS`.
651    pub fn doh_ssl_verify_status(mut self, verify: bool) -> Result<Self, Error<C>> {
652        self.easy.doh_ssl_verify_status(verify).map_err(|err| {
653            log::trace!("{err}");
654            Error::Curl(err)
655        })?;
656        Ok(self)
657    }
658
659    /// Specify the preferred receive buffer size, in bytes.
660    ///
661    /// This is treated as a request, not an order, and the main point of this
662    /// is that the write callback may get called more often with smaller
663    /// chunks.
664    ///
665    /// By default this option is the maximum write size and corresopnds to
666    /// `CURLOPT_BUFFERSIZE`.
667    pub fn buffer_size(mut self, size: usize) -> Result<Self, Error<C>> {
668        self.easy.buffer_size(size).map_err(|err| {
669            log::trace!("{err}");
670            Error::Curl(err)
671        })?;
672        Ok(self)
673    }
674
675    /// Specify the preferred send buffer size, in bytes.
676    ///
677    /// This is treated as a request, not an order, and the main point of this
678    /// is that the read callback may get called more often with smaller
679    /// chunks.
680    ///
681    /// The upload buffer size is by default 64 kilobytes.
682    pub fn upload_buffer_size(mut self, size: usize) -> Result<Self, Error<C>> {
683        self.easy.upload_buffer_size(size).map_err(|err| {
684            log::trace!("{err}");
685            Error::Curl(err)
686        })?;
687        Ok(self)
688    }
689
690    // /// Enable or disable TCP Fast Open
691    // ///
692    // /// By default this options defaults to `false` and corresponds to
693    // /// `CURLOPT_TCP_FASTOPEN`
694    // pub fn fast_open(mut self, enable: bool) -> Result<Self, Error<C>> {
695    // }
696
697    /// Configures whether the TCP_NODELAY option is set, or Nagle's algorithm
698    /// is disabled.
699    ///
700    /// The purpose of Nagle's algorithm is to minimize the number of small
701    /// packet's on the network, and disabling this may be less efficient in
702    /// some situations.
703    ///
704    /// By default this option is `false` and corresponds to
705    /// `CURLOPT_TCP_NODELAY`.
706    pub fn tcp_nodelay(mut self, enable: bool) -> Result<Self, Error<C>> {
707        self.easy.tcp_nodelay(enable).map_err(|err| {
708            log::trace!("{err}");
709            Error::Curl(err)
710        })?;
711        Ok(self)
712    }
713
714    /// Configures whether TCP keepalive probes will be sent.
715    ///
716    /// The delay and frequency of these probes is controlled by `tcp_keepidle`
717    /// and `tcp_keepintvl`.
718    ///
719    /// By default this option is `false` and corresponds to
720    /// `CURLOPT_TCP_KEEPALIVE`.
721    pub fn tcp_keepalive(mut self, enable: bool) -> Result<Self, Error<C>> {
722        self.easy.tcp_keepalive(enable).map_err(|err| {
723            log::trace!("{err}");
724            Error::Curl(err)
725        })?;
726        Ok(self)
727    }
728
729    /// Configures the TCP keepalive idle time wait.
730    ///
731    /// This is the delay, after which the connection is idle, keepalive probes
732    /// will be sent. Not all operating systems support this.
733    ///
734    /// By default this corresponds to `CURLOPT_TCP_KEEPIDLE`.
735    pub fn tcp_keepidle(mut self, amt: Duration) -> Result<Self, Error<C>> {
736        self.easy.tcp_keepidle(amt).map_err(|err| {
737            log::trace!("{err}");
738            Error::Curl(err)
739        })?;
740        Ok(self)
741    }
742
743    /// Configures the delay between keepalive probes.
744    ///
745    /// By default this corresponds to `CURLOPT_TCP_KEEPINTVL`.
746    pub fn tcp_keepintvl(mut self, amt: Duration) -> Result<Self, Error<C>> {
747        self.easy.tcp_keepintvl(amt).map_err(|err| {
748            log::trace!("{err}");
749            Error::Curl(err)
750        })?;
751        Ok(self)
752    }
753
754    /// Configures the scope for local IPv6 addresses.
755    ///
756    /// Sets the scope_id value to use when connecting to IPv6 or link-local
757    /// addresses.
758    ///
759    /// By default this value is 0 and corresponds to `CURLOPT_ADDRESS_SCOPE`
760    pub fn address_scope(mut self, scope: u32) -> Result<Self, Error<C>> {
761        self.easy.address_scope(scope).map_err(|err| {
762            log::trace!("{err}");
763            Error::Curl(err)
764        })?;
765        Ok(self)
766    }
767
768    // =========================================================================
769    // Names and passwords
770
771    /// Configures the username to pass as authentication for this connection.
772    ///
773    /// By default this value is not set and corresponds to `CURLOPT_USERNAME`.
774    pub fn username(mut self, user: &str) -> Result<Self, Error<C>> {
775        self.easy.username(user).map_err(|err| {
776            log::trace!("{err}");
777            Error::Curl(err)
778        })?;
779        Ok(self)
780    }
781
782    /// Configures the password to pass as authentication for this connection.
783    ///
784    /// By default this value is not set and corresponds to `CURLOPT_PASSWORD`.
785    pub fn password(mut self, pass: &str) -> Result<Self, Error<C>> {
786        self.easy.password(pass).map_err(|err| {
787            log::trace!("{err}");
788            Error::Curl(err)
789        })?;
790        Ok(self)
791    }
792
793    /// Set HTTP server authentication methods to try
794    ///
795    /// If more than one method is set, libcurl will first query the site to see
796    /// which authentication methods it supports and then pick the best one you
797    /// allow it to use. For some methods, this will induce an extra network
798    /// round-trip. Set the actual name and password with the `password` and
799    /// `username` methods.
800    ///
801    /// For authentication with a proxy, see `proxy_auth`.
802    ///
803    /// By default this value is basic and corresponds to `CURLOPT_HTTPAUTH`.
804    pub fn http_auth(mut self, auth: &Auth) -> Result<Self, Error<C>> {
805        self.easy.http_auth(auth).map_err(|err| {
806            log::trace!("{err}");
807            Error::Curl(err)
808        })?;
809        Ok(self)
810    }
811
812    /// Provides AWS V4 signature authentication on HTTP(S) header.
813    ///
814    /// `param` is used to create outgoing authentication headers.
815    /// Its format is `provider1[:provider2[:region[:service]]]`.
816    /// `provider1,\ provider2"` are used for generating auth parameters
817    /// such as "Algorithm", "date", "request type" and "signed headers".
818    /// `region` is the geographic area of a resources collection. It is
819    /// extracted from the host name specified in the URL if omitted.
820    /// `service` is a function provided by a cloud. It is extracted
821    /// from the host name specified in the URL if omitted.
822    ///
823    /// Example with "Test:Try", when curl will do the algorithm, it will
824    /// generate "TEST-HMAC-SHA256" for "Algorithm", "x-try-date" and
825    /// "X-Try-Date" for "date", "test4_request" for "request type", and
826    /// "SignedHeaders=content-type;host;x-try-date" for "signed headers".
827    /// If you use just "test", instead of "test:try", test will be use
828    /// for every strings generated.
829    ///
830    /// This is a special auth type that can't be combined with the others.
831    /// It will override the other auth types you might have set.
832    ///
833    /// By default this is not set and corresponds to `CURLOPT_AWS_SIGV4`.
834    pub fn aws_sigv4(mut self, param: &str) -> Result<Self, Error<C>> {
835        self.easy.aws_sigv4(param).map_err(|err| {
836            log::trace!("{err}");
837            Error::Curl(err)
838        })?;
839        Ok(self)
840    }
841
842    /// Configures the proxy username to pass as authentication for this
843    /// connection.
844    ///
845    /// By default this value is not set and corresponds to
846    /// `CURLOPT_PROXYUSERNAME`.
847    pub fn proxy_username(mut self, user: &str) -> Result<Self, Error<C>> {
848        self.easy.proxy_username(user).map_err(|err| {
849            log::trace!("{err}");
850            Error::Curl(err)
851        })?;
852        Ok(self)
853    }
854
855    /// Configures the proxy password to pass as authentication for this
856    /// connection.
857    ///
858    /// By default this value is not set and corresponds to
859    /// `CURLOPT_PROXYPASSWORD`.
860    pub fn proxy_password(mut self, pass: &str) -> Result<Self, Error<C>> {
861        self.easy.proxy_password(pass).map_err(|err| {
862            log::trace!("{err}");
863            Error::Curl(err)
864        })?;
865        Ok(self)
866    }
867
868    /// Set HTTP proxy authentication methods to try
869    ///
870    /// If more than one method is set, libcurl will first query the site to see
871    /// which authentication methods it supports and then pick the best one you
872    /// allow it to use. For some methods, this will induce an extra network
873    /// round-trip. Set the actual name and password with the `proxy_password`
874    /// and `proxy_username` methods.
875    ///
876    /// By default this value is basic and corresponds to `CURLOPT_PROXYAUTH`.
877    pub fn proxy_auth(mut self, auth: &Auth) -> Result<Self, Error<C>> {
878        self.easy.proxy_auth(auth).map_err(|err| {
879            log::trace!("{err}");
880            Error::Curl(err)
881        })?;
882        Ok(self)
883    }
884
885    /// Enable .netrc parsing
886    ///
887    /// By default the .netrc file is ignored and corresponds to `CURL_NETRC_IGNORED`.
888    pub fn netrc(mut self, netrc: NetRc) -> Result<Self, Error<C>> {
889        self.easy.netrc(netrc).map_err(|err| {
890            log::trace!("{err}");
891            Error::Curl(err)
892        })?;
893        Ok(self)
894    }
895
896    // =========================================================================
897    // HTTP Options
898
899    /// Indicates whether the referer header is automatically updated
900    ///
901    /// By default this option is `false` and corresponds to
902    /// `CURLOPT_AUTOREFERER`.
903    pub fn autoreferer(mut self, enable: bool) -> Result<Self, Error<C>> {
904        self.easy.autoreferer(enable).map_err(|err| {
905            log::trace!("{err}");
906            Error::Curl(err)
907        })?;
908        Ok(self)
909    }
910
911    /// Enables automatic decompression of HTTP downloads.
912    ///
913    /// Sets the contents of the Accept-Encoding header sent in an HTTP request.
914    /// This enables decoding of a response with Content-Encoding.
915    ///
916    /// Currently supported encoding are `identity`, `zlib`, and `gzip`. A
917    /// zero-length string passed in will send all accepted encodings.
918    ///
919    /// By default this option is not set and corresponds to
920    /// `CURLOPT_ACCEPT_ENCODING`.
921    pub fn accept_encoding(mut self, encoding: &str) -> Result<Self, Error<C>> {
922        self.easy.accept_encoding(encoding).map_err(|err| {
923            log::trace!("{err}");
924            Error::Curl(err)
925        })?;
926        Ok(self)
927    }
928
929    /// Request the HTTP Transfer Encoding.
930    ///
931    /// By default this option is `false` and corresponds to
932    /// `CURLOPT_TRANSFER_ENCODING`.
933    pub fn transfer_encoding(mut self, enable: bool) -> Result<Self, Error<C>> {
934        self.easy.transfer_encoding(enable).map_err(|err| {
935            log::trace!("{err}");
936            Error::Curl(err)
937        })?;
938        Ok(self)
939    }
940
941    /// Follow HTTP 3xx redirects.
942    ///
943    /// Indicates whether any `Location` headers in the response should get
944    /// followed.
945    ///
946    /// By default this option is `false` and corresponds to
947    /// `CURLOPT_FOLLOWLOCATION`.
948    pub fn follow_location(mut self, enable: bool) -> Result<Self, Error<C>> {
949        self.easy.follow_location(enable).map_err(|err| {
950            log::trace!("{err}");
951            Error::Curl(err)
952        })?;
953        Ok(self)
954    }
955
956    /// Send credentials to hosts other than the first as well.
957    ///
958    /// Sends username/password credentials even when the host changes as part
959    /// of a redirect.
960    ///
961    /// By default this option is `false` and corresponds to
962    /// `CURLOPT_UNRESTRICTED_AUTH`.
963    pub fn unrestricted_auth(mut self, enable: bool) -> Result<Self, Error<C>> {
964        self.easy.unrestricted_auth(enable).map_err(|err| {
965            log::trace!("{err}");
966            Error::Curl(err)
967        })?;
968        Ok(self)
969    }
970
971    /// Set the maximum number of redirects allowed.
972    ///
973    /// A value of 0 will refuse any redirect.
974    ///
975    /// By default this option is `-1` (unlimited) and corresponds to
976    /// `CURLOPT_MAXREDIRS`.
977    pub fn max_redirections(mut self, max: u32) -> Result<Self, Error<C>> {
978        self.easy.max_redirections(max).map_err(|err| {
979            log::trace!("{err}");
980            Error::Curl(err)
981        })?;
982        Ok(self)
983    }
984
985    /// Make an HTTP PUT request.
986    ///
987    /// By default this option is `false` and corresponds to `CURLOPT_PUT`.
988    pub fn put(mut self, enable: bool) -> Result<Self, Error<C>> {
989        self.easy.put(enable).map_err(|err| {
990            log::trace!("{err}");
991            Error::Curl(err)
992        })?;
993        Ok(self)
994    }
995
996    /// Make an HTTP POST request.
997    ///
998    /// This will also make the library use the
999    /// `Content-Type: application/x-www-form-urlencoded` header.
1000    ///
1001    /// POST data can be specified through `post_fields` or by specifying a read
1002    /// function.
1003    ///
1004    /// By default this option is `false` and corresponds to `CURLOPT_POST`.
1005    pub fn post(mut self, enable: bool) -> Result<Self, Error<C>> {
1006        self.easy.post(enable).map_err(|err| {
1007            log::trace!("{err}");
1008            Error::Curl(err)
1009        })?;
1010        Ok(self)
1011    }
1012
1013    /// Configures the data that will be uploaded as part of a POST.
1014    ///
1015    /// Note that the data is copied into this handle and if that's not desired
1016    /// then the read callbacks can be used instead.
1017    ///
1018    /// By default this option is not set and corresponds to
1019    /// `CURLOPT_COPYPOSTFIELDS`.
1020    pub fn post_fields_copy(mut self, data: &[u8]) -> Result<Self, Error<C>> {
1021        self.easy.post_fields_copy(data).map_err(|err| {
1022            log::trace!("{err}");
1023            Error::Curl(err)
1024        })?;
1025        Ok(self)
1026    }
1027
1028    /// Configures the size of data that's going to be uploaded as part of a
1029    /// POST operation.
1030    ///
1031    /// This is called automatically as part of `post_fields` and should only
1032    /// be called if data is being provided in a read callback (and even then
1033    /// it's optional).
1034    ///
1035    /// By default this option is not set and corresponds to
1036    /// `CURLOPT_POSTFIELDSIZE_LARGE`.
1037    pub fn post_field_size(mut self, size: u64) -> Result<Self, Error<C>> {
1038        self.easy.post_field_size(size).map_err(|err| {
1039            log::trace!("{err}");
1040            Error::Curl(err)
1041        })?;
1042        Ok(self)
1043    }
1044
1045    /// Tells libcurl you want a multipart/formdata HTTP POST to be made and you
1046    /// instruct what data to pass on to the server in the `form` argument.
1047    ///
1048    /// By default this option is set to null and corresponds to
1049    /// `CURLOPT_HTTPPOST`.
1050    pub fn httppost(mut self, form: Form) -> Result<Self, Error<C>> {
1051        self.easy.httppost(form).map_err(|err| {
1052            log::trace!("{err}");
1053            Error::Curl(err)
1054        })?;
1055        Ok(self)
1056    }
1057
1058    /// Sets the HTTP referer header
1059    ///
1060    /// By default this option is not set and corresponds to `CURLOPT_REFERER`.
1061    pub fn referer(mut self, referer: &str) -> Result<Self, Error<C>> {
1062        self.easy.referer(referer).map_err(|err| {
1063            log::trace!("{err}");
1064            Error::Curl(err)
1065        })?;
1066        Ok(self)
1067    }
1068
1069    /// Sets the HTTP user-agent header
1070    ///
1071    /// By default this option is not set and corresponds to
1072    /// `CURLOPT_USERAGENT`.
1073    pub fn useragent(mut self, useragent: &str) -> Result<Self, Error<C>> {
1074        self.easy.useragent(useragent).map_err(|err| {
1075            log::trace!("{err}");
1076            Error::Curl(err)
1077        })?;
1078        Ok(self)
1079    }
1080
1081    /// Add some headers to this HTTP request.
1082    ///
1083    /// If you add a header that is otherwise used internally, the value here
1084    /// takes precedence. If a header is added with no content (like `Accept:`)
1085    /// the internally the header will get disabled. To add a header with no
1086    /// content, use the form `MyHeader;` (not the trailing semicolon).
1087    ///
1088    /// Headers must not be CRLF terminated. Many replaced headers have common
1089    /// shortcuts which should be prefered.
1090    ///
1091    /// By default this option is not set and corresponds to
1092    /// `CURLOPT_HTTPHEADER`
1093    pub fn http_headers(mut self, list: List) -> Result<Self, Error<C>> {
1094        self.easy.http_headers(list).map_err(|err| {
1095            log::trace!("{err}");
1096            Error::Curl(err)
1097        })?;
1098        Ok(self)
1099    }
1100
1101    // /// Add some headers to send to the HTTP proxy.
1102    // ///
1103    // /// This function is essentially the same as `http_headers`.
1104    // ///
1105    // /// By default this option is not set and corresponds to
1106    // /// `CURLOPT_PROXYHEADER`
1107    // pub fn proxy_headers(mut self, list: &'a List) -> Result<Self, Error<C>> {
1108    //     self.setopt_ptr(curl_sys::CURLOPT_PROXYHEADER, list.raw as *const _)
1109    // }
1110
1111    /// Set the contents of the HTTP Cookie header.
1112    ///
1113    /// Pass a string of the form `name=contents` for one cookie value or
1114    /// `name1=val1; name2=val2` for multiple values.
1115    ///
1116    /// Using this option multiple times will only make the latest string
1117    /// override the previous ones. This option will not enable the cookie
1118    /// engine, use `cookie_file` or `cookie_jar` to do that.
1119    ///
1120    /// By default this option is not set and corresponds to `CURLOPT_COOKIE`.
1121    pub fn cookie(mut self, cookie: &str) -> Result<Self, Error<C>> {
1122        self.easy.cookie(cookie).map_err(|err| {
1123            log::trace!("{err}");
1124            Error::Curl(err)
1125        })?;
1126        Ok(self)
1127    }
1128
1129    /// Set the file name to read cookies from.
1130    ///
1131    /// The cookie data can be in either the old Netscape / Mozilla cookie data
1132    /// format or just regular HTTP headers (Set-Cookie style) dumped to a file.
1133    ///
1134    /// This also enables the cookie engine, making libcurl parse and send
1135    /// cookies on subsequent requests with this handle.
1136    ///
1137    /// Given an empty or non-existing file or by passing the empty string ("")
1138    /// to this option, you can enable the cookie engine without reading any
1139    /// initial cookies.
1140    ///
1141    /// If you use this option multiple times, you just add more files to read.
1142    /// Subsequent files will add more cookies.
1143    ///
1144    /// By default this option is not set and corresponds to
1145    /// `CURLOPT_COOKIEFILE`.
1146    pub fn cookie_file<P: AsRef<Path>>(mut self, file: P) -> Result<Self, Error<C>> {
1147        self.easy.cookie_file(file).map_err(|err| {
1148            log::trace!("{err}");
1149            Error::Curl(err)
1150        })?;
1151        Ok(self)
1152    }
1153
1154    /// Set the file name to store cookies to.
1155    ///
1156    /// This will make libcurl write all internally known cookies to the file
1157    /// when this handle is dropped. If no cookies are known, no file will be
1158    /// created. Specify "-" as filename to instead have the cookies written to
1159    /// stdout. Using this option also enables cookies for this session, so if
1160    /// you for example follow a location it will make matching cookies get sent
1161    /// accordingly.
1162    ///
1163    /// Note that libcurl doesn't read any cookies from the cookie jar. If you
1164    /// want to read cookies from a file, use `cookie_file`.
1165    ///
1166    /// By default this option is not set and corresponds to
1167    /// `CURLOPT_COOKIEJAR`.
1168    pub fn cookie_jar<P: AsRef<Path>>(mut self, file: P) -> Result<Self, Error<C>> {
1169        self.easy.cookie_jar(file).map_err(|err| {
1170            log::trace!("{err}");
1171            Error::Curl(err)
1172        })?;
1173        Ok(self)
1174    }
1175
1176    /// Start a new cookie session
1177    ///
1178    /// Marks this as a new cookie "session". It will force libcurl to ignore
1179    /// all cookies it is about to load that are "session cookies" from the
1180    /// previous session. By default, libcurl always stores and loads all
1181    /// cookies, independent if they are session cookies or not. Session cookies
1182    /// are cookies without expiry date and they are meant to be alive and
1183    /// existing for this "session" only.
1184    ///
1185    /// By default this option is `false` and corresponds to
1186    /// `CURLOPT_COOKIESESSION`.
1187    pub fn cookie_session(mut self, session: bool) -> Result<Self, Error<C>> {
1188        self.easy.cookie_session(session).map_err(|err| {
1189            log::trace!("{err}");
1190            Error::Curl(err)
1191        })?;
1192        Ok(self)
1193    }
1194
1195    /// Add to or manipulate cookies held in memory.
1196    ///
1197    /// Such a cookie can be either a single line in Netscape / Mozilla format
1198    /// or just regular HTTP-style header (Set-Cookie: ...) format. This will
1199    /// also enable the cookie engine. This adds that single cookie to the
1200    /// internal cookie store.
1201    ///
1202    /// Exercise caution if you are using this option and multiple transfers may
1203    /// occur. If you use the Set-Cookie format and don't specify a domain then
1204    /// the cookie is sent for any domain (even after redirects are followed)
1205    /// and cannot be modified by a server-set cookie. If a server sets a cookie
1206    /// of the same name (or maybe you've imported one) then both will be sent
1207    /// on a future transfer to that server, likely not what you intended.
1208    /// address these issues set a domain in Set-Cookie or use the Netscape
1209    /// format.
1210    ///
1211    /// Additionally, there are commands available that perform actions if you
1212    /// pass in these exact strings:
1213    ///
1214    /// * "ALL" - erases all cookies held in memory
1215    /// * "SESS" - erases all session cookies held in memory
1216    /// * "FLUSH" - write all known cookies to the specified cookie jar
1217    /// * "RELOAD" - reread all cookies from the cookie file
1218    ///
1219    /// By default this options corresponds to `CURLOPT_COOKIELIST`
1220    pub fn cookie_list(mut self, cookie: &str) -> Result<Self, Error<C>> {
1221        self.easy.cookie_list(cookie).map_err(|err| {
1222            log::trace!("{err}");
1223            Error::Curl(err)
1224        })?;
1225        Ok(self)
1226    }
1227
1228    /// Ask for a HTTP GET request.
1229    ///
1230    /// By default this option is `false` and corresponds to `CURLOPT_HTTPGET`.
1231    pub fn get(mut self, enable: bool) -> Result<Self, Error<C>> {
1232        self.easy.get(enable).map_err(|err| {
1233            log::trace!("{err}");
1234            Error::Curl(err)
1235        })?;
1236        Ok(self)
1237    }
1238
1239    // /// Ask for a HTTP GET request.
1240    // ///
1241    // /// By default this option is `false` and corresponds to `CURLOPT_HTTPGET`.
1242    // pub fn http_version(mut self, vers: &str) -> Result<Self, Error<C>> {
1243    //     self.setopt_long(curl_sys::CURLOPT_HTTPGET, enable as c_long)
1244    // }
1245
1246    /// Ignore the content-length header.
1247    ///
1248    /// By default this option is `false` and corresponds to
1249    /// `CURLOPT_IGNORE_CONTENT_LENGTH`.
1250    pub fn ignore_content_length(mut self, ignore: bool) -> Result<Self, Error<C>> {
1251        self.easy.ignore_content_length(ignore).map_err(|err| {
1252            log::trace!("{err}");
1253            Error::Curl(err)
1254        })?;
1255        Ok(self)
1256    }
1257
1258    /// Enable or disable HTTP content decoding.
1259    ///
1260    /// By default this option is `true` and corresponds to
1261    /// `CURLOPT_HTTP_CONTENT_DECODING`.
1262    pub fn http_content_decoding(mut self, enable: bool) -> Result<Self, Error<C>> {
1263        self.easy.http_content_decoding(enable).map_err(|err| {
1264            log::trace!("{err}");
1265            Error::Curl(err)
1266        })?;
1267        Ok(self)
1268    }
1269
1270    /// Enable or disable HTTP transfer decoding.
1271    ///
1272    /// By default this option is `true` and corresponds to
1273    /// `CURLOPT_HTTP_TRANSFER_DECODING`.
1274    pub fn http_transfer_decoding(mut self, enable: bool) -> Result<Self, Error<C>> {
1275        self.easy.http_transfer_decoding(enable).map_err(|err| {
1276            log::trace!("{err}");
1277            Error::Curl(err)
1278        })?;
1279        Ok(self)
1280    }
1281
1282    // /// Timeout for the Expect: 100-continue response
1283    // ///
1284    // /// By default this option is 1s and corresponds to
1285    // /// `CURLOPT_EXPECT_100_TIMEOUT_MS`.
1286    // pub fn expect_100_timeout(mut self, enable: bool) -> Result<Self, Error<C>> {
1287    //     self.setopt_long(curl_sys::CURLOPT_HTTP_TRANSFER_DECODING,
1288    //                      enable as c_long)
1289    // }
1290
1291    // /// Wait for pipelining/multiplexing.
1292    // ///
1293    // /// Tells libcurl to prefer to wait for a connection to confirm or deny that
1294    // /// it can do pipelining or multiplexing before continuing.
1295    // ///
1296    // /// When about to perform a new transfer that allows pipelining or
1297    // /// multiplexing, libcurl will check for existing connections to re-use and
1298    // /// pipeline on. If no such connection exists it will immediately continue
1299    // /// and create a fresh new connection to use.
1300    // ///
1301    // /// By setting this option to `true` - having `pipeline` enabled for the
1302    // /// multi handle this transfer is associated with - libcurl will instead
1303    // /// wait for the connection to reveal if it is possible to
1304    // /// pipeline/multiplex on before it continues. This enables libcurl to much
1305    // /// better keep the number of connections to a minimum when using pipelining
1306    // /// or multiplexing protocols.
1307    // ///
1308    // /// The effect thus becomes that with this option set, libcurl prefers to
1309    // /// wait and re-use an existing connection for pipelining rather than the
1310    // /// opposite: prefer to open a new connection rather than waiting.
1311    // ///
1312    // /// The waiting time is as long as it takes for the connection to get up and
1313    // /// for libcurl to get the necessary response back that informs it about its
1314    // /// protocol and support level.
1315    // pub fn http_pipewait(mut self, enable: bool) -> Result<Self, Error<C>> {
1316    // }
1317
1318    // =========================================================================
1319    // Protocol Options
1320
1321    /// Indicates the range that this request should retrieve.
1322    ///
1323    /// The string provided should be of the form `N-M` where either `N` or `M`
1324    /// can be left out. For HTTP transfers multiple ranges separated by commas
1325    /// are also accepted.
1326    ///
1327    /// By default this option is not set and corresponds to `CURLOPT_RANGE`.
1328    pub fn range(mut self, range: &str) -> Result<Self, Error<C>> {
1329        self.easy.range(range).map_err(|err| {
1330            log::trace!("{err}");
1331            Error::Curl(err)
1332        })?;
1333        Ok(self)
1334    }
1335
1336    /// Set a point to resume transfer from
1337    ///
1338    /// Specify the offset in bytes you want the transfer to start from.
1339    ///
1340    /// By default this option is 0 and corresponds to
1341    /// `CURLOPT_RESUME_FROM_LARGE`.
1342    pub fn resume_from(mut self, from: u64) -> Result<Self, Error<C>> {
1343        self.easy.resume_from(from).map_err(|err| {
1344            log::trace!("{err}");
1345            Error::Curl(err)
1346        })?;
1347        Ok(self)
1348    }
1349
1350    /// Set a custom request string
1351    ///
1352    /// Specifies that a custom request will be made (e.g. a custom HTTP
1353    /// method). This does not change how libcurl performs internally, just
1354    /// changes the string sent to the server.
1355    ///
1356    /// By default this option is not set and corresponds to
1357    /// `CURLOPT_CUSTOMREQUEST`.
1358    pub fn custom_request(mut self, request: &str) -> Result<Self, Error<C>> {
1359        self.easy.custom_request(request).map_err(|err| {
1360            log::trace!("{err}");
1361            Error::Curl(err)
1362        })?;
1363        Ok(self)
1364    }
1365
1366    /// Get the modification time of the remote resource
1367    ///
1368    /// If true, libcurl will attempt to get the modification time of the
1369    /// remote document in this operation. This requires that the remote server
1370    /// sends the time or replies to a time querying command. The `filetime`
1371    /// function can be used after a transfer to extract the received time (if
1372    /// any).
1373    ///
1374    /// By default this option is `false` and corresponds to `CURLOPT_FILETIME`
1375    pub fn fetch_filetime(mut self, fetch: bool) -> Result<Self, Error<C>> {
1376        self.easy.fetch_filetime(fetch).map_err(|err| {
1377            log::trace!("{err}");
1378            Error::Curl(err)
1379        })?;
1380        Ok(self)
1381    }
1382
1383    /// Indicate whether to download the request without getting the body
1384    ///
1385    /// This is useful, for example, for doing a HEAD request.
1386    ///
1387    /// By default this option is `false` and corresponds to `CURLOPT_NOBODY`.
1388    pub fn nobody(mut self, enable: bool) -> Result<Self, Error<C>> {
1389        self.easy.nobody(enable).map_err(|err| {
1390            log::trace!("{err}");
1391            Error::Curl(err)
1392        })?;
1393        Ok(self)
1394    }
1395
1396    /// Set the size of the input file to send off.
1397    ///
1398    /// By default this option is not set and corresponds to
1399    /// `CURLOPT_INFILESIZE_LARGE`.
1400    pub fn in_filesize(mut self, size: u64) -> Result<Self, Error<C>> {
1401        self.easy.in_filesize(size).map_err(|err| {
1402            log::trace!("{err}");
1403            Error::Curl(err)
1404        })?;
1405        Ok(self)
1406    }
1407
1408    /// Enable or disable data upload.
1409    ///
1410    /// This means that a PUT request will be made for HTTP and probably wants
1411    /// to be combined with the read callback as well as the `in_filesize`
1412    /// method.
1413    ///
1414    /// By default this option is `false` and corresponds to `CURLOPT_UPLOAD`.
1415    pub fn upload(mut self, enable: bool) -> Result<Self, Error<C>> {
1416        self.easy.upload(enable).map_err(|err| {
1417            log::trace!("{err}");
1418            Error::Curl(err)
1419        })?;
1420        Ok(self)
1421    }
1422
1423    /// Configure the maximum file size to download.
1424    ///
1425    /// By default this option is not set and corresponds to
1426    /// `CURLOPT_MAXFILESIZE_LARGE`.
1427    pub fn max_filesize(mut self, size: u64) -> Result<Self, Error<C>> {
1428        self.easy.max_filesize(size).map_err(|err| {
1429            log::trace!("{err}");
1430            Error::Curl(err)
1431        })?;
1432        Ok(self)
1433    }
1434
1435    /// Selects a condition for a time request.
1436    ///
1437    /// This value indicates how the `time_value` option is interpreted.
1438    ///
1439    /// By default this option is not set and corresponds to
1440    /// `CURLOPT_TIMECONDITION`.
1441    pub fn time_condition(mut self, cond: TimeCondition) -> Result<Self, Error<C>> {
1442        self.easy.time_condition(cond).map_err(|err| {
1443            log::trace!("{err}");
1444            Error::Curl(err)
1445        })?;
1446        Ok(self)
1447    }
1448
1449    /// Sets the time value for a conditional request.
1450    ///
1451    /// The value here should be the number of seconds elapsed since January 1,
1452    /// 1970. To pass how to interpret this value, use `time_condition`.
1453    ///
1454    /// By default this option is not set and corresponds to
1455    /// `CURLOPT_TIMEVALUE`.
1456    pub fn time_value(mut self, val: i64) -> Result<Self, Error<C>> {
1457        self.easy.time_value(val).map_err(|err| {
1458            log::trace!("{err}");
1459            Error::Curl(err)
1460        })?;
1461        Ok(self)
1462    }
1463
1464    // =========================================================================
1465    // Connection Options
1466
1467    /// Set maximum time the request is allowed to take.
1468    ///
1469    /// Normally, name lookups can take a considerable time and limiting
1470    /// operations to less than a few minutes risk aborting perfectly normal
1471    /// operations.
1472    ///
1473    /// If libcurl is built to use the standard system name resolver, that
1474    /// portion of the transfer will still use full-second resolution for
1475    /// timeouts with a minimum timeout allowed of one second.
1476    ///
1477    /// In unix-like systems, this might cause signals to be used unless
1478    /// `nosignal` is set.
1479    ///
1480    /// Since this puts a hard limit for how long a request is allowed to
1481    /// take, it has limited use in dynamic use cases with varying transfer
1482    /// times. You are then advised to explore `low_speed_limit`,
1483    /// `low_speed_time` or using `progress_function` to implement your own
1484    /// timeout logic.
1485    ///
1486    /// By default this option is not set and corresponds to
1487    /// `CURLOPT_TIMEOUT_MS`.
1488    pub fn timeout(mut self, timeout: Duration) -> Result<Self, Error<C>> {
1489        self.easy.timeout(timeout).map_err(|err| {
1490            log::trace!("{err}");
1491            Error::Curl(err)
1492        })?;
1493        Ok(self)
1494    }
1495
1496    /// Set the low speed limit in bytes per second.
1497    ///
1498    /// This specifies the average transfer speed in bytes per second that the
1499    /// transfer should be below during `low_speed_time` for libcurl to consider
1500    /// it to be too slow and abort.
1501    ///
1502    /// By default this option is not set and corresponds to
1503    /// `CURLOPT_LOW_SPEED_LIMIT`.
1504    pub fn low_speed_limit(mut self, limit: u32) -> Result<Self, Error<C>> {
1505        self.easy.low_speed_limit(limit).map_err(|err| {
1506            log::trace!("{err}");
1507            Error::Curl(err)
1508        })?;
1509        Ok(self)
1510    }
1511
1512    /// Set the low speed time period.
1513    ///
1514    /// Specifies the window of time for which if the transfer rate is below
1515    /// `low_speed_limit` the request will be aborted.
1516    ///
1517    /// By default this option is not set and corresponds to
1518    /// `CURLOPT_LOW_SPEED_TIME`.
1519    pub fn low_speed_time(mut self, dur: Duration) -> Result<Self, Error<C>> {
1520        self.easy.low_speed_time(dur).map_err(|err| {
1521            log::trace!("{err}");
1522            Error::Curl(err)
1523        })?;
1524        Ok(self)
1525    }
1526
1527    /// Rate limit data upload speed
1528    ///
1529    /// If an upload exceeds this speed (counted in bytes per second) on
1530    /// cumulative average during the transfer, the transfer will pause to keep
1531    /// the average rate less than or equal to the parameter value.
1532    ///
1533    /// By default this option is not set (unlimited speed) and corresponds to
1534    /// `CURLOPT_MAX_SEND_SPEED_LARGE`.
1535    pub fn max_send_speed(mut self, speed: u64) -> Result<Self, Error<C>> {
1536        self.easy.max_send_speed(speed).map_err(|err| {
1537            log::trace!("{err}");
1538            Error::Curl(err)
1539        })?;
1540        Ok(self)
1541    }
1542
1543    /// Rate limit data download speed
1544    ///
1545    /// If a download exceeds this speed (counted in bytes per second) on
1546    /// cumulative average during the transfer, the transfer will pause to keep
1547    /// the average rate less than or equal to the parameter value.
1548    ///
1549    /// By default this option is not set (unlimited speed) and corresponds to
1550    /// `CURLOPT_MAX_RECV_SPEED_LARGE`.
1551    pub fn max_recv_speed(mut self, speed: u64) -> Result<Self, Error<C>> {
1552        self.easy.max_recv_speed(speed).map_err(|err| {
1553            log::trace!("{err}");
1554            Error::Curl(err)
1555        })?;
1556        Ok(self)
1557    }
1558
1559    /// Set the maximum connection cache size.
1560    ///
1561    /// The set amount will be the maximum number of simultaneously open
1562    /// persistent connections that libcurl may cache in the pool associated
1563    /// with this handle. The default is 5, and there isn't much point in
1564    /// changing this value unless you are perfectly aware of how this works and
1565    /// changes libcurl's behaviour. This concerns connections using any of the
1566    /// protocols that support persistent connections.
1567    ///
1568    /// When reaching the maximum limit, curl closes the oldest one in the cache
1569    /// to prevent increasing the number of open connections.
1570    ///
1571    /// By default this option is set to 5 and corresponds to
1572    /// `CURLOPT_MAXCONNECTS`
1573    pub fn max_connects(mut self, max: u32) -> Result<Self, Error<C>> {
1574        self.easy.max_connects(max).map_err(|err| {
1575            log::trace!("{err}");
1576            Error::Curl(err)
1577        })?;
1578        Ok(self)
1579    }
1580
1581    /// Set the maximum idle time allowed for a connection.
1582    ///
1583    /// This configuration sets the maximum time that a connection inside of the connection cache
1584    /// can be reused. Any connection older than this value will be considered stale and will
1585    /// be closed.
1586    ///
1587    /// By default, a value of 118 seconds is used.
1588    pub fn maxage_conn(mut self, max_age: Duration) -> Result<Self, Error<C>> {
1589        self.easy.maxage_conn(max_age).map_err(|err| {
1590            log::trace!("{err}");
1591            Error::Curl(err)
1592        })?;
1593        Ok(self)
1594    }
1595
1596    /// Force a new connection to be used.
1597    ///
1598    /// Makes the next transfer use a new (fresh) connection by force instead of
1599    /// trying to re-use an existing one. This option should be used with
1600    /// caution and only if you understand what it does as it may seriously
1601    /// impact performance.
1602    ///
1603    /// By default this option is `false` and corresponds to
1604    /// `CURLOPT_FRESH_CONNECT`.
1605    pub fn fresh_connect(mut self, enable: bool) -> Result<Self, Error<C>> {
1606        self.easy.fresh_connect(enable).map_err(|err| {
1607            log::trace!("{err}");
1608            Error::Curl(err)
1609        })?;
1610        Ok(self)
1611    }
1612
1613    /// Make connection get closed at once after use.
1614    ///
1615    /// Makes libcurl explicitly close the connection when done with the
1616    /// transfer. Normally, libcurl keeps all connections alive when done with
1617    /// one transfer in case a succeeding one follows that can re-use them.
1618    /// This option should be used with caution and only if you understand what
1619    /// it does as it can seriously impact performance.
1620    ///
1621    /// By default this option is `false` and corresponds to
1622    /// `CURLOPT_FORBID_REUSE`.
1623    pub fn forbid_reuse(mut self, enable: bool) -> Result<Self, Error<C>> {
1624        self.easy.forbid_reuse(enable).map_err(|err| {
1625            log::trace!("{err}");
1626            Error::Curl(err)
1627        })?;
1628        Ok(self)
1629    }
1630
1631    /// Timeout for the connect phase
1632    ///
1633    /// This is the maximum time that you allow the connection phase to the
1634    /// server to take. This only limits the connection phase, it has no impact
1635    /// once it has connected.
1636    ///
1637    /// By default this value is 300 seconds and corresponds to
1638    /// `CURLOPT_CONNECTTIMEOUT_MS`.
1639    pub fn connect_timeout(mut self, timeout: Duration) -> Result<Self, Error<C>> {
1640        self.easy.connect_timeout(timeout).map_err(|err| {
1641            log::trace!("{err}");
1642            Error::Curl(err)
1643        })?;
1644        Ok(self)
1645    }
1646
1647    /// Specify which IP protocol version to use
1648    ///
1649    /// Allows an application to select what kind of IP addresses to use when
1650    /// resolving host names. This is only interesting when using host names
1651    /// that resolve addresses using more than one version of IP.
1652    ///
1653    /// By default this value is "any" and corresponds to `CURLOPT_IPRESOLVE`.
1654    pub fn ip_resolve(mut self, resolve: IpResolve) -> Result<Self, Error<C>> {
1655        self.easy.ip_resolve(resolve).map_err(|err| {
1656            log::trace!("{err}");
1657            Error::Curl(err)
1658        })?;
1659        Ok(self)
1660    }
1661
1662    /// Specify custom host name to IP address resolves.
1663    ///
1664    /// Allows specifying hostname to IP mappins to use before trying the
1665    /// system resolver.
1666    pub fn resolve(mut self, list: List) -> Result<Self, Error<C>> {
1667        self.easy.resolve(list).map_err(|err| {
1668            log::trace!("{err}");
1669            Error::Curl(err)
1670        })?;
1671        Ok(self)
1672    }
1673
1674    /// Configure whether to stop when connected to target server
1675    ///
1676    /// When enabled it tells the library to perform all the required proxy
1677    /// authentication and connection setup, but no data transfer, and then
1678    /// return.
1679    ///
1680    /// The option can be used to simply test a connection to a server.
1681    ///
1682    /// By default this value is `false` and corresponds to
1683    /// `CURLOPT_CONNECT_ONLY`.
1684    pub fn connect_only(mut self, enable: bool) -> Result<Self, Error<C>> {
1685        self.easy.connect_only(enable).map_err(|err| {
1686            log::trace!("{err}");
1687            Error::Curl(err)
1688        })?;
1689        Ok(self)
1690    }
1691
1692    // =========================================================================
1693    // SSL/Security Options
1694
1695    /// Sets the SSL client certificate.
1696    ///
1697    /// The string should be the file name of your client certificate. The
1698    /// default format is "P12" on Secure Transport and "PEM" on other engines,
1699    /// and can be changed with `ssl_cert_type`.
1700    ///
1701    /// With NSS or Secure Transport, this can also be the nickname of the
1702    /// certificate you wish to authenticate with as it is named in the security
1703    /// database. If you want to use a file from the current directory, please
1704    /// precede it with "./" prefix, in order to avoid confusion with a
1705    /// nickname.
1706    ///
1707    /// When using a client certificate, you most likely also need to provide a
1708    /// private key with `ssl_key`.
1709    ///
1710    /// By default this option is not set and corresponds to `CURLOPT_SSLCERT`.
1711    pub fn ssl_cert<P: AsRef<Path>>(mut self, cert: P) -> Result<Self, Error<C>> {
1712        self.easy.ssl_cert(cert).map_err(|err| {
1713            log::trace!("{err}");
1714            Error::Curl(err)
1715        })?;
1716        Ok(self)
1717    }
1718
1719    /// Set the SSL client certificate using an in-memory blob.
1720    ///
1721    /// The specified byte buffer should contain the binary content of your
1722    /// client certificate, which will be copied into the handle. The format of
1723    /// the certificate can be specified with `ssl_cert_type`.
1724    ///
1725    /// By default this option is not set and corresponds to
1726    /// `CURLOPT_SSLCERT_BLOB`.
1727    pub fn ssl_cert_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
1728        self.easy.ssl_cert_blob(blob).map_err(|err| {
1729            log::trace!("{err}");
1730            Error::Curl(err)
1731        })?;
1732        Ok(self)
1733    }
1734
1735    /// Specify type of the client SSL certificate.
1736    ///
1737    /// The string should be the format of your certificate. Supported formats
1738    /// are "PEM" and "DER", except with Secure Transport. OpenSSL (versions
1739    /// 0.9.3 and later) and Secure Transport (on iOS 5 or later, or OS X 10.7
1740    /// or later) also support "P12" for PKCS#12-encoded files.
1741    ///
1742    /// By default this option is "PEM" and corresponds to
1743    /// `CURLOPT_SSLCERTTYPE`.
1744    pub fn ssl_cert_type(mut self, kind: &str) -> Result<Self, Error<C>> {
1745        self.easy.ssl_cert_type(kind).map_err(|err| {
1746            log::trace!("{err}");
1747            Error::Curl(err)
1748        })?;
1749        Ok(self)
1750    }
1751
1752    /// Specify private keyfile for TLS and SSL client cert.
1753    ///
1754    /// The string should be the file name of your private key. The default
1755    /// format is "PEM" and can be changed with `ssl_key_type`.
1756    ///
1757    /// (iOS and Mac OS X only) This option is ignored if curl was built against
1758    /// Secure Transport. Secure Transport expects the private key to be already
1759    /// present in the keychain or PKCS#12 file containing the certificate.
1760    ///
1761    /// By default this option is not set and corresponds to `CURLOPT_SSLKEY`.
1762    pub fn ssl_key<P: AsRef<Path>>(mut self, key: P) -> Result<Self, Error<C>> {
1763        self.easy.ssl_key(key).map_err(|err| {
1764            log::trace!("{err}");
1765            Error::Curl(err)
1766        })?;
1767        Ok(self)
1768    }
1769
1770    /// Specify an SSL private key using an in-memory blob.
1771    ///
1772    /// The specified byte buffer should contain the binary content of your
1773    /// private key, which will be copied into the handle. The format of
1774    /// the private key can be specified with `ssl_key_type`.
1775    ///
1776    /// By default this option is not set and corresponds to
1777    /// `CURLOPT_SSLKEY_BLOB`.
1778    pub fn ssl_key_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
1779        self.easy.ssl_key_blob(blob).map_err(|err| {
1780            log::trace!("{err}");
1781            Error::Curl(err)
1782        })?;
1783        Ok(self)
1784    }
1785
1786    /// Set type of the private key file.
1787    ///
1788    /// The string should be the format of your private key. Supported formats
1789    /// are "PEM", "DER" and "ENG".
1790    ///
1791    /// The format "ENG" enables you to load the private key from a crypto
1792    /// engine. In this case `ssl_key` is used as an identifier passed to
1793    /// the engine. You have to set the crypto engine with `ssl_engine`.
1794    /// "DER" format key file currently does not work because of a bug in
1795    /// OpenSSL.
1796    ///
1797    /// By default this option is "PEM" and corresponds to
1798    /// `CURLOPT_SSLKEYTYPE`.
1799    pub fn ssl_key_type(mut self, kind: &str) -> Result<Self, Error<C>> {
1800        self.easy.ssl_key_type(kind).map_err(|err| {
1801            log::trace!("{err}");
1802            Error::Curl(err)
1803        })?;
1804        Ok(self)
1805    }
1806
1807    /// Set passphrase to private key.
1808    ///
1809    /// This will be used as the password required to use the `ssl_key`.
1810    /// You never needed a pass phrase to load a certificate but you need one to
1811    /// load your private key.
1812    ///
1813    /// By default this option is not set and corresponds to
1814    /// `CURLOPT_KEYPASSWD`.
1815    pub fn key_password(mut self, password: &str) -> Result<Self, Error<C>> {
1816        self.easy.key_password(password).map_err(|err| {
1817            log::trace!("{err}");
1818            Error::Curl(err)
1819        })?;
1820        Ok(self)
1821    }
1822
1823    /// Set the SSL Certificate Authorities using an in-memory blob.
1824    ///
1825    /// The specified byte buffer should contain the binary content of one
1826    /// or more PEM-encoded CA certificates, which will be copied into
1827    /// the handle.
1828    ///
1829    /// By default this option is not set and corresponds to
1830    /// `CURLOPT_CAINFO_BLOB`.
1831    pub fn ssl_cainfo_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
1832        self.easy.ssl_cainfo_blob(blob).map_err(|err| {
1833            log::trace!("{err}");
1834            Error::Curl(err)
1835        })?;
1836        Ok(self)
1837    }
1838
1839    /// Set the SSL Certificate Authorities for HTTPS proxies using an in-memory
1840    /// blob.
1841    ///
1842    /// The specified byte buffer should contain the binary content of one
1843    /// or more PEM-encoded CA certificates, which will be copied into
1844    /// the handle.
1845    ///
1846    /// By default this option is not set and corresponds to
1847    /// `CURLOPT_PROXY_CAINFO_BLOB`.
1848    pub fn proxy_ssl_cainfo_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
1849        self.easy.proxy_ssl_cainfo_blob(blob).map_err(|err| {
1850            log::trace!("{err}");
1851            Error::Curl(err)
1852        })?;
1853        Ok(self)
1854    }
1855
1856    /// Set the SSL engine identifier.
1857    ///
1858    /// This will be used as the identifier for the crypto engine you want to
1859    /// use for your private key.
1860    ///
1861    /// By default this option is not set and corresponds to
1862    /// `CURLOPT_SSLENGINE`.
1863    pub fn ssl_engine(mut self, engine: &str) -> Result<Self, Error<C>> {
1864        self.easy.ssl_engine(engine).map_err(|err| {
1865            log::trace!("{err}");
1866            Error::Curl(err)
1867        })?;
1868        Ok(self)
1869    }
1870
1871    /// Make this handle's SSL engine the default.
1872    ///
1873    /// By default this option is not set and corresponds to
1874    /// `CURLOPT_SSLENGINE_DEFAULT`.
1875    pub fn ssl_engine_default(mut self, enable: bool) -> Result<Self, Error<C>> {
1876        self.easy.ssl_engine_default(enable).map_err(|err| {
1877            log::trace!("{err}");
1878            Error::Curl(err)
1879        })?;
1880        Ok(self)
1881    }
1882
1883    // /// Enable TLS false start.
1884    // ///
1885    // /// This option determines whether libcurl should use false start during the
1886    // /// TLS handshake. False start is a mode where a TLS client will start
1887    // /// sending application data before verifying the server's Finished message,
1888    // /// thus saving a round trip when performing a full handshake.
1889    // ///
1890    // /// By default this option is not set and corresponds to
1891    // /// `CURLOPT_SSL_FALSESTARTE`.
1892    // pub fn ssl_false_start(mut self, enable: bool) -> Result<Self, Error<C>> {
1893    //     self.setopt_long(curl_sys::CURLOPT_SSLENGINE_DEFAULT, enable as c_long)
1894    // }
1895
1896    /// Set preferred HTTP version.
1897    ///
1898    /// By default this option is not set and corresponds to
1899    /// `CURLOPT_HTTP_VERSION`.
1900    pub fn http_version(mut self, version: HttpVersion) -> Result<Self, Error<C>> {
1901        self.easy.http_version(version).map_err(|err| {
1902            log::trace!("{err}");
1903            Error::Curl(err)
1904        })?;
1905        Ok(self)
1906    }
1907
1908    /// Set preferred TLS/SSL version.
1909    ///
1910    /// By default this option is not set and corresponds to
1911    /// `CURLOPT_SSLVERSION`.
1912    pub fn ssl_version(mut self, version: SslVersion) -> Result<Self, Error<C>> {
1913        self.easy.ssl_version(version).map_err(|err| {
1914            log::trace!("{err}");
1915            Error::Curl(err)
1916        })?;
1917        Ok(self)
1918    }
1919
1920    /// Set preferred TLS/SSL version when connecting to an HTTPS proxy.
1921    ///
1922    /// By default this option is not set and corresponds to
1923    /// `CURLOPT_PROXY_SSLVERSION`.
1924    pub fn proxy_ssl_version(mut self, version: SslVersion) -> Result<Self, Error<C>> {
1925        self.easy.proxy_ssl_version(version).map_err(|err| {
1926            log::trace!("{err}");
1927            Error::Curl(err)
1928        })?;
1929        Ok(self)
1930    }
1931
1932    /// Set preferred TLS/SSL version with minimum version and maximum version.
1933    ///
1934    /// By default this option is not set and corresponds to
1935    /// `CURLOPT_SSLVERSION`.
1936    pub fn ssl_min_max_version(
1937        mut self,
1938        min_version: SslVersion,
1939        max_version: SslVersion,
1940    ) -> Result<Self, Error<C>> {
1941        self.easy
1942            .ssl_min_max_version(min_version, max_version)
1943            .map_err(|err| {
1944                log::trace!("{err}");
1945                Error::Curl(err)
1946            })?;
1947        Ok(self)
1948    }
1949
1950    /// Set preferred TLS/SSL version with minimum version and maximum version
1951    /// when connecting to an HTTPS proxy.
1952    ///
1953    /// By default this option is not set and corresponds to
1954    /// `CURLOPT_PROXY_SSLVERSION`.
1955    pub fn proxy_ssl_min_max_version(
1956        mut self,
1957        min_version: SslVersion,
1958        max_version: SslVersion,
1959    ) -> Result<Self, Error<C>> {
1960        self.easy
1961            .proxy_ssl_min_max_version(min_version, max_version)
1962            .map_err(|err| {
1963                log::trace!("{err}");
1964                Error::Curl(err)
1965            })?;
1966        Ok(self)
1967    }
1968
1969    /// Verify the certificate's name against host.
1970    ///
1971    /// This should be disabled with great caution! It basically disables the
1972    /// security features of SSL if it is disabled.
1973    ///
1974    /// By default this option is set to `true` and corresponds to
1975    /// `CURLOPT_SSL_VERIFYHOST`.
1976    pub fn ssl_verify_host(mut self, verify: bool) -> Result<Self, Error<C>> {
1977        self.easy.ssl_verify_host(verify).map_err(|err| {
1978            log::trace!("{err}");
1979            Error::Curl(err)
1980        })?;
1981        Ok(self)
1982    }
1983
1984    /// Verify the certificate's name against host for HTTPS proxy.
1985    ///
1986    /// This should be disabled with great caution! It basically disables the
1987    /// security features of SSL if it is disabled.
1988    ///
1989    /// By default this option is set to `true` and corresponds to
1990    /// `CURLOPT_PROXY_SSL_VERIFYHOST`.
1991    pub fn proxy_ssl_verify_host(mut self, verify: bool) -> Result<Self, Error<C>> {
1992        self.easy.proxy_ssl_verify_host(verify).map_err(|err| {
1993            log::trace!("{err}");
1994            Error::Curl(err)
1995        })?;
1996        Ok(self)
1997    }
1998
1999    /// Verify the peer's SSL certificate.
2000    ///
2001    /// This should be disabled with great caution! It basically disables the
2002    /// security features of SSL if it is disabled.
2003    ///
2004    /// By default this option is set to `true` and corresponds to
2005    /// `CURLOPT_SSL_VERIFYPEER`.
2006    pub fn ssl_verify_peer(mut self, verify: bool) -> Result<Self, Error<C>> {
2007        self.easy.ssl_verify_peer(verify).map_err(|err| {
2008            log::trace!("{err}");
2009            Error::Curl(err)
2010        })?;
2011        Ok(self)
2012    }
2013
2014    /// Verify the peer's SSL certificate for HTTPS proxy.
2015    ///
2016    /// This should be disabled with great caution! It basically disables the
2017    /// security features of SSL if it is disabled.
2018    ///
2019    /// By default this option is set to `true` and corresponds to
2020    /// `CURLOPT_PROXY_SSL_VERIFYPEER`.
2021    pub fn proxy_ssl_verify_peer(mut self, verify: bool) -> Result<Self, Error<C>> {
2022        self.easy.proxy_ssl_verify_peer(verify).map_err(|err| {
2023            log::trace!("{err}");
2024            Error::Curl(err)
2025        })?;
2026        Ok(self)
2027    }
2028
2029    // /// Verify the certificate's status.
2030    // ///
2031    // /// This option determines whether libcurl verifies the status of the server
2032    // /// cert using the "Certificate Status Request" TLS extension (aka. OCSP
2033    // /// stapling).
2034    // ///
2035    // /// By default this option is set to `false` and corresponds to
2036    // /// `CURLOPT_SSL_VERIFYSTATUS`.
2037    // pub fn ssl_verify_status(mut self, verify: bool) -> Result<Self, Error<C>> {
2038    //     self.setopt_long(curl_sys::CURLOPT_SSL_VERIFYSTATUS, verify as c_long)
2039    // }
2040
2041    /// Specify the path to Certificate Authority (CA) bundle
2042    ///
2043    /// The file referenced should hold one or more certificates to verify the
2044    /// peer with.
2045    ///
2046    /// This option is by default set to the system path where libcurl's cacert
2047    /// bundle is assumed to be stored, as established at build time.
2048    ///
2049    /// If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module
2050    /// (libnsspem.so) needs to be available for this option to work properly.
2051    ///
2052    /// By default this option is the system defaults, and corresponds to
2053    /// `CURLOPT_CAINFO`.
2054    pub fn cainfo<P: AsRef<Path>>(mut self, path: P) -> Result<Self, Error<C>> {
2055        self.easy.cainfo(path).map_err(|err| {
2056            log::trace!("{err}");
2057            Error::Curl(err)
2058        })?;
2059        Ok(self)
2060    }
2061
2062    /// Set the issuer SSL certificate filename
2063    ///
2064    /// Specifies a file holding a CA certificate in PEM format. If the option
2065    /// is set, an additional check against the peer certificate is performed to
2066    /// verify the issuer is indeed the one associated with the certificate
2067    /// provided by the option. This additional check is useful in multi-level
2068    /// PKI where one needs to enforce that the peer certificate is from a
2069    /// specific branch of the tree.
2070    ///
2071    /// This option makes sense only when used in combination with the
2072    /// [`Easy2::ssl_verify_peer`] option. Otherwise, the result of the check is
2073    /// not considered as failure.
2074    ///
2075    /// By default this option is not set and corresponds to
2076    /// `CURLOPT_ISSUERCERT`.
2077    pub fn issuer_cert<P: AsRef<Path>>(mut self, path: P) -> Result<Self, Error<C>> {
2078        self.easy.issuer_cert(path).map_err(|err| {
2079            log::trace!("{err}");
2080            Error::Curl(err)
2081        })?;
2082        Ok(self)
2083    }
2084
2085    /// Set the issuer SSL certificate filename for HTTPS proxies
2086    ///
2087    /// Specifies a file holding a CA certificate in PEM format. If the option
2088    /// is set, an additional check against the peer certificate is performed to
2089    /// verify the issuer is indeed the one associated with the certificate
2090    /// provided by the option. This additional check is useful in multi-level
2091    /// PKI where one needs to enforce that the peer certificate is from a
2092    /// specific branch of the tree.
2093    ///
2094    /// This option makes sense only when used in combination with the
2095    /// [`Easy2::proxy_ssl_verify_peer`] option. Otherwise, the result of the
2096    /// check is not considered as failure.
2097    ///
2098    /// By default this option is not set and corresponds to
2099    /// `CURLOPT_PROXY_ISSUERCERT`.
2100    pub fn proxy_issuer_cert<P: AsRef<Path>>(mut self, path: P) -> Result<Self, Error<C>> {
2101        self.easy.proxy_issuer_cert(path).map_err(|err| {
2102            log::trace!("{err}");
2103            Error::Curl(err)
2104        })?;
2105        Ok(self)
2106    }
2107
2108    /// Set the issuer SSL certificate using an in-memory blob.
2109    ///
2110    /// The specified byte buffer should contain the binary content of a CA
2111    /// certificate in the PEM format. The certificate will be copied into the
2112    /// handle.
2113    ///
2114    /// By default this option is not set and corresponds to
2115    /// `CURLOPT_ISSUERCERT_BLOB`.
2116    pub fn issuer_cert_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
2117        self.easy.issuer_cert_blob(blob).map_err(|err| {
2118            log::trace!("{err}");
2119            Error::Curl(err)
2120        })?;
2121        Ok(self)
2122    }
2123
2124    /// Set the issuer SSL certificate for HTTPS proxies using an in-memory blob.
2125    ///
2126    /// The specified byte buffer should contain the binary content of a CA
2127    /// certificate in the PEM format. The certificate will be copied into the
2128    /// handle.
2129    ///
2130    /// By default this option is not set and corresponds to
2131    /// `CURLOPT_PROXY_ISSUERCERT_BLOB`.
2132    pub fn proxy_issuer_cert_blob(mut self, blob: &[u8]) -> Result<Self, Error<C>> {
2133        self.easy.proxy_issuer_cert_blob(blob).map_err(|err| {
2134            log::trace!("{err}");
2135            Error::Curl(err)
2136        })?;
2137        Ok(self)
2138    }
2139
2140    /// Specify directory holding CA certificates
2141    ///
2142    /// Names a directory holding multiple CA certificates to verify the peer
2143    /// with. If libcurl is built against OpenSSL, the certificate directory
2144    /// must be prepared using the openssl c_rehash utility. This makes sense
2145    /// only when used in combination with the `ssl_verify_peer` option.
2146    ///
2147    /// By default this option is not set and corresponds to `CURLOPT_CAPATH`.
2148    pub fn capath<P: AsRef<Path>>(mut self, path: P) -> Result<Self, Error<C>> {
2149        self.easy.capath(path).map_err(|err| {
2150            log::trace!("{err}");
2151            Error::Curl(err)
2152        })?;
2153        Ok(self)
2154    }
2155
2156    /// Specify a Certificate Revocation List file
2157    ///
2158    /// Names a file with the concatenation of CRL (in PEM format) to use in the
2159    /// certificate validation that occurs during the SSL exchange.
2160    ///
2161    /// When curl is built to use NSS or GnuTLS, there is no way to influence
2162    /// the use of CRL passed to help in the verification process. When libcurl
2163    /// is built with OpenSSL support, X509_V_FLAG_CRL_CHECK and
2164    /// X509_V_FLAG_CRL_CHECK_ALL are both set, requiring CRL check against all
2165    /// the elements of the certificate chain if a CRL file is passed.
2166    ///
2167    /// This option makes sense only when used in combination with the
2168    /// [`Easy2::ssl_verify_peer`] option.
2169    ///
2170    /// A specific error code (`is_ssl_crl_badfile`) is defined with the
2171    /// option. It is returned when the SSL exchange fails because the CRL file
2172    /// cannot be loaded. A failure in certificate verification due to a
2173    /// revocation information found in the CRL does not trigger this specific
2174    /// error.
2175    ///
2176    /// By default this option is not set and corresponds to `CURLOPT_CRLFILE`.
2177    pub fn crlfile<P: AsRef<Path>>(mut self, path: P) -> Result<Self, Error<C>> {
2178        self.easy.crlfile(path).map_err(|err| {
2179            log::trace!("{err}");
2180            Error::Curl(err)
2181        })?;
2182        Ok(self)
2183    }
2184
2185    /// Specify a Certificate Revocation List file to use when connecting to an
2186    /// HTTPS proxy.
2187    ///
2188    /// Names a file with the concatenation of CRL (in PEM format) to use in the
2189    /// certificate validation that occurs during the SSL exchange.
2190    ///
2191    /// When curl is built to use NSS or GnuTLS, there is no way to influence
2192    /// the use of CRL passed to help in the verification process. When libcurl
2193    /// is built with OpenSSL support, X509_V_FLAG_CRL_CHECK and
2194    /// X509_V_FLAG_CRL_CHECK_ALL are both set, requiring CRL check against all
2195    /// the elements of the certificate chain if a CRL file is passed.
2196    ///
2197    /// This option makes sense only when used in combination with the
2198    /// [`Easy2::proxy_ssl_verify_peer`] option.
2199    ///
2200    /// By default this option is not set and corresponds to
2201    /// `CURLOPT_PROXY_CRLFILE`.
2202    pub fn proxy_crlfile<P: AsRef<Path>>(mut self, path: P) -> Result<Self, Error<C>> {
2203        self.easy.proxy_crlfile(path).map_err(|err| {
2204            log::trace!("{err}");
2205            Error::Curl(err)
2206        })?;
2207        Ok(self)
2208    }
2209
2210    /// Request SSL certificate information
2211    ///
2212    /// Enable libcurl's certificate chain info gatherer. With this enabled,
2213    /// libcurl will extract lots of information and data about the certificates
2214    /// in the certificate chain used in the SSL connection.
2215    ///
2216    /// By default this option is `false` and corresponds to
2217    /// `CURLOPT_CERTINFO`.
2218    pub fn certinfo(mut self, enable: bool) -> Result<Self, Error<C>> {
2219        self.easy.certinfo(enable).map_err(|err| {
2220            log::trace!("{err}");
2221            Error::Curl(err)
2222        })?;
2223        Ok(self)
2224    }
2225
2226    /// Set pinned public key.
2227    ///
2228    /// Pass a pointer to a zero terminated string as parameter. The string can
2229    /// be the file name of your pinned public key. The file format expected is
2230    /// "PEM" or "DER". The string can also be any number of base64 encoded
2231    /// sha256 hashes preceded by "sha256//" and separated by ";"
2232    ///
2233    /// When negotiating a TLS or SSL connection, the server sends a certificate
2234    /// indicating its identity. A public key is extracted from this certificate
2235    /// and if it does not exactly match the public key provided to this option,
2236    /// curl will abort the connection before sending or receiving any data.
2237    ///
2238    /// By default this option is not set and corresponds to
2239    /// `CURLOPT_PINNEDPUBLICKEY`.
2240    pub fn pinned_public_key(mut self, pubkey: &str) -> Result<Self, Error<C>> {
2241        self.easy.pinned_public_key(pubkey).map_err(|err| {
2242            log::trace!("{err}");
2243            Error::Curl(err)
2244        })?;
2245        Ok(self)
2246    }
2247
2248    /// Specify a source for random data
2249    ///
2250    /// The file will be used to read from to seed the random engine for SSL and
2251    /// more.
2252    ///
2253    /// By default this option is not set and corresponds to
2254    /// `CURLOPT_RANDOM_FILE`.
2255    pub fn random_file<P: AsRef<Path>>(mut self, p: P) -> Result<Self, Error<C>> {
2256        self.easy.random_file(p).map_err(|err| {
2257            log::trace!("{err}");
2258            Error::Curl(err)
2259        })?;
2260        Ok(self)
2261    }
2262
2263    /// Specify EGD socket path.
2264    ///
2265    /// Indicates the path name to the Entropy Gathering Daemon socket. It will
2266    /// be used to seed the random engine for SSL.
2267    ///
2268    /// By default this option is not set and corresponds to
2269    /// `CURLOPT_EGDSOCKET`.
2270    pub fn egd_socket<P: AsRef<Path>>(mut self, p: P) -> Result<Self, Error<C>> {
2271        self.easy.egd_socket(p).map_err(|err| {
2272            log::trace!("{err}");
2273            Error::Curl(err)
2274        })?;
2275        Ok(self)
2276    }
2277
2278    /// Specify ciphers to use for TLS.
2279    ///
2280    /// Holds the list of ciphers to use for the SSL connection. The list must
2281    /// be syntactically correct, it consists of one or more cipher strings
2282    /// separated by colons. Commas or spaces are also acceptable separators
2283    /// but colons are normally used, !, - and + can be used as operators.
2284    ///
2285    /// For OpenSSL and GnuTLS valid examples of cipher lists include 'RC4-SHA',
2286    /// ´SHA1+DES´, 'TLSv1' and 'DEFAULT'. The default list is normally set when
2287    /// you compile OpenSSL.
2288    ///
2289    /// You'll find more details about cipher lists on this URL:
2290    ///
2291    /// <https://www.openssl.org/docs/apps/ciphers.html>
2292    ///
2293    /// For NSS, valid examples of cipher lists include 'rsa_rc4_128_md5',
2294    /// ´rsa_aes_128_sha´, etc. With NSS you don't add/remove ciphers. If one
2295    /// uses this option then all known ciphers are disabled and only those
2296    /// passed in are enabled.
2297    ///
2298    /// By default this option is not set and corresponds to
2299    /// `CURLOPT_SSL_CIPHER_LIST`.
2300    pub fn ssl_cipher_list(mut self, ciphers: &str) -> Result<Self, Error<C>> {
2301        self.easy.ssl_cipher_list(ciphers).map_err(|err| {
2302            log::trace!("{err}");
2303            Error::Curl(err)
2304        })?;
2305        Ok(self)
2306    }
2307
2308    /// Specify ciphers to use for TLS for an HTTPS proxy.
2309    ///
2310    /// Holds the list of ciphers to use for the SSL connection. The list must
2311    /// be syntactically correct, it consists of one or more cipher strings
2312    /// separated by colons. Commas or spaces are also acceptable separators
2313    /// but colons are normally used, !, - and + can be used as operators.
2314    ///
2315    /// For OpenSSL and GnuTLS valid examples of cipher lists include 'RC4-SHA',
2316    /// ´SHA1+DES´, 'TLSv1' and 'DEFAULT'. The default list is normally set when
2317    /// you compile OpenSSL.
2318    ///
2319    /// You'll find more details about cipher lists on this URL:
2320    ///
2321    /// <https://www.openssl.org/docs/apps/ciphers.html>
2322    ///
2323    /// For NSS, valid examples of cipher lists include 'rsa_rc4_128_md5',
2324    /// ´rsa_aes_128_sha´, etc. With NSS you don't add/remove ciphers. If one
2325    /// uses this option then all known ciphers are disabled and only those
2326    /// passed in are enabled.
2327    ///
2328    /// By default this option is not set and corresponds to
2329    /// `CURLOPT_PROXY_SSL_CIPHER_LIST`.
2330    pub fn proxy_ssl_cipher_list(mut self, ciphers: &str) -> Result<Self, Error<C>> {
2331        self.easy.proxy_ssl_cipher_list(ciphers).map_err(|err| {
2332            log::trace!("{err}");
2333            Error::Curl(err)
2334        })?;
2335        Ok(self)
2336    }
2337
2338    /// Enable or disable use of the SSL session-ID cache
2339    ///
2340    /// By default all transfers are done using the cache enabled. While nothing
2341    /// ever should get hurt by attempting to reuse SSL session-IDs, there seem
2342    /// to be or have been broken SSL implementations in the wild that may
2343    /// require you to disable this in order for you to succeed.
2344    ///
2345    /// This corresponds to the `CURLOPT_SSL_SESSIONID_CACHE` option.
2346    pub fn ssl_sessionid_cache(mut self, enable: bool) -> Result<Self, Error<C>> {
2347        self.easy.ssl_sessionid_cache(enable).map_err(|err| {
2348            log::trace!("{err}");
2349            Error::Curl(err)
2350        })?;
2351        Ok(self)
2352    }
2353
2354    /// Set SSL behavior options
2355    ///
2356    /// Inform libcurl about SSL specific behaviors.
2357    ///
2358    /// This corresponds to the `CURLOPT_SSL_OPTIONS` option.
2359    pub fn ssl_options(mut self, bits: &SslOpt) -> Result<Self, Error<C>> {
2360        self.easy.ssl_options(bits).map_err(|err| {
2361            log::trace!("{err}");
2362            Error::Curl(err)
2363        })?;
2364        Ok(self)
2365    }
2366
2367    /// Set SSL behavior options for proxies
2368    ///
2369    /// Inform libcurl about SSL specific behaviors.
2370    ///
2371    /// This corresponds to the `CURLOPT_PROXY_SSL_OPTIONS` option.
2372    pub fn proxy_ssl_options(mut self, bits: &SslOpt) -> Result<Self, Error<C>> {
2373        self.easy.proxy_ssl_options(bits).map_err(|err| {
2374            log::trace!("{err}");
2375            Error::Curl(err)
2376        })?;
2377        Ok(self)
2378    }
2379
2380    // /// Stores a private pointer-sized piece of data.
2381    // ///
2382    // /// This can be retrieved through the `private` function and otherwise
2383    // /// libcurl does not tamper with this value. This corresponds to
2384    // /// `CURLOPT_PRIVATE` and defaults to 0.
2385    // pub fn set_private(mut self, private: usize) -> Result<Self, Error<C>> {
2386    //     self.setopt_ptr(curl_sys::CURLOPT_PRIVATE, private as *const _)
2387    // }
2388    //
2389    // /// Fetches this handle's private pointer-sized piece of data.
2390    // ///
2391    // /// This corresponds to `CURLINFO_PRIVATE` and defaults to 0.
2392    // pub fn private(&self) -> Result<usize, Error> {
2393    //     self.getopt_ptr(curl_sys::CURLINFO_PRIVATE).map(|p| p as usize)
2394    // }
2395
2396    // =========================================================================
2397    // getters
2398
2399    /// Set maximum time to wait for Expect 100 request before sending body.
2400    ///
2401    /// `curl` has internal heuristics that trigger the use of a `Expect`
2402    /// header for large enough request bodies where the client first sends the
2403    /// request header along with an `Expect: 100-continue` header. The server
2404    /// is supposed to validate the headers and respond with a `100` response
2405    /// status code after which `curl` will send the actual request body.
2406    ///
2407    /// However, if the server does not respond to the initial request
2408    /// within `CURLOPT_EXPECT_100_TIMEOUT_MS` then `curl` will send the
2409    /// request body anyways.
2410    ///
2411    /// The best-case scenario is where the request is invalid and the server
2412    /// replies with a `417 Expectation Failed` without having to wait for or process
2413    /// the request body at all. However, this behaviour can also lead to higher
2414    /// total latency since in the best case, an additional server roundtrip is required
2415    /// and in the worst case, the request is delayed by `CURLOPT_EXPECT_100_TIMEOUT_MS`.
2416    ///
2417    /// More info: <https://curl.se/libcurl/c/CURLOPT_EXPECT_100_TIMEOUT_MS.html>
2418    ///
2419    /// By default this option is not set and corresponds to
2420    /// `CURLOPT_EXPECT_100_TIMEOUT_MS`.
2421    pub fn expect_100_timeout(mut self, timeout: Duration) -> Result<Self, Error<C>> {
2422        self.easy.expect_100_timeout(timeout).map_err(|err| {
2423            log::trace!("{err}");
2424            Error::Curl(err)
2425        })?;
2426        Ok(self)
2427    }
2428
2429    /// Wait for pipelining/multiplexing
2430    ///
2431    /// Set wait to `true` to tell libcurl to prefer to wait for a connection to
2432    /// confirm or deny that it can do pipelining or multiplexing before
2433    /// continuing.
2434    ///
2435    /// When about to perform a new transfer that allows pipelining or
2436    /// multiplexing, libcurl will check for existing connections to re-use and
2437    /// pipeline on. If no such connection exists it will immediately continue
2438    /// and create a fresh new connection to use.
2439    ///
2440    /// By setting this option to `true` - and having `pipelining(true, true)`
2441    /// enabled for the multi handle this transfer is associated with - libcurl
2442    /// will instead wait for the connection to reveal if it is possible to
2443    /// pipeline/multiplex on before it continues. This enables libcurl to much
2444    /// better keep the number of connections to a minimum when using pipelining
2445    /// or multiplexing protocols.
2446    ///
2447    /// The effect thus becomes that with this option set, libcurl prefers to
2448    /// wait and re-use an existing connection for pipelining rather than the
2449    /// opposite: prefer to open a new connection rather than waiting.
2450    ///
2451    /// The waiting time is as long as it takes for the connection to get up and
2452    /// for libcurl to get the necessary response back that informs it about its
2453    /// protocol and support level.
2454    ///
2455    /// This corresponds to the `CURLOPT_PIPEWAIT` option.
2456    pub fn pipewait(mut self, wait: bool) -> Result<Self, Error<C>> {
2457        self.easy.pipewait(wait).map_err(|err| {
2458            log::trace!("{err}");
2459            Error::Curl(err)
2460        })?;
2461        Ok(self)
2462    }
2463
2464    /// Allow HTTP/0.9 compliant responses
2465    ///
2466    /// Set allow to `true` to tell libcurl to allow HTTP/0.9 responses. A HTTP/0.9
2467    /// response is a server response entirely without headers and only a body.
2468    ///
2469    /// By default this option is not set and corresponds to
2470    /// `CURLOPT_HTTP09_ALLOWED`.
2471    pub fn http_09_allowed(mut self, allow: bool) -> Result<Self, Error<C>> {
2472        self.easy.http_09_allowed(allow).map_err(|err| {
2473            log::trace!("{err}");
2474            Error::Curl(err)
2475        })?;
2476        Ok(self)
2477    }
2478
2479    /// Finalizes your build to proceed in performing CURL operation.
2480    pub fn finalize(self) -> AsyncCurl<C, Perform> {
2481        AsyncCurl::<C, Perform> {
2482            curl: self.curl,
2483            easy: self.easy,
2484            _state: Perform,
2485        }
2486    }
2487}
2488
2489impl<C> AsyncCurl<C, Perform>
2490where
2491    C: Handler + std::fmt::Debug + Send,
2492{
2493    /// This will send the request asynchronously,
2494    /// and return the underlying [`Easy2<C>`](https://docs.rs/curl/latest/curl/easy/struct.Easy2.html) useful if you
2495    /// want to decide how to transform the response yourself.
2496    pub async fn perform(self) -> Result<Easy2<C>, Error<C>> {
2497        self.curl.send_request(self.easy).await
2498    }
2499}