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}