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}