curl/easy/
handle.rs

1use std::cell::Cell;
2use std::fmt;
3use std::io::SeekFrom;
4use std::path::Path;
5use std::ptr;
6use std::str;
7use std::time::Duration;
8
9use libc::c_void;
10
11use crate::easy::handler::{self, InfoType, ReadError, SeekResult, WriteError};
12use crate::easy::handler::{Auth, NetRc, PostRedirections, ProxyType, SslOpt};
13use crate::easy::handler::{HttpVersion, IpResolve, SslVersion, TimeCondition};
14use crate::easy::{Easy2, Handler};
15use crate::easy::{Form, List};
16use crate::Error;
17
18/// Raw bindings to a libcurl "easy session".
19///
20/// This type is the same as the `Easy2` type in this library except that it
21/// does not contain a type parameter. Callbacks from curl are all controlled
22/// via closures on this `Easy` type, and this type namely has a `transfer`
23/// method as well for ergonomic management of these callbacks.
24///
25/// There's not necessarily a right answer for which type is correct to use, but
26/// as a general rule of thumb `Easy` is typically a reasonable choice for
27/// synchronous I/O and `Easy2` is a good choice for asynchronous I/O.
28///
29/// ## Examples
30///
31/// Creating a handle which can be used later
32///
33/// ```
34/// use curl::easy::Easy;
35///
36/// let handle = Easy::new();
37/// ```
38///
39/// Send an HTTP request, writing the response to stdout.
40///
41/// ```
42/// use std::io::{stdout, Write};
43///
44/// use curl::easy::Easy;
45///
46/// let mut handle = Easy::new();
47/// handle.url("https://www.rust-lang.org/").unwrap();
48/// handle.write_function(|data| {
49///     stdout().write_all(data).unwrap();
50///     Ok(data.len())
51/// }).unwrap();
52/// handle.perform().unwrap();
53/// ```
54///
55/// Collect all output of an HTTP request to a vector.
56///
57/// ```
58/// use curl::easy::Easy;
59///
60/// let mut data = Vec::new();
61/// let mut handle = Easy::new();
62/// handle.url("https://www.rust-lang.org/").unwrap();
63/// {
64///     let mut transfer = handle.transfer();
65///     transfer.write_function(|new_data| {
66///         data.extend_from_slice(new_data);
67///         Ok(new_data.len())
68///     }).unwrap();
69///     transfer.perform().unwrap();
70/// }
71/// println!("{:?}", data);
72/// ```
73///
74/// More examples of various properties of an HTTP request can be found on the
75/// specific methods as well.
76#[derive(Debug)]
77pub struct Easy {
78    inner: Easy2<EasyData>,
79}
80
81/// A scoped transfer of information which borrows an `Easy` and allows
82/// referencing stack-local data of the lifetime `'data`.
83///
84/// Usage of `Easy` requires the `'static` and `Send` bounds on all callbacks
85/// registered, but that's not often wanted if all you need is to collect a
86/// bunch of data in memory to a vector, for example. The `Transfer` structure,
87/// created by the `Easy::transfer` method, is used for this sort of request.
88///
89/// The callbacks attached to a `Transfer` are only active for that one transfer
90/// object, and they allow to elide both the `Send` and `'static` bounds to
91/// close over stack-local information.
92pub struct Transfer<'easy, 'data> {
93    easy: &'easy mut Easy,
94    data: Box<Callbacks<'data>>,
95}
96
97pub struct EasyData {
98    running: Cell<bool>,
99    owned: Callbacks<'static>,
100    borrowed: Cell<*mut Callbacks<'static>>,
101}
102
103unsafe impl Send for EasyData {}
104
105#[derive(Default)]
106struct Callbacks<'a> {
107    write: Option<Box<dyn FnMut(&[u8]) -> Result<usize, WriteError> + 'a>>,
108    read: Option<Box<dyn FnMut(&mut [u8]) -> Result<usize, ReadError> + 'a>>,
109    seek: Option<Box<dyn FnMut(SeekFrom) -> SeekResult + 'a>>,
110    debug: Option<Box<dyn FnMut(InfoType, &[u8]) + 'a>>,
111    header: Option<Box<dyn FnMut(&[u8]) -> bool + 'a>>,
112    progress: Option<Box<dyn FnMut(f64, f64, f64, f64) -> bool + 'a>>,
113    ssl_ctx: Option<Box<dyn FnMut(*mut c_void) -> Result<(), Error> + 'a>>,
114}
115
116impl Easy {
117    /// Creates a new "easy" handle which is the core of almost all operations
118    /// in libcurl.
119    ///
120    /// To use a handle, applications typically configure a number of options
121    /// followed by a call to `perform`. Options are preserved across calls to
122    /// `perform` and need to be reset manually (or via the `reset` method) if
123    /// this is not desired.
124    pub fn new() -> Easy {
125        Easy {
126            inner: Easy2::new(EasyData {
127                running: Cell::new(false),
128                owned: Callbacks::default(),
129                borrowed: Cell::new(ptr::null_mut()),
130            }),
131        }
132    }
133
134    // =========================================================================
135    // Behavior options
136
137    /// Same as [`Easy2::verbose`](struct.Easy2.html#method.verbose)
138    pub fn verbose(&mut self, verbose: bool) -> Result<(), Error> {
139        self.inner.verbose(verbose)
140    }
141
142    /// Same as [`Easy2::show_header`](struct.Easy2.html#method.show_header)
143    pub fn show_header(&mut self, show: bool) -> Result<(), Error> {
144        self.inner.show_header(show)
145    }
146
147    /// Same as [`Easy2::progress`](struct.Easy2.html#method.progress)
148    pub fn progress(&mut self, progress: bool) -> Result<(), Error> {
149        self.inner.progress(progress)
150    }
151
152    /// Same as [`Easy2::signal`](struct.Easy2.html#method.signal)
153    pub fn signal(&mut self, signal: bool) -> Result<(), Error> {
154        self.inner.signal(signal)
155    }
156
157    /// Same as [`Easy2::wildcard_match`](struct.Easy2.html#method.wildcard_match)
158    pub fn wildcard_match(&mut self, m: bool) -> Result<(), Error> {
159        self.inner.wildcard_match(m)
160    }
161
162    /// Same as [`Easy2::unix_socket`](struct.Easy2.html#method.unix_socket)
163    pub fn unix_socket(&mut self, unix_domain_socket: &str) -> Result<(), Error> {
164        self.inner.unix_socket(unix_domain_socket)
165    }
166
167    /// Same as [`Easy2::unix_socket_path`](struct.Easy2.html#method.unix_socket_path)
168    pub fn unix_socket_path<P: AsRef<Path>>(&mut self, path: Option<P>) -> Result<(), Error> {
169        self.inner.unix_socket_path(path)
170    }
171
172    /// Same as [`Easy2::abstract_unix_socket`](struct.Easy2.html#method.abstract_unix_socket)
173    ///
174    /// NOTE: this API can only be used on Linux OS.
175    #[cfg(target_os = "linux")]
176    pub fn abstract_unix_socket(&mut self, addr: &[u8]) -> Result<(), Error> {
177        self.inner.abstract_unix_socket(addr)
178    }
179
180    // =========================================================================
181    // Callback options
182
183    /// Set callback for writing received data.
184    ///
185    /// This callback function gets called by libcurl as soon as there is data
186    /// received that needs to be saved.
187    ///
188    /// The callback function will be passed as much data as possible in all
189    /// invokes, but you must not make any assumptions. It may be one byte, it
190    /// may be thousands. If `show_header` is enabled, which makes header data
191    /// get passed to the write callback, you can get up to
192    /// `CURL_MAX_HTTP_HEADER` bytes of header data passed into it.  This
193    /// usually means 100K.
194    ///
195    /// This function may be called with zero bytes data if the transferred file
196    /// is empty.
197    ///
198    /// The callback should return the number of bytes actually taken care of.
199    /// If that amount differs from the amount passed to your callback function,
200    /// it'll signal an error condition to the library. This will cause the
201    /// transfer to get aborted and the libcurl function used will return
202    /// an error with `is_write_error`.
203    ///
204    /// If your callback function returns `Err(WriteError::Pause)` it will cause
205    /// this transfer to become paused. See `unpause_write` for further details.
206    ///
207    /// By default data is sent into the void, and this corresponds to the
208    /// `CURLOPT_WRITEFUNCTION` and `CURLOPT_WRITEDATA` options.
209    ///
210    /// Note that the lifetime bound on this function is `'static`, but that
211    /// is often too restrictive. To use stack data consider calling the
212    /// `transfer` method and then using `write_function` to configure a
213    /// callback that can reference stack-local data.
214    ///
215    /// # Examples
216    ///
217    /// ```
218    /// use std::io::{stdout, Write};
219    /// use curl::easy::Easy;
220    ///
221    /// let mut handle = Easy::new();
222    /// handle.url("https://www.rust-lang.org/").unwrap();
223    /// handle.write_function(|data| {
224    ///     Ok(stdout().write(data).unwrap())
225    /// }).unwrap();
226    /// handle.perform().unwrap();
227    /// ```
228    ///
229    /// Writing to a stack-local buffer
230    ///
231    /// ```
232    /// use std::io::{stdout, Write};
233    /// use curl::easy::Easy;
234    ///
235    /// let mut buf = Vec::new();
236    /// let mut handle = Easy::new();
237    /// handle.url("https://www.rust-lang.org/").unwrap();
238    ///
239    /// let mut transfer = handle.transfer();
240    /// transfer.write_function(|data| {
241    ///     buf.extend_from_slice(data);
242    ///     Ok(data.len())
243    /// }).unwrap();
244    /// transfer.perform().unwrap();
245    /// ```
246    pub fn write_function<F>(&mut self, f: F) -> Result<(), Error>
247    where
248        F: FnMut(&[u8]) -> Result<usize, WriteError> + Send + 'static,
249    {
250        self.inner.get_mut().owned.write = Some(Box::new(f));
251        Ok(())
252    }
253
254    /// Read callback for data uploads.
255    ///
256    /// This callback function gets called by libcurl as soon as it needs to
257    /// read data in order to send it to the peer - like if you ask it to upload
258    /// or post data to the server.
259    ///
260    /// Your function must then return the actual number of bytes that it stored
261    /// in that memory area. Returning 0 will signal end-of-file to the library
262    /// and cause it to stop the current transfer.
263    ///
264    /// If you stop the current transfer by returning 0 "pre-maturely" (i.e
265    /// before the server expected it, like when you've said you will upload N
266    /// bytes and you upload less than N bytes), you may experience that the
267    /// server "hangs" waiting for the rest of the data that won't come.
268    ///
269    /// The read callback may return `Err(ReadError::Abort)` to stop the
270    /// current operation immediately, resulting in a `is_aborted_by_callback`
271    /// error code from the transfer.
272    ///
273    /// The callback can return `Err(ReadError::Pause)` to cause reading from
274    /// this connection to pause. See `unpause_read` for further details.
275    ///
276    /// By default data not input, and this corresponds to the
277    /// `CURLOPT_READFUNCTION` and `CURLOPT_READDATA` options.
278    ///
279    /// Note that the lifetime bound on this function is `'static`, but that
280    /// is often too restrictive. To use stack data consider calling the
281    /// `transfer` method and then using `read_function` to configure a
282    /// callback that can reference stack-local data.
283    ///
284    /// # Examples
285    ///
286    /// Read input from stdin
287    ///
288    /// ```no_run
289    /// use std::io::{stdin, Read};
290    /// use curl::easy::Easy;
291    ///
292    /// let mut handle = Easy::new();
293    /// handle.url("https://example.com/login").unwrap();
294    /// handle.read_function(|into| {
295    ///     Ok(stdin().read(into).unwrap())
296    /// }).unwrap();
297    /// handle.post(true).unwrap();
298    /// handle.perform().unwrap();
299    /// ```
300    ///
301    /// Reading from stack-local data:
302    ///
303    /// ```no_run
304    /// use std::io::{stdin, Read};
305    /// use curl::easy::Easy;
306    ///
307    /// let mut data_to_upload = &b"foobar"[..];
308    /// let mut handle = Easy::new();
309    /// handle.url("https://example.com/login").unwrap();
310    /// handle.post(true).unwrap();
311    ///
312    /// let mut transfer = handle.transfer();
313    /// transfer.read_function(|into| {
314    ///     Ok(data_to_upload.read(into).unwrap())
315    /// }).unwrap();
316    /// transfer.perform().unwrap();
317    /// ```
318    pub fn read_function<F>(&mut self, f: F) -> Result<(), Error>
319    where
320        F: FnMut(&mut [u8]) -> Result<usize, ReadError> + Send + 'static,
321    {
322        self.inner.get_mut().owned.read = Some(Box::new(f));
323        Ok(())
324    }
325
326    /// User callback for seeking in input stream.
327    ///
328    /// This function gets called by libcurl to seek to a certain position in
329    /// the input stream and can be used to fast forward a file in a resumed
330    /// upload (instead of reading all uploaded bytes with the normal read
331    /// function/callback). It is also called to rewind a stream when data has
332    /// already been sent to the server and needs to be sent again. This may
333    /// happen when doing a HTTP PUT or POST with a multi-pass authentication
334    /// method, or when an existing HTTP connection is reused too late and the
335    /// server closes the connection.
336    ///
337    /// The callback function must return `SeekResult::Ok` on success,
338    /// `SeekResult::Fail` to cause the upload operation to fail or
339    /// `SeekResult::CantSeek` to indicate that while the seek failed, libcurl
340    /// is free to work around the problem if possible. The latter can sometimes
341    /// be done by instead reading from the input or similar.
342    ///
343    /// By default data this option is not set, and this corresponds to the
344    /// `CURLOPT_SEEKFUNCTION` and `CURLOPT_SEEKDATA` options.
345    ///
346    /// Note that the lifetime bound on this function is `'static`, but that
347    /// is often too restrictive. To use stack data consider calling the
348    /// `transfer` method and then using `seek_function` to configure a
349    /// callback that can reference stack-local data.
350    pub fn seek_function<F>(&mut self, f: F) -> Result<(), Error>
351    where
352        F: FnMut(SeekFrom) -> SeekResult + Send + 'static,
353    {
354        self.inner.get_mut().owned.seek = Some(Box::new(f));
355        Ok(())
356    }
357
358    /// Callback to progress meter function
359    ///
360    /// This function gets called by libcurl instead of its internal equivalent
361    /// with a frequent interval. While data is being transferred it will be
362    /// called very frequently, and during slow periods like when nothing is
363    /// being transferred it can slow down to about one call per second.
364    ///
365    /// The callback gets told how much data libcurl will transfer and has
366    /// transferred, in number of bytes. The first argument is the total number
367    /// of bytes libcurl expects to download in this transfer. The second
368    /// argument is the number of bytes downloaded so far. The third argument is
369    /// the total number of bytes libcurl expects to upload in this transfer.
370    /// The fourth argument is the number of bytes uploaded so far.
371    ///
372    /// Unknown/unused argument values passed to the callback will be set to
373    /// zero (like if you only download data, the upload size will remain 0).
374    /// Many times the callback will be called one or more times first, before
375    /// it knows the data sizes so a program must be made to handle that.
376    ///
377    /// Returning `false` from this callback will cause libcurl to abort the
378    /// transfer and return `is_aborted_by_callback`.
379    ///
380    /// If you transfer data with the multi interface, this function will not be
381    /// called during periods of idleness unless you call the appropriate
382    /// libcurl function that performs transfers.
383    ///
384    /// `progress` must be set to `true` to make this function actually get
385    /// called.
386    ///
387    /// By default this function calls an internal method and corresponds to
388    /// `CURLOPT_PROGRESSFUNCTION` and `CURLOPT_PROGRESSDATA`.
389    ///
390    /// Note that the lifetime bound on this function is `'static`, but that
391    /// is often too restrictive. To use stack data consider calling the
392    /// `transfer` method and then using `progress_function` to configure a
393    /// callback that can reference stack-local data.
394    pub fn progress_function<F>(&mut self, f: F) -> Result<(), Error>
395    where
396        F: FnMut(f64, f64, f64, f64) -> bool + Send + 'static,
397    {
398        self.inner.get_mut().owned.progress = Some(Box::new(f));
399        Ok(())
400    }
401
402    /// Callback to SSL context
403    ///
404    /// This callback function gets called by libcurl just before the
405    /// initialization of an SSL connection after having processed all
406    /// other SSL related options to give a last chance to an
407    /// application to modify the behaviour of the SSL
408    /// initialization. The `ssl_ctx` parameter is actually a pointer
409    /// to the SSL library's SSL_CTX. If an error is returned from the
410    /// callback no attempt to establish a connection is made and the
411    /// perform operation will return the callback's error code.
412    ///
413    /// This function will get called on all new connections made to a
414    /// server, during the SSL negotiation. The SSL_CTX pointer will
415    /// be a new one every time.
416    ///
417    /// To use this properly, a non-trivial amount of knowledge of
418    /// your SSL library is necessary. For example, you can use this
419    /// function to call library-specific callbacks to add additional
420    /// validation code for certificates, and even to change the
421    /// actual URI of a HTTPS request.
422    ///
423    /// By default this function calls an internal method and
424    /// corresponds to `CURLOPT_SSL_CTX_FUNCTION` and
425    /// `CURLOPT_SSL_CTX_DATA`.
426    ///
427    /// Note that the lifetime bound on this function is `'static`, but that
428    /// is often too restrictive. To use stack data consider calling the
429    /// `transfer` method and then using `progress_function` to configure a
430    /// callback that can reference stack-local data.
431    pub fn ssl_ctx_function<F>(&mut self, f: F) -> Result<(), Error>
432    where
433        F: FnMut(*mut c_void) -> Result<(), Error> + Send + 'static,
434    {
435        self.inner.get_mut().owned.ssl_ctx = Some(Box::new(f));
436        Ok(())
437    }
438
439    /// Specify a debug callback
440    ///
441    /// `debug_function` replaces the standard debug function used when
442    /// `verbose` is in effect. This callback receives debug information,
443    /// as specified in the type argument.
444    ///
445    /// By default this option is not set and corresponds to the
446    /// `CURLOPT_DEBUGFUNCTION` and `CURLOPT_DEBUGDATA` options.
447    ///
448    /// Note that the lifetime bound on this function is `'static`, but that
449    /// is often too restrictive. To use stack data consider calling the
450    /// `transfer` method and then using `debug_function` to configure a
451    /// callback that can reference stack-local data.
452    pub fn debug_function<F>(&mut self, f: F) -> Result<(), Error>
453    where
454        F: FnMut(InfoType, &[u8]) + Send + 'static,
455    {
456        self.inner.get_mut().owned.debug = Some(Box::new(f));
457        Ok(())
458    }
459
460    /// Callback that receives header data
461    ///
462    /// This function gets called by libcurl as soon as it has received header
463    /// data. The header callback will be called once for each header and only
464    /// complete header lines are passed on to the callback. Parsing headers is
465    /// very easy using this. If this callback returns `false` it'll signal an
466    /// error to the library. This will cause the transfer to get aborted and
467    /// the libcurl function in progress will return `is_write_error`.
468    ///
469    /// A complete HTTP header that is passed to this function can be up to
470    /// CURL_MAX_HTTP_HEADER (100K) bytes.
471    ///
472    /// It's important to note that the callback will be invoked for the headers
473    /// of all responses received after initiating a request and not just the
474    /// final response. This includes all responses which occur during
475    /// authentication negotiation. If you need to operate on only the headers
476    /// from the final response, you will need to collect headers in the
477    /// callback yourself and use HTTP status lines, for example, to delimit
478    /// response boundaries.
479    ///
480    /// When a server sends a chunked encoded transfer, it may contain a
481    /// trailer. That trailer is identical to a HTTP header and if such a
482    /// trailer is received it is passed to the application using this callback
483    /// as well. There are several ways to detect it being a trailer and not an
484    /// ordinary header: 1) it comes after the response-body. 2) it comes after
485    /// the final header line (CR LF) 3) a Trailer: header among the regular
486    /// response-headers mention what header(s) to expect in the trailer.
487    ///
488    /// For non-HTTP protocols like FTP, POP3, IMAP and SMTP this function will
489    /// get called with the server responses to the commands that libcurl sends.
490    ///
491    /// By default this option is not set and corresponds to the
492    /// `CURLOPT_HEADERFUNCTION` and `CURLOPT_HEADERDATA` options.
493    ///
494    /// Note that the lifetime bound on this function is `'static`, but that
495    /// is often too restrictive. To use stack data consider calling the
496    /// `transfer` method and then using `header_function` to configure a
497    /// callback that can reference stack-local data.
498    ///
499    /// # Examples
500    ///
501    /// ```
502    /// use std::str;
503    ///
504    /// use curl::easy::Easy;
505    ///
506    /// let mut handle = Easy::new();
507    /// handle.url("https://www.rust-lang.org/").unwrap();
508    /// handle.header_function(|header| {
509    ///     print!("header: {}", str::from_utf8(header).unwrap());
510    ///     true
511    /// }).unwrap();
512    /// handle.perform().unwrap();
513    /// ```
514    ///
515    /// Collecting headers to a stack local vector
516    ///
517    /// ```
518    /// use std::str;
519    ///
520    /// use curl::easy::Easy;
521    ///
522    /// let mut headers = Vec::new();
523    /// let mut handle = Easy::new();
524    /// handle.url("https://www.rust-lang.org/").unwrap();
525    ///
526    /// {
527    ///     let mut transfer = handle.transfer();
528    ///     transfer.header_function(|header| {
529    ///         headers.push(str::from_utf8(header).unwrap().to_string());
530    ///         true
531    ///     }).unwrap();
532    ///     transfer.perform().unwrap();
533    /// }
534    ///
535    /// println!("{:?}", headers);
536    /// ```
537    pub fn header_function<F>(&mut self, f: F) -> Result<(), Error>
538    where
539        F: FnMut(&[u8]) -> bool + Send + 'static,
540    {
541        self.inner.get_mut().owned.header = Some(Box::new(f));
542        Ok(())
543    }
544
545    // =========================================================================
546    // Error options
547
548    // TODO: error buffer and stderr
549
550    /// Same as [`Easy2::fail_on_error`](struct.Easy2.html#method.fail_on_error)
551    pub fn fail_on_error(&mut self, fail: bool) -> Result<(), Error> {
552        self.inner.fail_on_error(fail)
553    }
554
555    // =========================================================================
556    // Network options
557
558    /// Same as [`Easy2::url`](struct.Easy2.html#method.url)
559    pub fn url(&mut self, url: &str) -> Result<(), Error> {
560        self.inner.url(url)
561    }
562
563    /// Same as [`Easy2::port`](struct.Easy2.html#method.port)
564    pub fn port(&mut self, port: u16) -> Result<(), Error> {
565        self.inner.port(port)
566    }
567
568    /// Same as [`Easy2::connect_to`](struct.Easy2.html#method.connect_to)
569    pub fn connect_to(&mut self, list: List) -> Result<(), Error> {
570        self.inner.connect_to(list)
571    }
572
573    /// Same as [`Easy2::path_as_is`](struct.Easy2.html#method.path_as_is)
574    pub fn path_as_is(&mut self, as_is: bool) -> Result<(), Error> {
575        self.inner.path_as_is(as_is)
576    }
577
578    /// Same as [`Easy2::proxy`](struct.Easy2.html#method.proxy)
579    pub fn proxy(&mut self, url: &str) -> Result<(), Error> {
580        self.inner.proxy(url)
581    }
582
583    /// Same as [`Easy2::proxy_port`](struct.Easy2.html#method.proxy_port)
584    pub fn proxy_port(&mut self, port: u16) -> Result<(), Error> {
585        self.inner.proxy_port(port)
586    }
587
588    /// Same as [`Easy2::proxy_cainfo`](struct.Easy2.html#method.proxy_cainfo)
589    pub fn proxy_cainfo(&mut self, cainfo: &str) -> Result<(), Error> {
590        self.inner.proxy_cainfo(cainfo)
591    }
592
593    /// Same as [`Easy2::proxy_capath`](struct.Easy2.html#method.proxy_capath)
594    pub fn proxy_capath<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
595        self.inner.proxy_capath(path)
596    }
597
598    /// Same as [`Easy2::proxy_sslcert`](struct.Easy2.html#method.proxy_sslcert)
599    pub fn proxy_sslcert(&mut self, sslcert: &str) -> Result<(), Error> {
600        self.inner.proxy_sslcert(sslcert)
601    }
602
603    /// Same as [`Easy2::proxy_sslcert_type`](struct.Easy2.html#method.proxy_sslcert_type)
604    pub fn proxy_sslcert_type(&mut self, kind: &str) -> Result<(), Error> {
605        self.inner.proxy_sslcert_type(kind)
606    }
607
608    /// Same as [`Easy2::proxy_sslcert_blob`](struct.Easy2.html#method.proxy_sslcert_blob)
609    pub fn proxy_sslcert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
610        self.inner.proxy_sslcert_blob(blob)
611    }
612
613    /// Same as [`Easy2::proxy_sslkey`](struct.Easy2.html#method.proxy_sslkey)
614    pub fn proxy_sslkey(&mut self, sslkey: &str) -> Result<(), Error> {
615        self.inner.proxy_sslkey(sslkey)
616    }
617
618    /// Same as [`Easy2::proxy_sslkey_type`](struct.Easy2.html#method.proxy_sslkey_type)
619    pub fn proxy_sslkey_type(&mut self, kind: &str) -> Result<(), Error> {
620        self.inner.proxy_sslkey_type(kind)
621    }
622
623    /// Same as [`Easy2::proxy_sslkey_blob`](struct.Easy2.html#method.proxy_sslkey_blob)
624    pub fn proxy_sslkey_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
625        self.inner.proxy_sslkey_blob(blob)
626    }
627
628    /// Same as [`Easy2::proxy_key_password`](struct.Easy2.html#method.proxy_key_password)
629    pub fn proxy_key_password(&mut self, password: &str) -> Result<(), Error> {
630        self.inner.proxy_key_password(password)
631    }
632
633    /// Same as [`Easy2::proxy_type`](struct.Easy2.html#method.proxy_type)
634    pub fn proxy_type(&mut self, kind: ProxyType) -> Result<(), Error> {
635        self.inner.proxy_type(kind)
636    }
637
638    /// Same as [`Easy2::noproxy`](struct.Easy2.html#method.noproxy)
639    pub fn noproxy(&mut self, skip: &str) -> Result<(), Error> {
640        self.inner.noproxy(skip)
641    }
642
643    /// Same as [`Easy2::http_proxy_tunnel`](struct.Easy2.html#method.http_proxy_tunnel)
644    pub fn http_proxy_tunnel(&mut self, tunnel: bool) -> Result<(), Error> {
645        self.inner.http_proxy_tunnel(tunnel)
646    }
647
648    /// Same as [`Easy2::interface`](struct.Easy2.html#method.interface)
649    pub fn interface(&mut self, interface: &str) -> Result<(), Error> {
650        self.inner.interface(interface)
651    }
652
653    /// Same as [`Easy2::set_local_port`](struct.Easy2.html#method.set_local_port)
654    pub fn set_local_port(&mut self, port: u16) -> Result<(), Error> {
655        self.inner.set_local_port(port)
656    }
657
658    /// Same as [`Easy2::local_port_range`](struct.Easy2.html#method.local_port_range)
659    pub fn local_port_range(&mut self, range: u16) -> Result<(), Error> {
660        self.inner.local_port_range(range)
661    }
662
663    /// Same as [`Easy2::dns_servers`](struct.Easy2.html#method.dns_servers)
664    pub fn dns_servers(&mut self, servers: &str) -> Result<(), Error> {
665        self.inner.dns_servers(servers)
666    }
667
668    /// Same as [`Easy2::dns_cache_timeout`](struct.Easy2.html#method.dns_cache_timeout)
669    pub fn dns_cache_timeout(&mut self, dur: Duration) -> Result<(), Error> {
670        self.inner.dns_cache_timeout(dur)
671    }
672
673    /// Same as [`Easy2::doh_url`](struct.Easy2.html#method.doh_url)
674    pub fn doh_url(&mut self, url: Option<&str>) -> Result<(), Error> {
675        self.inner.doh_url(url)
676    }
677
678    /// Same as [`Easy2::doh_ssl_verify_peer`](struct.Easy2.html#method.doh_ssl_verify_peer)
679    pub fn doh_ssl_verify_peer(&mut self, verify: bool) -> Result<(), Error> {
680        self.inner.doh_ssl_verify_peer(verify)
681    }
682
683    /// Same as [`Easy2::doh_ssl_verify_host`](struct.Easy2.html#method.doh_ssl_verify_host)
684    pub fn doh_ssl_verify_host(&mut self, verify: bool) -> Result<(), Error> {
685        self.inner.doh_ssl_verify_host(verify)
686    }
687
688    /// Same as [`Easy2::doh_ssl_verify_status`](struct.Easy2.html#method.doh_ssl_verify_status)
689    pub fn doh_ssl_verify_status(&mut self, verify: bool) -> Result<(), Error> {
690        self.inner.doh_ssl_verify_status(verify)
691    }
692
693    /// Same as [`Easy2::buffer_size`](struct.Easy2.html#method.buffer_size)
694    pub fn buffer_size(&mut self, size: usize) -> Result<(), Error> {
695        self.inner.buffer_size(size)
696    }
697
698    /// Same as [`Easy2::upload_buffer_size`](struct.Easy2.html#method.upload_buffer_size)
699    pub fn upload_buffer_size(&mut self, size: usize) -> Result<(), Error> {
700        self.inner.upload_buffer_size(size)
701    }
702
703    /// Same as [`Easy2::tcp_nodelay`](struct.Easy2.html#method.tcp_nodelay)
704    pub fn tcp_nodelay(&mut self, enable: bool) -> Result<(), Error> {
705        self.inner.tcp_nodelay(enable)
706    }
707
708    /// Same as [`Easy2::tcp_keepalive`](struct.Easy2.html#method.tcp_keepalive)
709    pub fn tcp_keepalive(&mut self, enable: bool) -> Result<(), Error> {
710        self.inner.tcp_keepalive(enable)
711    }
712
713    /// Same as [`Easy2::tcp_keepintvl`](struct.Easy2.html#method.tcp_keepalive)
714    pub fn tcp_keepintvl(&mut self, dur: Duration) -> Result<(), Error> {
715        self.inner.tcp_keepintvl(dur)
716    }
717
718    /// Same as [`Easy2::tcp_keepidle`](struct.Easy2.html#method.tcp_keepidle)
719    pub fn tcp_keepidle(&mut self, dur: Duration) -> Result<(), Error> {
720        self.inner.tcp_keepidle(dur)
721    }
722
723    /// Same as [`Easy2::address_scope`](struct.Easy2.html#method.address_scope)
724    pub fn address_scope(&mut self, scope: u32) -> Result<(), Error> {
725        self.inner.address_scope(scope)
726    }
727
728    // =========================================================================
729    // Names and passwords
730
731    /// Same as [`Easy2::username`](struct.Easy2.html#method.username)
732    pub fn username(&mut self, user: &str) -> Result<(), Error> {
733        self.inner.username(user)
734    }
735
736    /// Same as [`Easy2::password`](struct.Easy2.html#method.password)
737    pub fn password(&mut self, pass: &str) -> Result<(), Error> {
738        self.inner.password(pass)
739    }
740
741    /// Same as [`Easy2::http_auth`](struct.Easy2.html#method.http_auth)
742    pub fn http_auth(&mut self, auth: &Auth) -> Result<(), Error> {
743        self.inner.http_auth(auth)
744    }
745
746    /// Same as [`Easy2::aws_sigv4`](struct.Easy2.html#method.aws_sigv4)
747    pub fn aws_sigv4(&mut self, param: &str) -> Result<(), Error> {
748        self.inner.aws_sigv4(param)
749    }
750
751    /// Same as [`Easy2::proxy_username`](struct.Easy2.html#method.proxy_username)
752    pub fn proxy_username(&mut self, user: &str) -> Result<(), Error> {
753        self.inner.proxy_username(user)
754    }
755
756    /// Same as [`Easy2::proxy_password`](struct.Easy2.html#method.proxy_password)
757    pub fn proxy_password(&mut self, pass: &str) -> Result<(), Error> {
758        self.inner.proxy_password(pass)
759    }
760
761    /// Same as [`Easy2::proxy_auth`](struct.Easy2.html#method.proxy_auth)
762    pub fn proxy_auth(&mut self, auth: &Auth) -> Result<(), Error> {
763        self.inner.proxy_auth(auth)
764    }
765
766    /// Same as [`Easy2::netrc`](struct.Easy2.html#method.netrc)
767    pub fn netrc(&mut self, netrc: NetRc) -> Result<(), Error> {
768        self.inner.netrc(netrc)
769    }
770
771    // =========================================================================
772    // HTTP Options
773
774    /// Same as [`Easy2::autoreferer`](struct.Easy2.html#method.autoreferer)
775    pub fn autoreferer(&mut self, enable: bool) -> Result<(), Error> {
776        self.inner.autoreferer(enable)
777    }
778
779    /// Same as [`Easy2::accept_encoding`](struct.Easy2.html#method.accept_encoding)
780    pub fn accept_encoding(&mut self, encoding: &str) -> Result<(), Error> {
781        self.inner.accept_encoding(encoding)
782    }
783
784    /// Same as [`Easy2::transfer_encoding`](struct.Easy2.html#method.transfer_encoding)
785    pub fn transfer_encoding(&mut self, enable: bool) -> Result<(), Error> {
786        self.inner.transfer_encoding(enable)
787    }
788
789    /// Same as [`Easy2::follow_location`](struct.Easy2.html#method.follow_location)
790    pub fn follow_location(&mut self, enable: bool) -> Result<(), Error> {
791        self.inner.follow_location(enable)
792    }
793
794    /// Same as [`Easy2::unrestricted_auth`](struct.Easy2.html#method.unrestricted_auth)
795    pub fn unrestricted_auth(&mut self, enable: bool) -> Result<(), Error> {
796        self.inner.unrestricted_auth(enable)
797    }
798
799    /// Same as [`Easy2::max_redirections`](struct.Easy2.html#method.max_redirections)
800    pub fn max_redirections(&mut self, max: u32) -> Result<(), Error> {
801        self.inner.max_redirections(max)
802    }
803
804    /// Same as [`Easy2::post_redirections`](struct.Easy2.html#method.post_redirections)
805    pub fn post_redirections(&mut self, redirects: &PostRedirections) -> Result<(), Error> {
806        self.inner.post_redirections(redirects)
807    }
808
809    /// Same as [`Easy2::put`](struct.Easy2.html#method.put)
810    pub fn put(&mut self, enable: bool) -> Result<(), Error> {
811        self.inner.put(enable)
812    }
813
814    /// Same as [`Easy2::post`](struct.Easy2.html#method.post)
815    pub fn post(&mut self, enable: bool) -> Result<(), Error> {
816        self.inner.post(enable)
817    }
818
819    /// Same as [`Easy2::post_field_copy`](struct.Easy2.html#method.post_field_copy)
820    pub fn post_fields_copy(&mut self, data: &[u8]) -> Result<(), Error> {
821        self.inner.post_fields_copy(data)
822    }
823
824    /// Same as [`Easy2::post_field_size`](struct.Easy2.html#method.post_field_size)
825    pub fn post_field_size(&mut self, size: u64) -> Result<(), Error> {
826        self.inner.post_field_size(size)
827    }
828
829    /// Same as [`Easy2::httppost`](struct.Easy2.html#method.httppost)
830    pub fn httppost(&mut self, form: Form) -> Result<(), Error> {
831        self.inner.httppost(form)
832    }
833
834    /// Same as [`Easy2::referer`](struct.Easy2.html#method.referer)
835    pub fn referer(&mut self, referer: &str) -> Result<(), Error> {
836        self.inner.referer(referer)
837    }
838
839    /// Same as [`Easy2::useragent`](struct.Easy2.html#method.useragent)
840    pub fn useragent(&mut self, useragent: &str) -> Result<(), Error> {
841        self.inner.useragent(useragent)
842    }
843
844    /// Same as [`Easy2::http_headers`](struct.Easy2.html#method.http_headers)
845    pub fn http_headers(&mut self, list: List) -> Result<(), Error> {
846        self.inner.http_headers(list)
847    }
848
849    /// Same as [`Easy2::cookie`](struct.Easy2.html#method.cookie)
850    pub fn cookie(&mut self, cookie: &str) -> Result<(), Error> {
851        self.inner.cookie(cookie)
852    }
853
854    /// Same as [`Easy2::cookie_file`](struct.Easy2.html#method.cookie_file)
855    pub fn cookie_file<P: AsRef<Path>>(&mut self, file: P) -> Result<(), Error> {
856        self.inner.cookie_file(file)
857    }
858
859    /// Same as [`Easy2::cookie_jar`](struct.Easy2.html#method.cookie_jar)
860    pub fn cookie_jar<P: AsRef<Path>>(&mut self, file: P) -> Result<(), Error> {
861        self.inner.cookie_jar(file)
862    }
863
864    /// Same as [`Easy2::cookie_session`](struct.Easy2.html#method.cookie_session)
865    pub fn cookie_session(&mut self, session: bool) -> Result<(), Error> {
866        self.inner.cookie_session(session)
867    }
868
869    /// Same as [`Easy2::cookie_list`](struct.Easy2.html#method.cookie_list)
870    pub fn cookie_list(&mut self, cookie: &str) -> Result<(), Error> {
871        self.inner.cookie_list(cookie)
872    }
873
874    /// Same as [`Easy2::get`](struct.Easy2.html#method.get)
875    pub fn get(&mut self, enable: bool) -> Result<(), Error> {
876        self.inner.get(enable)
877    }
878
879    /// Same as [`Easy2::ignore_content_length`](struct.Easy2.html#method.ignore_content_length)
880    pub fn ignore_content_length(&mut self, ignore: bool) -> Result<(), Error> {
881        self.inner.ignore_content_length(ignore)
882    }
883
884    /// Same as [`Easy2::http_content_decoding`](struct.Easy2.html#method.http_content_decoding)
885    pub fn http_content_decoding(&mut self, enable: bool) -> Result<(), Error> {
886        self.inner.http_content_decoding(enable)
887    }
888
889    /// Same as [`Easy2::http_transfer_decoding`](struct.Easy2.html#method.http_transfer_decoding)
890    pub fn http_transfer_decoding(&mut self, enable: bool) -> Result<(), Error> {
891        self.inner.http_transfer_decoding(enable)
892    }
893
894    // =========================================================================
895    // Protocol Options
896
897    /// Same as [`Easy2::range`](struct.Easy2.html#method.range)
898    pub fn range(&mut self, range: &str) -> Result<(), Error> {
899        self.inner.range(range)
900    }
901
902    /// Same as [`Easy2::resume_from`](struct.Easy2.html#method.resume_from)
903    pub fn resume_from(&mut self, from: u64) -> Result<(), Error> {
904        self.inner.resume_from(from)
905    }
906
907    /// Same as [`Easy2::custom_request`](struct.Easy2.html#method.custom_request)
908    pub fn custom_request(&mut self, request: &str) -> Result<(), Error> {
909        self.inner.custom_request(request)
910    }
911
912    /// Same as [`Easy2::fetch_filetime`](struct.Easy2.html#method.fetch_filetime)
913    pub fn fetch_filetime(&mut self, fetch: bool) -> Result<(), Error> {
914        self.inner.fetch_filetime(fetch)
915    }
916
917    /// Same as [`Easy2::nobody`](struct.Easy2.html#method.nobody)
918    pub fn nobody(&mut self, enable: bool) -> Result<(), Error> {
919        self.inner.nobody(enable)
920    }
921
922    /// Same as [`Easy2::in_filesize`](struct.Easy2.html#method.in_filesize)
923    pub fn in_filesize(&mut self, size: u64) -> Result<(), Error> {
924        self.inner.in_filesize(size)
925    }
926
927    /// Same as [`Easy2::upload`](struct.Easy2.html#method.upload)
928    pub fn upload(&mut self, enable: bool) -> Result<(), Error> {
929        self.inner.upload(enable)
930    }
931
932    /// Same as [`Easy2::max_filesize`](struct.Easy2.html#method.max_filesize)
933    pub fn max_filesize(&mut self, size: u64) -> Result<(), Error> {
934        self.inner.max_filesize(size)
935    }
936
937    /// Same as [`Easy2::time_condition`](struct.Easy2.html#method.time_condition)
938    pub fn time_condition(&mut self, cond: TimeCondition) -> Result<(), Error> {
939        self.inner.time_condition(cond)
940    }
941
942    /// Same as [`Easy2::time_value`](struct.Easy2.html#method.time_value)
943    pub fn time_value(&mut self, val: i64) -> Result<(), Error> {
944        self.inner.time_value(val)
945    }
946
947    // =========================================================================
948    // Connection Options
949
950    /// Same as [`Easy2::timeout`](struct.Easy2.html#method.timeout)
951    pub fn timeout(&mut self, timeout: Duration) -> Result<(), Error> {
952        self.inner.timeout(timeout)
953    }
954
955    /// Same as [`Easy2::low_speed_limit`](struct.Easy2.html#method.low_speed_limit)
956    pub fn low_speed_limit(&mut self, limit: u32) -> Result<(), Error> {
957        self.inner.low_speed_limit(limit)
958    }
959
960    /// Same as [`Easy2::low_speed_time`](struct.Easy2.html#method.low_speed_time)
961    pub fn low_speed_time(&mut self, dur: Duration) -> Result<(), Error> {
962        self.inner.low_speed_time(dur)
963    }
964
965    /// Same as [`Easy2::max_send_speed`](struct.Easy2.html#method.max_send_speed)
966    pub fn max_send_speed(&mut self, speed: u64) -> Result<(), Error> {
967        self.inner.max_send_speed(speed)
968    }
969
970    /// Same as [`Easy2::max_recv_speed`](struct.Easy2.html#method.max_recv_speed)
971    pub fn max_recv_speed(&mut self, speed: u64) -> Result<(), Error> {
972        self.inner.max_recv_speed(speed)
973    }
974
975    /// Same as [`Easy2::max_connects`](struct.Easy2.html#method.max_connects)
976    pub fn max_connects(&mut self, max: u32) -> Result<(), Error> {
977        self.inner.max_connects(max)
978    }
979
980    /// Same as [`Easy2::maxage_conn`](struct.Easy2.html#method.maxage_conn)
981    pub fn maxage_conn(&mut self, max_age: Duration) -> Result<(), Error> {
982        self.inner.maxage_conn(max_age)
983    }
984
985    /// Same as [`Easy2::fresh_connect`](struct.Easy2.html#method.fresh_connect)
986    pub fn fresh_connect(&mut self, enable: bool) -> Result<(), Error> {
987        self.inner.fresh_connect(enable)
988    }
989
990    /// Same as [`Easy2::forbid_reuse`](struct.Easy2.html#method.forbid_reuse)
991    pub fn forbid_reuse(&mut self, enable: bool) -> Result<(), Error> {
992        self.inner.forbid_reuse(enable)
993    }
994
995    /// Same as [`Easy2::connect_timeout`](struct.Easy2.html#method.connect_timeout)
996    pub fn connect_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
997        self.inner.connect_timeout(timeout)
998    }
999
1000    /// Same as [`Easy2::ip_resolve`](struct.Easy2.html#method.ip_resolve)
1001    pub fn ip_resolve(&mut self, resolve: IpResolve) -> Result<(), Error> {
1002        self.inner.ip_resolve(resolve)
1003    }
1004
1005    /// Same as [`Easy2::resolve`](struct.Easy2.html#method.resolve)
1006    pub fn resolve(&mut self, list: List) -> Result<(), Error> {
1007        self.inner.resolve(list)
1008    }
1009
1010    /// Same as [`Easy2::connect_only`](struct.Easy2.html#method.connect_only)
1011    pub fn connect_only(&mut self, enable: bool) -> Result<(), Error> {
1012        self.inner.connect_only(enable)
1013    }
1014
1015    // =========================================================================
1016    // SSL/Security Options
1017
1018    /// Same as [`Easy2::ssl_cert`](struct.Easy2.html#method.ssl_cert)
1019    pub fn ssl_cert<P: AsRef<Path>>(&mut self, cert: P) -> Result<(), Error> {
1020        self.inner.ssl_cert(cert)
1021    }
1022
1023    /// Same as [`Easy2::ssl_cert_blob`](struct.Easy2.html#method.ssl_cert_blob)
1024    pub fn ssl_cert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1025        self.inner.ssl_cert_blob(blob)
1026    }
1027
1028    /// Same as [`Easy2::ssl_cert_type`](struct.Easy2.html#method.ssl_cert_type)
1029    pub fn ssl_cert_type(&mut self, kind: &str) -> Result<(), Error> {
1030        self.inner.ssl_cert_type(kind)
1031    }
1032
1033    /// Same as [`Easy2::ssl_key`](struct.Easy2.html#method.ssl_key)
1034    pub fn ssl_key<P: AsRef<Path>>(&mut self, key: P) -> Result<(), Error> {
1035        self.inner.ssl_key(key)
1036    }
1037
1038    /// Same as [`Easy2::ssl_key_blob`](struct.Easy2.html#method.ssl_key_blob)
1039    pub fn ssl_key_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1040        self.inner.ssl_key_blob(blob)
1041    }
1042
1043    /// Same as [`Easy2::ssl_key_type`](struct.Easy2.html#method.ssl_key_type)
1044    pub fn ssl_key_type(&mut self, kind: &str) -> Result<(), Error> {
1045        self.inner.ssl_key_type(kind)
1046    }
1047
1048    /// Same as [`Easy2::key_password`](struct.Easy2.html#method.key_password)
1049    pub fn key_password(&mut self, password: &str) -> Result<(), Error> {
1050        self.inner.key_password(password)
1051    }
1052
1053    /// Same as [`Easy2::ssl_cainfo_blob`](struct.Easy2.html#method.ssl_cainfo_blob)
1054    pub fn ssl_cainfo_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1055        self.inner.ssl_cainfo_blob(blob)
1056    }
1057
1058    /// Same as [`Easy2::proxy_ssl_cainfo_blob`](struct.Easy2.html#method.proxy_ssl_cainfo_blob)
1059    pub fn proxy_ssl_cainfo_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1060        self.inner.proxy_ssl_cainfo_blob(blob)
1061    }
1062
1063    /// Same as [`Easy2::ssl_engine`](struct.Easy2.html#method.ssl_engine)
1064    pub fn ssl_engine(&mut self, engine: &str) -> Result<(), Error> {
1065        self.inner.ssl_engine(engine)
1066    }
1067
1068    /// Same as [`Easy2::ssl_engine_default`](struct.Easy2.html#method.ssl_engine_default)
1069    pub fn ssl_engine_default(&mut self, enable: bool) -> Result<(), Error> {
1070        self.inner.ssl_engine_default(enable)
1071    }
1072
1073    /// Same as [`Easy2::http_version`](struct.Easy2.html#method.http_version)
1074    pub fn http_version(&mut self, version: HttpVersion) -> Result<(), Error> {
1075        self.inner.http_version(version)
1076    }
1077
1078    /// Same as [`Easy2::ssl_version`](struct.Easy2.html#method.ssl_version)
1079    pub fn ssl_version(&mut self, version: SslVersion) -> Result<(), Error> {
1080        self.inner.ssl_version(version)
1081    }
1082
1083    /// Same as [`Easy2::proxy_ssl_version`](struct.Easy2.html#method.proxy_ssl_version)
1084    pub fn proxy_ssl_version(&mut self, version: SslVersion) -> Result<(), Error> {
1085        self.inner.proxy_ssl_version(version)
1086    }
1087
1088    /// Same as [`Easy2::ssl_min_max_version`](struct.Easy2.html#method.ssl_min_max_version)
1089    pub fn ssl_min_max_version(
1090        &mut self,
1091        min_version: SslVersion,
1092        max_version: SslVersion,
1093    ) -> Result<(), Error> {
1094        self.inner.ssl_min_max_version(min_version, max_version)
1095    }
1096
1097    /// Same as [`Easy2::proxy_ssl_min_max_version`](struct.Easy2.html#method.proxy_ssl_min_max_version)
1098    pub fn proxy_ssl_min_max_version(
1099        &mut self,
1100        min_version: SslVersion,
1101        max_version: SslVersion,
1102    ) -> Result<(), Error> {
1103        self.inner
1104            .proxy_ssl_min_max_version(min_version, max_version)
1105    }
1106
1107    /// Same as [`Easy2::ssl_verify_host`](struct.Easy2.html#method.ssl_verify_host)
1108    pub fn ssl_verify_host(&mut self, verify: bool) -> Result<(), Error> {
1109        self.inner.ssl_verify_host(verify)
1110    }
1111
1112    /// Same as [`Easy2::proxy_ssl_verify_host`](struct.Easy2.html#method.proxy_ssl_verify_host)
1113    pub fn proxy_ssl_verify_host(&mut self, verify: bool) -> Result<(), Error> {
1114        self.inner.proxy_ssl_verify_host(verify)
1115    }
1116
1117    /// Same as [`Easy2::ssl_verify_peer`](struct.Easy2.html#method.ssl_verify_peer)
1118    pub fn ssl_verify_peer(&mut self, verify: bool) -> Result<(), Error> {
1119        self.inner.ssl_verify_peer(verify)
1120    }
1121
1122    /// Same as [`Easy2::proxy_ssl_verify_peer`](struct.Easy2.html#method.proxy_ssl_verify_peer)
1123    pub fn proxy_ssl_verify_peer(&mut self, verify: bool) -> Result<(), Error> {
1124        self.inner.proxy_ssl_verify_peer(verify)
1125    }
1126
1127    /// Same as [`Easy2::cainfo`](struct.Easy2.html#method.cainfo)
1128    pub fn cainfo<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1129        self.inner.cainfo(path)
1130    }
1131
1132    /// Same as [`Easy2::issuer_cert`](struct.Easy2.html#method.issuer_cert)
1133    pub fn issuer_cert<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1134        self.inner.issuer_cert(path)
1135    }
1136
1137    /// Same as [`Easy2::proxy_issuer_cert`](struct.Easy2.html#method.proxy_issuer_cert)
1138    pub fn proxy_issuer_cert<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1139        self.inner.proxy_issuer_cert(path)
1140    }
1141
1142    /// Same as [`Easy2::issuer_cert_blob`](struct.Easy2.html#method.issuer_cert_blob)
1143    pub fn issuer_cert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1144        self.inner.issuer_cert_blob(blob)
1145    }
1146
1147    /// Same as [`Easy2::proxy_issuer_cert_blob`](struct.Easy2.html#method.proxy_issuer_cert_blob)
1148    pub fn proxy_issuer_cert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1149        self.inner.proxy_issuer_cert_blob(blob)
1150    }
1151
1152    /// Same as [`Easy2::capath`](struct.Easy2.html#method.capath)
1153    pub fn capath<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1154        self.inner.capath(path)
1155    }
1156
1157    /// Same as [`Easy2::crlfile`](struct.Easy2.html#method.crlfile)
1158    pub fn crlfile<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1159        self.inner.crlfile(path)
1160    }
1161
1162    /// Same as [`Easy2::proxy_crlfile`](struct.Easy2.html#method.proxy_crlfile)
1163    pub fn proxy_crlfile<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1164        self.inner.proxy_crlfile(path)
1165    }
1166
1167    /// Same as [`Easy2::certinfo`](struct.Easy2.html#method.certinfo)
1168    pub fn certinfo(&mut self, enable: bool) -> Result<(), Error> {
1169        self.inner.certinfo(enable)
1170    }
1171
1172    /// Same as [`Easy2::random_file`](struct.Easy2.html#method.random_file)
1173    pub fn random_file<P: AsRef<Path>>(&mut self, p: P) -> Result<(), Error> {
1174        self.inner.random_file(p)
1175    }
1176
1177    /// Same as [`Easy2::egd_socket`](struct.Easy2.html#method.egd_socket)
1178    pub fn egd_socket<P: AsRef<Path>>(&mut self, p: P) -> Result<(), Error> {
1179        self.inner.egd_socket(p)
1180    }
1181
1182    /// Same as [`Easy2::ssl_cipher_list`](struct.Easy2.html#method.ssl_cipher_list)
1183    pub fn ssl_cipher_list(&mut self, ciphers: &str) -> Result<(), Error> {
1184        self.inner.ssl_cipher_list(ciphers)
1185    }
1186
1187    /// Same as [`Easy2::proxy_ssl_cipher_list`](struct.Easy2.html#method.proxy_ssl_cipher_list)
1188    pub fn proxy_ssl_cipher_list(&mut self, ciphers: &str) -> Result<(), Error> {
1189        self.inner.proxy_ssl_cipher_list(ciphers)
1190    }
1191
1192    /// Same as [`Easy2::ssl_sessionid_cache`](struct.Easy2.html#method.ssl_sessionid_cache)
1193    pub fn ssl_sessionid_cache(&mut self, enable: bool) -> Result<(), Error> {
1194        self.inner.ssl_sessionid_cache(enable)
1195    }
1196
1197    /// Same as [`Easy2::ssl_options`](struct.Easy2.html#method.ssl_options)
1198    pub fn ssl_options(&mut self, bits: &SslOpt) -> Result<(), Error> {
1199        self.inner.ssl_options(bits)
1200    }
1201
1202    /// Same as [`Easy2::proxy_ssl_options`](struct.Easy2.html#method.proxy_ssl_options)
1203    pub fn proxy_ssl_options(&mut self, bits: &SslOpt) -> Result<(), Error> {
1204        self.inner.proxy_ssl_options(bits)
1205    }
1206
1207    /// Same as [`Easy2::pinned_public_key`](struct.Easy2.html#method.pinned_public_key)
1208    pub fn pinned_public_key(&mut self, pubkey: &str) -> Result<(), Error> {
1209        self.inner.pinned_public_key(pubkey)
1210    }
1211
1212    // =========================================================================
1213    // getters
1214
1215    /// Same as [`Easy2::time_condition_unmet`](struct.Easy2.html#method.time_condition_unmet)
1216    pub fn time_condition_unmet(&mut self) -> Result<bool, Error> {
1217        self.inner.time_condition_unmet()
1218    }
1219
1220    /// Same as [`Easy2::effective_url`](struct.Easy2.html#method.effective_url)
1221    pub fn effective_url(&mut self) -> Result<Option<&str>, Error> {
1222        self.inner.effective_url()
1223    }
1224
1225    /// Same as [`Easy2::effective_url_bytes`](struct.Easy2.html#method.effective_url_bytes)
1226    pub fn effective_url_bytes(&mut self) -> Result<Option<&[u8]>, Error> {
1227        self.inner.effective_url_bytes()
1228    }
1229
1230    /// Same as [`Easy2::response_code`](struct.Easy2.html#method.response_code)
1231    pub fn response_code(&mut self) -> Result<u32, Error> {
1232        self.inner.response_code()
1233    }
1234
1235    /// Same as [`Easy2::http_connectcode`](struct.Easy2.html#method.http_connectcode)
1236    pub fn http_connectcode(&mut self) -> Result<u32, Error> {
1237        self.inner.http_connectcode()
1238    }
1239
1240    /// Same as [`Easy2::filetime`](struct.Easy2.html#method.filetime)
1241    pub fn filetime(&mut self) -> Result<Option<i64>, Error> {
1242        self.inner.filetime()
1243    }
1244
1245    /// Same as [`Easy2::download_size`](struct.Easy2.html#method.download_size)
1246    pub fn download_size(&mut self) -> Result<f64, Error> {
1247        self.inner.download_size()
1248    }
1249
1250    /// Same as [`Easy2::upload_size`](struct.Easy2.html#method.upload_size)
1251    pub fn upload_size(&mut self) -> Result<f64, Error> {
1252        self.inner.upload_size()
1253    }
1254
1255    /// Same as [`Easy2::content_length_download`](struct.Easy2.html#method.content_length_download)
1256    pub fn content_length_download(&mut self) -> Result<f64, Error> {
1257        self.inner.content_length_download()
1258    }
1259
1260    /// Same as [`Easy2::total_time`](struct.Easy2.html#method.total_time)
1261    pub fn total_time(&mut self) -> Result<Duration, Error> {
1262        self.inner.total_time()
1263    }
1264
1265    /// Same as [`Easy2::namelookup_time`](struct.Easy2.html#method.namelookup_time)
1266    pub fn namelookup_time(&mut self) -> Result<Duration, Error> {
1267        self.inner.namelookup_time()
1268    }
1269
1270    /// Same as [`Easy2::connect_time`](struct.Easy2.html#method.connect_time)
1271    pub fn connect_time(&mut self) -> Result<Duration, Error> {
1272        self.inner.connect_time()
1273    }
1274
1275    /// Same as [`Easy2::appconnect_time`](struct.Easy2.html#method.appconnect_time)
1276    pub fn appconnect_time(&mut self) -> Result<Duration, Error> {
1277        self.inner.appconnect_time()
1278    }
1279
1280    /// Same as [`Easy2::pretransfer_time`](struct.Easy2.html#method.pretransfer_time)
1281    pub fn pretransfer_time(&mut self) -> Result<Duration, Error> {
1282        self.inner.pretransfer_time()
1283    }
1284
1285    /// Same as [`Easy2::starttransfer_time`](struct.Easy2.html#method.starttransfer_time)
1286    pub fn starttransfer_time(&mut self) -> Result<Duration, Error> {
1287        self.inner.starttransfer_time()
1288    }
1289
1290    /// Same as [`Easy2::redirect_time`](struct.Easy2.html#method.redirect_time)
1291    pub fn redirect_time(&mut self) -> Result<Duration, Error> {
1292        self.inner.redirect_time()
1293    }
1294
1295    /// Same as [`Easy2::redirect_count`](struct.Easy2.html#method.redirect_count)
1296    pub fn redirect_count(&mut self) -> Result<u32, Error> {
1297        self.inner.redirect_count()
1298    }
1299
1300    /// Same as [`Easy2::redirect_url`](struct.Easy2.html#method.redirect_url)
1301    pub fn redirect_url(&mut self) -> Result<Option<&str>, Error> {
1302        self.inner.redirect_url()
1303    }
1304
1305    /// Same as [`Easy2::redirect_url_bytes`](struct.Easy2.html#method.redirect_url_bytes)
1306    pub fn redirect_url_bytes(&mut self) -> Result<Option<&[u8]>, Error> {
1307        self.inner.redirect_url_bytes()
1308    }
1309
1310    /// Same as [`Easy2::header_size`](struct.Easy2.html#method.header_size)
1311    pub fn header_size(&mut self) -> Result<u64, Error> {
1312        self.inner.header_size()
1313    }
1314
1315    /// Same as [`Easy2::request_size`](struct.Easy2.html#method.request_size)
1316    pub fn request_size(&mut self) -> Result<u64, Error> {
1317        self.inner.request_size()
1318    }
1319
1320    /// Same as [`Easy2::content_type`](struct.Easy2.html#method.content_type)
1321    pub fn content_type(&mut self) -> Result<Option<&str>, Error> {
1322        self.inner.content_type()
1323    }
1324
1325    /// Same as [`Easy2::content_type_bytes`](struct.Easy2.html#method.content_type_bytes)
1326    pub fn content_type_bytes(&mut self) -> Result<Option<&[u8]>, Error> {
1327        self.inner.content_type_bytes()
1328    }
1329
1330    /// Same as [`Easy2::os_errno`](struct.Easy2.html#method.os_errno)
1331    pub fn os_errno(&mut self) -> Result<i32, Error> {
1332        self.inner.os_errno()
1333    }
1334
1335    /// Same as [`Easy2::primary_ip`](struct.Easy2.html#method.primary_ip)
1336    pub fn primary_ip(&mut self) -> Result<Option<&str>, Error> {
1337        self.inner.primary_ip()
1338    }
1339
1340    /// Same as [`Easy2::primary_port`](struct.Easy2.html#method.primary_port)
1341    pub fn primary_port(&mut self) -> Result<u16, Error> {
1342        self.inner.primary_port()
1343    }
1344
1345    /// Same as [`Easy2::local_ip`](struct.Easy2.html#method.local_ip)
1346    pub fn local_ip(&mut self) -> Result<Option<&str>, Error> {
1347        self.inner.local_ip()
1348    }
1349
1350    /// Same as [`Easy2::local_port`](struct.Easy2.html#method.local_port)
1351    pub fn local_port(&mut self) -> Result<u16, Error> {
1352        self.inner.local_port()
1353    }
1354
1355    /// Same as [`Easy2::cookies`](struct.Easy2.html#method.cookies)
1356    pub fn cookies(&mut self) -> Result<List, Error> {
1357        self.inner.cookies()
1358    }
1359
1360    /// Same as [`Easy2::pipewait`](struct.Easy2.html#method.pipewait)
1361    pub fn pipewait(&mut self, wait: bool) -> Result<(), Error> {
1362        self.inner.pipewait(wait)
1363    }
1364
1365    /// Same as [`Easy2::http_09_allowed`](struct.Easy2.html#method.http_09_allowed)
1366    pub fn http_09_allowed(&mut self, allow: bool) -> Result<(), Error> {
1367        self.inner.http_09_allowed(allow)
1368    }
1369
1370    // =========================================================================
1371    // Other methods
1372
1373    /// Same as [`Easy2::perform`](struct.Easy2.html#method.perform)
1374    pub fn perform(&self) -> Result<(), Error> {
1375        assert!(self.inner.get_ref().borrowed.get().is_null());
1376        self.do_perform()
1377    }
1378
1379    fn do_perform(&self) -> Result<(), Error> {
1380        // We don't allow recursive invocations of `perform` because we're
1381        // invoking `FnMut`closures behind a `&self` pointer. This flag acts as
1382        // our own `RefCell` borrow flag sorta.
1383        if self.inner.get_ref().running.get() {
1384            return Err(Error::new(curl_sys::CURLE_FAILED_INIT));
1385        }
1386
1387        self.inner.get_ref().running.set(true);
1388        struct Reset<'a>(&'a Cell<bool>);
1389        impl<'a> Drop for Reset<'a> {
1390            fn drop(&mut self) {
1391                self.0.set(false);
1392            }
1393        }
1394        let _reset = Reset(&self.inner.get_ref().running);
1395
1396        self.inner.perform()
1397    }
1398
1399    /// Creates a new scoped transfer which can be used to set callbacks and
1400    /// data which only live for the scope of the returned object.
1401    ///
1402    /// An `Easy` handle is often reused between different requests to cache
1403    /// connections to servers, but often the lifetime of the data as part of
1404    /// each transfer is unique. This function serves as an ability to share an
1405    /// `Easy` across many transfers while ergonomically using possibly
1406    /// stack-local data as part of each transfer.
1407    ///
1408    /// Configuration can be set on the `Easy` and then a `Transfer` can be
1409    /// created to set scoped configuration (like callbacks). Finally, the
1410    /// `perform` method on the `Transfer` function can be used.
1411    ///
1412    /// When the `Transfer` option is dropped then all configuration set on the
1413    /// transfer itself will be reset.
1414    pub fn transfer<'data, 'easy>(&'easy mut self) -> Transfer<'easy, 'data> {
1415        assert!(!self.inner.get_ref().running.get());
1416        Transfer {
1417            data: Box::new(Callbacks::default()),
1418            easy: self,
1419        }
1420    }
1421
1422    /// Same as [`Easy2::upkeep`](struct.Easy2.html#method.upkeep)
1423    #[cfg(feature = "upkeep_7_62_0")]
1424    pub fn upkeep(&self) -> Result<(), Error> {
1425        self.inner.upkeep()
1426    }
1427
1428    /// Same as [`Easy2::unpause_read`](struct.Easy2.html#method.unpause_read)
1429    pub fn unpause_read(&self) -> Result<(), Error> {
1430        self.inner.unpause_read()
1431    }
1432
1433    /// Same as [`Easy2::unpause_write`](struct.Easy2.html#method.unpause_write)
1434    pub fn unpause_write(&self) -> Result<(), Error> {
1435        self.inner.unpause_write()
1436    }
1437
1438    /// Same as [`Easy2::url_encode`](struct.Easy2.html#method.url_encode)
1439    pub fn url_encode(&mut self, s: &[u8]) -> String {
1440        self.inner.url_encode(s)
1441    }
1442
1443    /// Same as [`Easy2::url_decode`](struct.Easy2.html#method.url_decode)
1444    pub fn url_decode(&mut self, s: &str) -> Vec<u8> {
1445        self.inner.url_decode(s)
1446    }
1447
1448    /// Same as [`Easy2::reset`](struct.Easy2.html#method.reset)
1449    pub fn reset(&mut self) {
1450        self.inner.reset()
1451    }
1452
1453    /// Same as [`Easy2::recv`](struct.Easy2.html#method.recv)
1454    pub fn recv(&mut self, data: &mut [u8]) -> Result<usize, Error> {
1455        self.inner.recv(data)
1456    }
1457
1458    /// Same as [`Easy2::send`](struct.Easy2.html#method.send)
1459    pub fn send(&mut self, data: &[u8]) -> Result<usize, Error> {
1460        self.inner.send(data)
1461    }
1462
1463    /// Same as [`Easy2::raw`](struct.Easy2.html#method.raw)
1464    pub fn raw(&self) -> *mut curl_sys::CURL {
1465        self.inner.raw()
1466    }
1467
1468    /// Same as [`Easy2::take_error_buf`](struct.Easy2.html#method.take_error_buf)
1469    pub fn take_error_buf(&self) -> Option<String> {
1470        self.inner.take_error_buf()
1471    }
1472}
1473
1474impl EasyData {
1475    /// An unsafe function to get the appropriate callback field.
1476    ///
1477    /// We can have callbacks configured from one of two different sources.
1478    /// We could either have a callback from the `borrowed` field, callbacks on
1479    /// an ephemeral `Transfer`, or the `owned` field which are `'static`
1480    /// callbacks that live for the lifetime of this `EasyData`.
1481    ///
1482    /// The first set of callbacks are unsafe to access because they're actually
1483    /// owned elsewhere and we're just aliasing. Additionally they don't
1484    /// technically live long enough for us to access them, so they're hidden
1485    /// behind unsafe pointers and casts.
1486    ///
1487    /// This function returns `&'a mut T` but that's actually somewhat of a lie.
1488    /// The value should **not be stored to** nor should it be used for the full
1489    /// lifetime of `'a`, but rather immediately in the local scope.
1490    ///
1491    /// Basically this is just intended to acquire a callback, invoke it, and
1492    /// then stop. Nothing else. Super unsafe.
1493    unsafe fn callback<'a, T, F>(&'a mut self, f: F) -> Option<&'a mut T>
1494    where
1495        F: for<'b> Fn(&'b mut Callbacks<'static>) -> &'b mut Option<T>,
1496    {
1497        let ptr = self.borrowed.get();
1498        if !ptr.is_null() {
1499            let val = f(&mut *ptr);
1500            if val.is_some() {
1501                return val.as_mut();
1502            }
1503        }
1504        f(&mut self.owned).as_mut()
1505    }
1506}
1507
1508impl Handler for EasyData {
1509    fn write(&mut self, data: &[u8]) -> Result<usize, WriteError> {
1510        unsafe {
1511            match self.callback(|s| &mut s.write) {
1512                Some(write) => write(data),
1513                None => Ok(data.len()),
1514            }
1515        }
1516    }
1517
1518    fn read(&mut self, data: &mut [u8]) -> Result<usize, ReadError> {
1519        unsafe {
1520            match self.callback(|s| &mut s.read) {
1521                Some(read) => read(data),
1522                None => Ok(0),
1523            }
1524        }
1525    }
1526
1527    fn seek(&mut self, whence: SeekFrom) -> SeekResult {
1528        unsafe {
1529            match self.callback(|s| &mut s.seek) {
1530                Some(seek) => seek(whence),
1531                None => SeekResult::CantSeek,
1532            }
1533        }
1534    }
1535
1536    fn debug(&mut self, kind: InfoType, data: &[u8]) {
1537        unsafe {
1538            match self.callback(|s| &mut s.debug) {
1539                Some(debug) => debug(kind, data),
1540                None => handler::debug(kind, data),
1541            }
1542        }
1543    }
1544
1545    fn header(&mut self, data: &[u8]) -> bool {
1546        unsafe {
1547            match self.callback(|s| &mut s.header) {
1548                Some(header) => header(data),
1549                None => true,
1550            }
1551        }
1552    }
1553
1554    fn progress(&mut self, dltotal: f64, dlnow: f64, ultotal: f64, ulnow: f64) -> bool {
1555        unsafe {
1556            match self.callback(|s| &mut s.progress) {
1557                Some(progress) => progress(dltotal, dlnow, ultotal, ulnow),
1558                None => true,
1559            }
1560        }
1561    }
1562
1563    fn ssl_ctx(&mut self, cx: *mut c_void) -> Result<(), Error> {
1564        unsafe {
1565            match self.callback(|s| &mut s.ssl_ctx) {
1566                Some(ssl_ctx) => ssl_ctx(cx),
1567                None => handler::ssl_ctx(cx),
1568            }
1569        }
1570    }
1571}
1572
1573impl fmt::Debug for EasyData {
1574    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1575        "callbacks ...".fmt(f)
1576    }
1577}
1578
1579impl<'easy, 'data> Transfer<'easy, 'data> {
1580    /// Same as `Easy::write_function`, just takes a non `'static` lifetime
1581    /// corresponding to the lifetime of this transfer.
1582    pub fn write_function<F>(&mut self, f: F) -> Result<(), Error>
1583    where
1584        F: FnMut(&[u8]) -> Result<usize, WriteError> + 'data,
1585    {
1586        self.data.write = Some(Box::new(f));
1587        Ok(())
1588    }
1589
1590    /// Same as `Easy::read_function`, just takes a non `'static` lifetime
1591    /// corresponding to the lifetime of this transfer.
1592    pub fn read_function<F>(&mut self, f: F) -> Result<(), Error>
1593    where
1594        F: FnMut(&mut [u8]) -> Result<usize, ReadError> + 'data,
1595    {
1596        self.data.read = Some(Box::new(f));
1597        Ok(())
1598    }
1599
1600    /// Same as `Easy::seek_function`, just takes a non `'static` lifetime
1601    /// corresponding to the lifetime of this transfer.
1602    pub fn seek_function<F>(&mut self, f: F) -> Result<(), Error>
1603    where
1604        F: FnMut(SeekFrom) -> SeekResult + 'data,
1605    {
1606        self.data.seek = Some(Box::new(f));
1607        Ok(())
1608    }
1609
1610    /// Same as `Easy::progress_function`, just takes a non `'static` lifetime
1611    /// corresponding to the lifetime of this transfer.
1612    pub fn progress_function<F>(&mut self, f: F) -> Result<(), Error>
1613    where
1614        F: FnMut(f64, f64, f64, f64) -> bool + 'data,
1615    {
1616        self.data.progress = Some(Box::new(f));
1617        Ok(())
1618    }
1619
1620    /// Same as `Easy::ssl_ctx_function`, just takes a non `'static`
1621    /// lifetime corresponding to the lifetime of this transfer.
1622    pub fn ssl_ctx_function<F>(&mut self, f: F) -> Result<(), Error>
1623    where
1624        F: FnMut(*mut c_void) -> Result<(), Error> + Send + 'data,
1625    {
1626        self.data.ssl_ctx = Some(Box::new(f));
1627        Ok(())
1628    }
1629
1630    /// Same as `Easy::debug_function`, just takes a non `'static` lifetime
1631    /// corresponding to the lifetime of this transfer.
1632    pub fn debug_function<F>(&mut self, f: F) -> Result<(), Error>
1633    where
1634        F: FnMut(InfoType, &[u8]) + 'data,
1635    {
1636        self.data.debug = Some(Box::new(f));
1637        Ok(())
1638    }
1639
1640    /// Same as `Easy::header_function`, just takes a non `'static` lifetime
1641    /// corresponding to the lifetime of this transfer.
1642    pub fn header_function<F>(&mut self, f: F) -> Result<(), Error>
1643    where
1644        F: FnMut(&[u8]) -> bool + 'data,
1645    {
1646        self.data.header = Some(Box::new(f));
1647        Ok(())
1648    }
1649
1650    /// Same as `Easy::perform`.
1651    pub fn perform(&self) -> Result<(), Error> {
1652        let inner = self.easy.inner.get_ref();
1653
1654        // Note that we're casting a `&self` pointer to a `*mut`, and then
1655        // during the invocation of this call we're going to invoke `FnMut`
1656        // closures that we ourselves own.
1657        //
1658        // This should be ok, however, because `do_perform` checks for recursive
1659        // invocations of `perform` and disallows them. Our type also isn't
1660        // `Sync`.
1661        inner.borrowed.set(&*self.data as *const _ as *mut _);
1662
1663        // Make sure to reset everything back to the way it was before when
1664        // we're done.
1665        struct Reset<'a>(&'a Cell<*mut Callbacks<'static>>);
1666        impl<'a> Drop for Reset<'a> {
1667            fn drop(&mut self) {
1668                self.0.set(ptr::null_mut());
1669            }
1670        }
1671        let _reset = Reset(&inner.borrowed);
1672
1673        self.easy.do_perform()
1674    }
1675
1676    /// Same as `Easy::upkeep`
1677    #[cfg(feature = "upkeep_7_62_0")]
1678    pub fn upkeep(&self) -> Result<(), Error> {
1679        self.easy.upkeep()
1680    }
1681
1682    /// Same as `Easy::unpause_read`.
1683    pub fn unpause_read(&self) -> Result<(), Error> {
1684        self.easy.unpause_read()
1685    }
1686
1687    /// Same as `Easy::unpause_write`
1688    pub fn unpause_write(&self) -> Result<(), Error> {
1689        self.easy.unpause_write()
1690    }
1691}
1692
1693impl<'easy, 'data> fmt::Debug for Transfer<'easy, 'data> {
1694    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1695        f.debug_struct("Transfer")
1696            .field("easy", &self.easy)
1697            .finish()
1698    }
1699}
1700
1701impl<'easy, 'data> Drop for Transfer<'easy, 'data> {
1702    fn drop(&mut self) {
1703        // Extra double check to make sure we don't leak a pointer to ourselves.
1704        assert!(self.easy.inner.get_ref().borrowed.get().is_null());
1705    }
1706}