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