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 curl_sys;
10use libc::c_void;
11
12use crate::easy::handler::{self, InfoType, ReadError, SeekResult, WriteError};
13use crate::easy::handler::{Auth, NetRc, ProxyType, SslOpt};
14use crate::easy::handler::{HttpVersion, IpResolve, SslVersion, TimeCondition};
15use crate::easy::{Easy2, Handler};
16use crate::easy::{Form, List};
17use crate::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)]
78pub 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.
93pub struct Transfer<'easy, 'data> {
94 easy: &'easy mut Easy,
95 data: Box<Callbacks<'data>>,
96}
97
98pub struct EasyData {
99 running: Cell<bool>,
100 owned: Callbacks<'static>,
101 borrowed: Cell<*mut Callbacks<'static>>,
102}
103
104unsafe impl Send for EasyData {}
105
106#[derive(Default)]
107struct 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
117impl 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.
125 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)
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)
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)
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)
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)
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)
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)
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 /// ```
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 /// ```
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.
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.
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.
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.
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 /// ```
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)
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)
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)
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)
562 pub fn connect_to(&mut self, list: List) -> Result<(), Error> {
563 self.inner.connect_to(list)
564 }
565
566 /// Same as [`Easy2::path_as_is`](struct.Easy2.html#method.path_as_is)
567 pub fn path_as_is(&mut self, as_is: bool) -> Result<(), Error> {
568 self.inner.path_as_is(as_is)
569 }
570
571 /// Same as [`Easy2::proxy`](struct.Easy2.html#method.proxy)
572 pub fn proxy(&mut self, url: &str) -> Result<(), Error> {
573 self.inner.proxy(url)
574 }
575
576 /// Same as [`Easy2::proxy_port`](struct.Easy2.html#method.proxy_port)
577 pub fn proxy_port(&mut self, port: u16) -> Result<(), Error> {
578 self.inner.proxy_port(port)
579 }
580
581 /// Same as [`Easy2::proxy_cainfo`](struct.Easy2.html#method.proxy_cainfo)
582 pub fn proxy_cainfo(&mut self, cainfo: &str) -> Result<(), Error> {
583 self.inner.proxy_cainfo(cainfo)
584 }
585
586 /// Same as [`Easy2::proxy_capath`](struct.Easy2.html#method.proxy_capath)
587 pub fn proxy_capath<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
588 self.inner.proxy_capath(path)
589 }
590
591 /// Same as [`Easy2::proxy_sslcert`](struct.Easy2.html#method.proxy_sslcert)
592 pub fn proxy_sslcert(&mut self, sslcert: &str) -> Result<(), Error> {
593 self.inner.proxy_sslcert(sslcert)
594 }
595
596 /// Same as [`Easy2::proxy_sslcert_type`](struct.Easy2.html#method.proxy_sslcert_type)
597 pub fn proxy_sslcert_type(&mut self, kind: &str) -> Result<(), Error> {
598 self.inner.proxy_sslcert_type(kind)
599 }
600
601 /// Same as [`Easy2::proxy_sslcert_blob`](struct.Easy2.html#method.proxy_sslcert_blob)
602 pub fn proxy_sslcert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
603 self.inner.proxy_sslcert_blob(blob)
604 }
605
606 /// Same as [`Easy2::proxy_sslkey`](struct.Easy2.html#method.proxy_sslkey)
607 pub fn proxy_sslkey(&mut self, sslkey: &str) -> Result<(), Error> {
608 self.inner.proxy_sslkey(sslkey)
609 }
610
611 /// Same as [`Easy2::proxy_sslkey_type`](struct.Easy2.html#method.proxy_sslkey_type)
612 pub fn proxy_sslkey_type(&mut self, kind: &str) -> Result<(), Error> {
613 self.inner.proxy_sslkey_type(kind)
614 }
615
616 /// Same as [`Easy2::proxy_sslkey_blob`](struct.Easy2.html#method.proxy_sslkey_blob)
617 pub fn proxy_sslkey_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
618 self.inner.proxy_sslkey_blob(blob)
619 }
620
621 /// Same as [`Easy2::proxy_key_password`](struct.Easy2.html#method.proxy_key_password)
622 pub fn proxy_key_password(&mut self, password: &str) -> Result<(), Error> {
623 self.inner.proxy_key_password(password)
624 }
625
626 /// Same as [`Easy2::proxy_type`](struct.Easy2.html#method.proxy_type)
627 pub fn proxy_type(&mut self, kind: ProxyType) -> Result<(), Error> {
628 self.inner.proxy_type(kind)
629 }
630
631 /// Same as [`Easy2::noproxy`](struct.Easy2.html#method.noproxy)
632 pub fn noproxy(&mut self, skip: &str) -> Result<(), Error> {
633 self.inner.noproxy(skip)
634 }
635
636 /// Same as [`Easy2::http_proxy_tunnel`](struct.Easy2.html#method.http_proxy_tunnel)
637 pub fn http_proxy_tunnel(&mut self, tunnel: bool) -> Result<(), Error> {
638 self.inner.http_proxy_tunnel(tunnel)
639 }
640
641 /// Same as [`Easy2::interface`](struct.Easy2.html#method.interface)
642 pub fn interface(&mut self, interface: &str) -> Result<(), Error> {
643 self.inner.interface(interface)
644 }
645
646 /// Same as [`Easy2::set_local_port`](struct.Easy2.html#method.set_local_port)
647 pub fn set_local_port(&mut self, port: u16) -> Result<(), Error> {
648 self.inner.set_local_port(port)
649 }
650
651 /// Same as [`Easy2::local_port_range`](struct.Easy2.html#method.local_port_range)
652 pub fn local_port_range(&mut self, range: u16) -> Result<(), Error> {
653 self.inner.local_port_range(range)
654 }
655
656 /// Same as [`Easy2::dns_servers`](struct.Easy2.html#method.dns_servers)
657 pub fn dns_servers(&mut self, servers: &str) -> Result<(), Error> {
658 self.inner.dns_servers(servers)
659 }
660
661 /// Same as [`Easy2::dns_cache_timeout`](struct.Easy2.html#method.dns_cache_timeout)
662 pub fn dns_cache_timeout(&mut self, dur: Duration) -> Result<(), Error> {
663 self.inner.dns_cache_timeout(dur)
664 }
665
666 /// Same as [`Easy2::doh_url`](struct.Easy2.html#method.doh_url)
667 pub fn doh_url(&mut self, url: Option<&str>) -> Result<(), Error> {
668 self.inner.doh_url(url)
669 }
670
671 /// Same as [`Easy2::doh_ssl_verify_peer`](struct.Easy2.html#method.doh_ssl_verify_peer)
672 pub fn doh_ssl_verify_peer(&mut self, verify: bool) -> Result<(), Error> {
673 self.inner.doh_ssl_verify_peer(verify)
674 }
675
676 /// Same as [`Easy2::doh_ssl_verify_host`](struct.Easy2.html#method.doh_ssl_verify_host)
677 pub fn doh_ssl_verify_host(&mut self, verify: bool) -> Result<(), Error> {
678 self.inner.doh_ssl_verify_host(verify)
679 }
680
681 /// Same as [`Easy2::doh_ssl_verify_status`](struct.Easy2.html#method.doh_ssl_verify_status)
682 pub fn doh_ssl_verify_status(&mut self, verify: bool) -> Result<(), Error> {
683 self.inner.doh_ssl_verify_status(verify)
684 }
685
686 /// Same as [`Easy2::buffer_size`](struct.Easy2.html#method.buffer_size)
687 pub fn buffer_size(&mut self, size: usize) -> Result<(), Error> {
688 self.inner.buffer_size(size)
689 }
690
691 /// Same as [`Easy2::upload_buffer_size`](struct.Easy2.html#method.upload_buffer_size)
692 pub fn upload_buffer_size(&mut self, size: usize) -> Result<(), Error> {
693 self.inner.upload_buffer_size(size)
694 }
695
696 /// Same as [`Easy2::tcp_nodelay`](struct.Easy2.html#method.tcp_nodelay)
697 pub fn tcp_nodelay(&mut self, enable: bool) -> Result<(), Error> {
698 self.inner.tcp_nodelay(enable)
699 }
700
701 /// Same as [`Easy2::tcp_keepalive`](struct.Easy2.html#method.tcp_keepalive)
702 pub fn tcp_keepalive(&mut self, enable: bool) -> Result<(), Error> {
703 self.inner.tcp_keepalive(enable)
704 }
705
706 /// Same as [`Easy2::tcp_keepintvl`](struct.Easy2.html#method.tcp_keepalive)
707 pub fn tcp_keepintvl(&mut self, dur: Duration) -> Result<(), Error> {
708 self.inner.tcp_keepintvl(dur)
709 }
710
711 /// Same as [`Easy2::tcp_keepidle`](struct.Easy2.html#method.tcp_keepidle)
712 pub fn tcp_keepidle(&mut self, dur: Duration) -> Result<(), Error> {
713 self.inner.tcp_keepidle(dur)
714 }
715
716 /// Same as [`Easy2::address_scope`](struct.Easy2.html#method.address_scope)
717 pub fn address_scope(&mut self, scope: u32) -> Result<(), Error> {
718 self.inner.address_scope(scope)
719 }
720
721 // =========================================================================
722 // Names and passwords
723
724 /// Same as [`Easy2::username`](struct.Easy2.html#method.username)
725 pub fn username(&mut self, user: &str) -> Result<(), Error> {
726 self.inner.username(user)
727 }
728
729 /// Same as [`Easy2::password`](struct.Easy2.html#method.password)
730 pub fn password(&mut self, pass: &str) -> Result<(), Error> {
731 self.inner.password(pass)
732 }
733
734 /// Same as [`Easy2::http_auth`](struct.Easy2.html#method.http_auth)
735 pub fn http_auth(&mut self, auth: &Auth) -> Result<(), Error> {
736 self.inner.http_auth(auth)
737 }
738
739 /// Same as [`Easy2::aws_sigv4`](struct.Easy2.html#method.aws_sigv4)
740 pub fn aws_sigv4(&mut self, param: &str) -> Result<(), Error> {
741 self.inner.aws_sigv4(param)
742 }
743
744 /// Same as [`Easy2::proxy_username`](struct.Easy2.html#method.proxy_username)
745 pub fn proxy_username(&mut self, user: &str) -> Result<(), Error> {
746 self.inner.proxy_username(user)
747 }
748
749 /// Same as [`Easy2::proxy_password`](struct.Easy2.html#method.proxy_password)
750 pub fn proxy_password(&mut self, pass: &str) -> Result<(), Error> {
751 self.inner.proxy_password(pass)
752 }
753
754 /// Same as [`Easy2::proxy_auth`](struct.Easy2.html#method.proxy_auth)
755 pub fn proxy_auth(&mut self, auth: &Auth) -> Result<(), Error> {
756 self.inner.proxy_auth(auth)
757 }
758
759 /// Same as [`Easy2::netrc`](struct.Easy2.html#method.netrc)
760 pub fn netrc(&mut self, netrc: NetRc) -> Result<(), Error> {
761 self.inner.netrc(netrc)
762 }
763
764 // =========================================================================
765 // HTTP Options
766
767 /// Same as [`Easy2::autoreferer`](struct.Easy2.html#method.autoreferer)
768 pub fn autoreferer(&mut self, enable: bool) -> Result<(), Error> {
769 self.inner.autoreferer(enable)
770 }
771
772 /// Same as [`Easy2::accept_encoding`](struct.Easy2.html#method.accept_encoding)
773 pub fn accept_encoding(&mut self, encoding: &str) -> Result<(), Error> {
774 self.inner.accept_encoding(encoding)
775 }
776
777 /// Same as [`Easy2::transfer_encoding`](struct.Easy2.html#method.transfer_encoding)
778 pub fn transfer_encoding(&mut self, enable: bool) -> Result<(), Error> {
779 self.inner.transfer_encoding(enable)
780 }
781
782 /// Same as [`Easy2::follow_location`](struct.Easy2.html#method.follow_location)
783 pub fn follow_location(&mut self, enable: bool) -> Result<(), Error> {
784 self.inner.follow_location(enable)
785 }
786
787 /// Same as [`Easy2::unrestricted_auth`](struct.Easy2.html#method.unrestricted_auth)
788 pub fn unrestricted_auth(&mut self, enable: bool) -> Result<(), Error> {
789 self.inner.unrestricted_auth(enable)
790 }
791
792 /// Same as [`Easy2::max_redirections`](struct.Easy2.html#method.max_redirections)
793 pub fn max_redirections(&mut self, max: u32) -> Result<(), Error> {
794 self.inner.max_redirections(max)
795 }
796
797 /// Same as [`Easy2::put`](struct.Easy2.html#method.put)
798 pub fn put(&mut self, enable: bool) -> Result<(), Error> {
799 self.inner.put(enable)
800 }
801
802 /// Same as [`Easy2::post`](struct.Easy2.html#method.post)
803 pub fn post(&mut self, enable: bool) -> Result<(), Error> {
804 self.inner.post(enable)
805 }
806
807 /// Same as [`Easy2::post_field_copy`](struct.Easy2.html#method.post_field_copy)
808 pub fn post_fields_copy(&mut self, data: &[u8]) -> Result<(), Error> {
809 self.inner.post_fields_copy(data)
810 }
811
812 /// Same as [`Easy2::post_field_size`](struct.Easy2.html#method.post_field_size)
813 pub fn post_field_size(&mut self, size: u64) -> Result<(), Error> {
814 self.inner.post_field_size(size)
815 }
816
817 /// Same as [`Easy2::httppost`](struct.Easy2.html#method.httppost)
818 pub fn httppost(&mut self, form: Form) -> Result<(), Error> {
819 self.inner.httppost(form)
820 }
821
822 /// Same as [`Easy2::referer`](struct.Easy2.html#method.referer)
823 pub fn referer(&mut self, referer: &str) -> Result<(), Error> {
824 self.inner.referer(referer)
825 }
826
827 /// Same as [`Easy2::useragent`](struct.Easy2.html#method.useragent)
828 pub fn useragent(&mut self, useragent: &str) -> Result<(), Error> {
829 self.inner.useragent(useragent)
830 }
831
832 /// Same as [`Easy2::http_headers`](struct.Easy2.html#method.http_headers)
833 pub fn http_headers(&mut self, list: List) -> Result<(), Error> {
834 self.inner.http_headers(list)
835 }
836
837 /// Same as [`Easy2::cookie`](struct.Easy2.html#method.cookie)
838 pub fn cookie(&mut self, cookie: &str) -> Result<(), Error> {
839 self.inner.cookie(cookie)
840 }
841
842 /// Same as [`Easy2::cookie_file`](struct.Easy2.html#method.cookie_file)
843 pub fn cookie_file<P: AsRef<Path>>(&mut self, file: P) -> Result<(), Error> {
844 self.inner.cookie_file(file)
845 }
846
847 /// Same as [`Easy2::cookie_jar`](struct.Easy2.html#method.cookie_jar)
848 pub fn cookie_jar<P: AsRef<Path>>(&mut self, file: P) -> Result<(), Error> {
849 self.inner.cookie_jar(file)
850 }
851
852 /// Same as [`Easy2::cookie_session`](struct.Easy2.html#method.cookie_session)
853 pub fn cookie_session(&mut self, session: bool) -> Result<(), Error> {
854 self.inner.cookie_session(session)
855 }
856
857 /// Same as [`Easy2::cookie_list`](struct.Easy2.html#method.cookie_list)
858 pub fn cookie_list(&mut self, cookie: &str) -> Result<(), Error> {
859 self.inner.cookie_list(cookie)
860 }
861
862 /// Same as [`Easy2::get`](struct.Easy2.html#method.get)
863 pub fn get(&mut self, enable: bool) -> Result<(), Error> {
864 self.inner.get(enable)
865 }
866
867 /// Same as [`Easy2::ignore_content_length`](struct.Easy2.html#method.ignore_content_length)
868 pub fn ignore_content_length(&mut self, ignore: bool) -> Result<(), Error> {
869 self.inner.ignore_content_length(ignore)
870 }
871
872 /// Same as [`Easy2::http_content_decoding`](struct.Easy2.html#method.http_content_decoding)
873 pub fn http_content_decoding(&mut self, enable: bool) -> Result<(), Error> {
874 self.inner.http_content_decoding(enable)
875 }
876
877 /// Same as [`Easy2::http_transfer_decoding`](struct.Easy2.html#method.http_transfer_decoding)
878 pub fn http_transfer_decoding(&mut self, enable: bool) -> Result<(), Error> {
879 self.inner.http_transfer_decoding(enable)
880 }
881
882 // =========================================================================
883 // Protocol Options
884
885 /// Same as [`Easy2::range`](struct.Easy2.html#method.range)
886 pub fn range(&mut self, range: &str) -> Result<(), Error> {
887 self.inner.range(range)
888 }
889
890 /// Same as [`Easy2::resume_from`](struct.Easy2.html#method.resume_from)
891 pub fn resume_from(&mut self, from: u64) -> Result<(), Error> {
892 self.inner.resume_from(from)
893 }
894
895 /// Same as [`Easy2::custom_request`](struct.Easy2.html#method.custom_request)
896 pub fn custom_request(&mut self, request: &str) -> Result<(), Error> {
897 self.inner.custom_request(request)
898 }
899
900 /// Same as [`Easy2::fetch_filetime`](struct.Easy2.html#method.fetch_filetime)
901 pub fn fetch_filetime(&mut self, fetch: bool) -> Result<(), Error> {
902 self.inner.fetch_filetime(fetch)
903 }
904
905 /// Same as [`Easy2::nobody`](struct.Easy2.html#method.nobody)
906 pub fn nobody(&mut self, enable: bool) -> Result<(), Error> {
907 self.inner.nobody(enable)
908 }
909
910 /// Same as [`Easy2::in_filesize`](struct.Easy2.html#method.in_filesize)
911 pub fn in_filesize(&mut self, size: u64) -> Result<(), Error> {
912 self.inner.in_filesize(size)
913 }
914
915 /// Same as [`Easy2::upload`](struct.Easy2.html#method.upload)
916 pub fn upload(&mut self, enable: bool) -> Result<(), Error> {
917 self.inner.upload(enable)
918 }
919
920 /// Same as [`Easy2::max_filesize`](struct.Easy2.html#method.max_filesize)
921 pub fn max_filesize(&mut self, size: u64) -> Result<(), Error> {
922 self.inner.max_filesize(size)
923 }
924
925 /// Same as [`Easy2::time_condition`](struct.Easy2.html#method.time_condition)
926 pub fn time_condition(&mut self, cond: TimeCondition) -> Result<(), Error> {
927 self.inner.time_condition(cond)
928 }
929
930 /// Same as [`Easy2::time_value`](struct.Easy2.html#method.time_value)
931 pub fn time_value(&mut self, val: i64) -> Result<(), Error> {
932 self.inner.time_value(val)
933 }
934
935 // =========================================================================
936 // Connection Options
937
938 /// Same as [`Easy2::timeout`](struct.Easy2.html#method.timeout)
939 pub fn timeout(&mut self, timeout: Duration) -> Result<(), Error> {
940 self.inner.timeout(timeout)
941 }
942
943 /// Same as [`Easy2::low_speed_limit`](struct.Easy2.html#method.low_speed_limit)
944 pub fn low_speed_limit(&mut self, limit: u32) -> Result<(), Error> {
945 self.inner.low_speed_limit(limit)
946 }
947
948 /// Same as [`Easy2::low_speed_time`](struct.Easy2.html#method.low_speed_time)
949 pub fn low_speed_time(&mut self, dur: Duration) -> Result<(), Error> {
950 self.inner.low_speed_time(dur)
951 }
952
953 /// Same as [`Easy2::max_send_speed`](struct.Easy2.html#method.max_send_speed)
954 pub fn max_send_speed(&mut self, speed: u64) -> Result<(), Error> {
955 self.inner.max_send_speed(speed)
956 }
957
958 /// Same as [`Easy2::max_recv_speed`](struct.Easy2.html#method.max_recv_speed)
959 pub fn max_recv_speed(&mut self, speed: u64) -> Result<(), Error> {
960 self.inner.max_recv_speed(speed)
961 }
962
963 /// Same as [`Easy2::max_connects`](struct.Easy2.html#method.max_connects)
964 pub fn max_connects(&mut self, max: u32) -> Result<(), Error> {
965 self.inner.max_connects(max)
966 }
967
968 /// Same as [`Easy2::maxage_conn`](struct.Easy2.html#method.maxage_conn)
969 pub fn maxage_conn(&mut self, max_age: Duration) -> Result<(), Error> {
970 self.inner.maxage_conn(max_age)
971 }
972
973 /// Same as [`Easy2::fresh_connect`](struct.Easy2.html#method.fresh_connect)
974 pub fn fresh_connect(&mut self, enable: bool) -> Result<(), Error> {
975 self.inner.fresh_connect(enable)
976 }
977
978 /// Same as [`Easy2::forbid_reuse`](struct.Easy2.html#method.forbid_reuse)
979 pub fn forbid_reuse(&mut self, enable: bool) -> Result<(), Error> {
980 self.inner.forbid_reuse(enable)
981 }
982
983 /// Same as [`Easy2::connect_timeout`](struct.Easy2.html#method.connect_timeout)
984 pub fn connect_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
985 self.inner.connect_timeout(timeout)
986 }
987
988 /// Same as [`Easy2::ip_resolve`](struct.Easy2.html#method.ip_resolve)
989 pub fn ip_resolve(&mut self, resolve: IpResolve) -> Result<(), Error> {
990 self.inner.ip_resolve(resolve)
991 }
992
993 /// Same as [`Easy2::resolve`](struct.Easy2.html#method.resolve)
994 pub fn resolve(&mut self, list: List) -> Result<(), Error> {
995 self.inner.resolve(list)
996 }
997
998 /// Same as [`Easy2::connect_only`](struct.Easy2.html#method.connect_only)
999 pub fn connect_only(&mut self, enable: bool) -> Result<(), Error> {
1000 self.inner.connect_only(enable)
1001 }
1002
1003 // =========================================================================
1004 // SSL/Security Options
1005
1006 /// Same as [`Easy2::ssl_cert`](struct.Easy2.html#method.ssl_cert)
1007 pub fn ssl_cert<P: AsRef<Path>>(&mut self, cert: P) -> Result<(), Error> {
1008 self.inner.ssl_cert(cert)
1009 }
1010
1011 /// Same as [`Easy2::ssl_cert_blob`](struct.Easy2.html#method.ssl_cert_blob)
1012 pub fn ssl_cert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1013 self.inner.ssl_cert_blob(blob)
1014 }
1015
1016 /// Same as [`Easy2::ssl_cert_type`](struct.Easy2.html#method.ssl_cert_type)
1017 pub fn ssl_cert_type(&mut self, kind: &str) -> Result<(), Error> {
1018 self.inner.ssl_cert_type(kind)
1019 }
1020
1021 /// Same as [`Easy2::ssl_key`](struct.Easy2.html#method.ssl_key)
1022 pub fn ssl_key<P: AsRef<Path>>(&mut self, key: P) -> Result<(), Error> {
1023 self.inner.ssl_key(key)
1024 }
1025
1026 /// Same as [`Easy2::ssl_key_blob`](struct.Easy2.html#method.ssl_key_blob)
1027 pub fn ssl_key_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1028 self.inner.ssl_key_blob(blob)
1029 }
1030
1031 /// Same as [`Easy2::ssl_key_type`](struct.Easy2.html#method.ssl_key_type)
1032 pub fn ssl_key_type(&mut self, kind: &str) -> Result<(), Error> {
1033 self.inner.ssl_key_type(kind)
1034 }
1035
1036 /// Same as [`Easy2::key_password`](struct.Easy2.html#method.key_password)
1037 pub fn key_password(&mut self, password: &str) -> Result<(), Error> {
1038 self.inner.key_password(password)
1039 }
1040
1041 /// Same as [`Easy2::ssl_cainfo_blob`](struct.Easy2.html#method.ssl_cainfo_blob)
1042 pub fn ssl_cainfo_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1043 self.inner.ssl_cainfo_blob(blob)
1044 }
1045
1046 /// Same as [`Easy2::proxy_ssl_cainfo_blob`](struct.Easy2.html#method.proxy_ssl_cainfo_blob)
1047 pub fn proxy_ssl_cainfo_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1048 self.inner.proxy_ssl_cainfo_blob(blob)
1049 }
1050
1051 /// Same as [`Easy2::ssl_engine`](struct.Easy2.html#method.ssl_engine)
1052 pub fn ssl_engine(&mut self, engine: &str) -> Result<(), Error> {
1053 self.inner.ssl_engine(engine)
1054 }
1055
1056 /// Same as [`Easy2::ssl_engine_default`](struct.Easy2.html#method.ssl_engine_default)
1057 pub fn ssl_engine_default(&mut self, enable: bool) -> Result<(), Error> {
1058 self.inner.ssl_engine_default(enable)
1059 }
1060
1061 /// Same as [`Easy2::http_version`](struct.Easy2.html#method.http_version)
1062 pub fn http_version(&mut self, version: HttpVersion) -> Result<(), Error> {
1063 self.inner.http_version(version)
1064 }
1065
1066 /// Same as [`Easy2::ssl_version`](struct.Easy2.html#method.ssl_version)
1067 pub fn ssl_version(&mut self, version: SslVersion) -> Result<(), Error> {
1068 self.inner.ssl_version(version)
1069 }
1070
1071 /// Same as [`Easy2::proxy_ssl_version`](struct.Easy2.html#method.proxy_ssl_version)
1072 pub fn proxy_ssl_version(&mut self, version: SslVersion) -> Result<(), Error> {
1073 self.inner.proxy_ssl_version(version)
1074 }
1075
1076 /// Same as [`Easy2::ssl_min_max_version`](struct.Easy2.html#method.ssl_min_max_version)
1077 pub fn ssl_min_max_version(
1078 &mut self,
1079 min_version: SslVersion,
1080 max_version: SslVersion,
1081 ) -> Result<(), Error> {
1082 self.inner.ssl_min_max_version(min_version, max_version)
1083 }
1084
1085 /// Same as [`Easy2::proxy_ssl_min_max_version`](struct.Easy2.html#method.proxy_ssl_min_max_version)
1086 pub fn proxy_ssl_min_max_version(
1087 &mut self,
1088 min_version: SslVersion,
1089 max_version: SslVersion,
1090 ) -> Result<(), Error> {
1091 self.inner
1092 .proxy_ssl_min_max_version(min_version, max_version)
1093 }
1094
1095 /// Same as [`Easy2::ssl_verify_host`](struct.Easy2.html#method.ssl_verify_host)
1096 pub fn ssl_verify_host(&mut self, verify: bool) -> Result<(), Error> {
1097 self.inner.ssl_verify_host(verify)
1098 }
1099
1100 /// Same as [`Easy2::proxy_ssl_verify_host`](struct.Easy2.html#method.proxy_ssl_verify_host)
1101 pub fn proxy_ssl_verify_host(&mut self, verify: bool) -> Result<(), Error> {
1102 self.inner.proxy_ssl_verify_host(verify)
1103 }
1104
1105 /// Same as [`Easy2::ssl_verify_peer`](struct.Easy2.html#method.ssl_verify_peer)
1106 pub fn ssl_verify_peer(&mut self, verify: bool) -> Result<(), Error> {
1107 self.inner.ssl_verify_peer(verify)
1108 }
1109
1110 /// Same as [`Easy2::proxy_ssl_verify_peer`](struct.Easy2.html#method.proxy_ssl_verify_peer)
1111 pub fn proxy_ssl_verify_peer(&mut self, verify: bool) -> Result<(), Error> {
1112 self.inner.proxy_ssl_verify_peer(verify)
1113 }
1114
1115 /// Same as [`Easy2::cainfo`](struct.Easy2.html#method.cainfo)
1116 pub fn cainfo<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1117 self.inner.cainfo(path)
1118 }
1119
1120 /// Same as [`Easy2::issuer_cert`](struct.Easy2.html#method.issuer_cert)
1121 pub fn issuer_cert<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1122 self.inner.issuer_cert(path)
1123 }
1124
1125 /// Same as [`Easy2::proxy_issuer_cert`](struct.Easy2.html#method.proxy_issuer_cert)
1126 pub fn proxy_issuer_cert<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1127 self.inner.proxy_issuer_cert(path)
1128 }
1129
1130 /// Same as [`Easy2::issuer_cert_blob`](struct.Easy2.html#method.issuer_cert_blob)
1131 pub fn issuer_cert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1132 self.inner.issuer_cert_blob(blob)
1133 }
1134
1135 /// Same as [`Easy2::proxy_issuer_cert_blob`](struct.Easy2.html#method.proxy_issuer_cert_blob)
1136 pub fn proxy_issuer_cert_blob(&mut self, blob: &[u8]) -> Result<(), Error> {
1137 self.inner.proxy_issuer_cert_blob(blob)
1138 }
1139
1140 /// Same as [`Easy2::capath`](struct.Easy2.html#method.capath)
1141 pub fn capath<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1142 self.inner.capath(path)
1143 }
1144
1145 /// Same as [`Easy2::crlfile`](struct.Easy2.html#method.crlfile)
1146 pub fn crlfile<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1147 self.inner.crlfile(path)
1148 }
1149
1150 /// Same as [`Easy2::proxy_crlfile`](struct.Easy2.html#method.proxy_crlfile)
1151 pub fn proxy_crlfile<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
1152 self.inner.proxy_crlfile(path)
1153 }
1154
1155 /// Same as [`Easy2::certinfo`](struct.Easy2.html#method.certinfo)
1156 pub fn certinfo(&mut self, enable: bool) -> Result<(), Error> {
1157 self.inner.certinfo(enable)
1158 }
1159
1160 /// Same as [`Easy2::random_file`](struct.Easy2.html#method.random_file)
1161 pub fn random_file<P: AsRef<Path>>(&mut self, p: P) -> Result<(), Error> {
1162 self.inner.random_file(p)
1163 }
1164
1165 /// Same as [`Easy2::egd_socket`](struct.Easy2.html#method.egd_socket)
1166 pub fn egd_socket<P: AsRef<Path>>(&mut self, p: P) -> Result<(), Error> {
1167 self.inner.egd_socket(p)
1168 }
1169
1170 /// Same as [`Easy2::ssl_cipher_list`](struct.Easy2.html#method.ssl_cipher_list)
1171 pub fn ssl_cipher_list(&mut self, ciphers: &str) -> Result<(), Error> {
1172 self.inner.ssl_cipher_list(ciphers)
1173 }
1174
1175 /// Same as [`Easy2::proxy_ssl_cipher_list`](struct.Easy2.html#method.proxy_ssl_cipher_list)
1176 pub fn proxy_ssl_cipher_list(&mut self, ciphers: &str) -> Result<(), Error> {
1177 self.inner.proxy_ssl_cipher_list(ciphers)
1178 }
1179
1180 /// Same as [`Easy2::ssl_sessionid_cache`](struct.Easy2.html#method.ssl_sessionid_cache)
1181 pub fn ssl_sessionid_cache(&mut self, enable: bool) -> Result<(), Error> {
1182 self.inner.ssl_sessionid_cache(enable)
1183 }
1184
1185 /// Same as [`Easy2::ssl_options`](struct.Easy2.html#method.ssl_options)
1186 pub fn ssl_options(&mut self, bits: &SslOpt) -> Result<(), Error> {
1187 self.inner.ssl_options(bits)
1188 }
1189
1190 /// Same as [`Easy2::proxy_ssl_options`](struct.Easy2.html#method.proxy_ssl_options)
1191 pub fn proxy_ssl_options(&mut self, bits: &SslOpt) -> Result<(), Error> {
1192 self.inner.proxy_ssl_options(bits)
1193 }
1194
1195 /// Same as [`Easy2::pinned_public_key`](struct.Easy2.html#method.pinned_public_key)
1196 pub fn pinned_public_key(&mut self, pubkey: &str) -> Result<(), Error> {
1197 self.inner.pinned_public_key(pubkey)
1198 }
1199
1200 // =========================================================================
1201 // getters
1202
1203 /// Same as [`Easy2::time_condition_unmet`](struct.Easy2.html#method.time_condition_unmet)
1204 pub fn time_condition_unmet(&mut self) -> Result<bool, Error> {
1205 self.inner.time_condition_unmet()
1206 }
1207
1208 /// Same as [`Easy2::effective_url`](struct.Easy2.html#method.effective_url)
1209 pub fn effective_url(&mut self) -> Result<Option<&str>, Error> {
1210 self.inner.effective_url()
1211 }
1212
1213 /// Same as [`Easy2::effective_url_bytes`](struct.Easy2.html#method.effective_url_bytes)
1214 pub fn effective_url_bytes(&mut self) -> Result<Option<&[u8]>, Error> {
1215 self.inner.effective_url_bytes()
1216 }
1217
1218 /// Same as [`Easy2::response_code`](struct.Easy2.html#method.response_code)
1219 pub fn response_code(&mut self) -> Result<u32, Error> {
1220 self.inner.response_code()
1221 }
1222
1223 /// Same as [`Easy2::http_connectcode`](struct.Easy2.html#method.http_connectcode)
1224 pub fn http_connectcode(&mut self) -> Result<u32, Error> {
1225 self.inner.http_connectcode()
1226 }
1227
1228 /// Same as [`Easy2::filetime`](struct.Easy2.html#method.filetime)
1229 pub fn filetime(&mut self) -> Result<Option<i64>, Error> {
1230 self.inner.filetime()
1231 }
1232
1233 /// Same as [`Easy2::download_size`](struct.Easy2.html#method.download_size)
1234 pub fn download_size(&mut self) -> Result<f64, Error> {
1235 self.inner.download_size()
1236 }
1237
1238 /// Same as [`Easy2::upload_size`](struct.Easy2.html#method.upload_size)
1239 pub fn upload_size(&mut self) -> Result<f64, Error> {
1240 self.inner.upload_size()
1241 }
1242
1243 /// Same as [`Easy2::content_length_download`](struct.Easy2.html#method.content_length_download)
1244 pub fn content_length_download(&mut self) -> Result<f64, Error> {
1245 self.inner.content_length_download()
1246 }
1247
1248 /// Same as [`Easy2::total_time`](struct.Easy2.html#method.total_time)
1249 pub fn total_time(&mut self) -> Result<Duration, Error> {
1250 self.inner.total_time()
1251 }
1252
1253 /// Same as [`Easy2::namelookup_time`](struct.Easy2.html#method.namelookup_time)
1254 pub fn namelookup_time(&mut self) -> Result<Duration, Error> {
1255 self.inner.namelookup_time()
1256 }
1257
1258 /// Same as [`Easy2::connect_time`](struct.Easy2.html#method.connect_time)
1259 pub fn connect_time(&mut self) -> Result<Duration, Error> {
1260 self.inner.connect_time()
1261 }
1262
1263 /// Same as [`Easy2::appconnect_time`](struct.Easy2.html#method.appconnect_time)
1264 pub fn appconnect_time(&mut self) -> Result<Duration, Error> {
1265 self.inner.appconnect_time()
1266 }
1267
1268 /// Same as [`Easy2::pretransfer_time`](struct.Easy2.html#method.pretransfer_time)
1269 pub fn pretransfer_time(&mut self) -> Result<Duration, Error> {
1270 self.inner.pretransfer_time()
1271 }
1272
1273 /// Same as [`Easy2::starttransfer_time`](struct.Easy2.html#method.starttransfer_time)
1274 pub fn starttransfer_time(&mut self) -> Result<Duration, Error> {
1275 self.inner.starttransfer_time()
1276 }
1277
1278 /// Same as [`Easy2::redirect_time`](struct.Easy2.html#method.redirect_time)
1279 pub fn redirect_time(&mut self) -> Result<Duration, Error> {
1280 self.inner.redirect_time()
1281 }
1282
1283 /// Same as [`Easy2::redirect_count`](struct.Easy2.html#method.redirect_count)
1284 pub fn redirect_count(&mut self) -> Result<u32, Error> {
1285 self.inner.redirect_count()
1286 }
1287
1288 /// Same as [`Easy2::redirect_url`](struct.Easy2.html#method.redirect_url)
1289 pub fn redirect_url(&mut self) -> Result<Option<&str>, Error> {
1290 self.inner.redirect_url()
1291 }
1292
1293 /// Same as [`Easy2::redirect_url_bytes`](struct.Easy2.html#method.redirect_url_bytes)
1294 pub fn redirect_url_bytes(&mut self) -> Result<Option<&[u8]>, Error> {
1295 self.inner.redirect_url_bytes()
1296 }
1297
1298 /// Same as [`Easy2::header_size`](struct.Easy2.html#method.header_size)
1299 pub fn header_size(&mut self) -> Result<u64, Error> {
1300 self.inner.header_size()
1301 }
1302
1303 /// Same as [`Easy2::request_size`](struct.Easy2.html#method.request_size)
1304 pub fn request_size(&mut self) -> Result<u64, Error> {
1305 self.inner.request_size()
1306 }
1307
1308 /// Same as [`Easy2::content_type`](struct.Easy2.html#method.content_type)
1309 pub fn content_type(&mut self) -> Result<Option<&str>, Error> {
1310 self.inner.content_type()
1311 }
1312
1313 /// Same as [`Easy2::content_type_bytes`](struct.Easy2.html#method.content_type_bytes)
1314 pub fn content_type_bytes(&mut self) -> Result<Option<&[u8]>, Error> {
1315 self.inner.content_type_bytes()
1316 }
1317
1318 /// Same as [`Easy2::os_errno`](struct.Easy2.html#method.os_errno)
1319 pub fn os_errno(&mut self) -> Result<i32, Error> {
1320 self.inner.os_errno()
1321 }
1322
1323 /// Same as [`Easy2::primary_ip`](struct.Easy2.html#method.primary_ip)
1324 pub fn primary_ip(&mut self) -> Result<Option<&str>, Error> {
1325 self.inner.primary_ip()
1326 }
1327
1328 /// Same as [`Easy2::primary_port`](struct.Easy2.html#method.primary_port)
1329 pub fn primary_port(&mut self) -> Result<u16, Error> {
1330 self.inner.primary_port()
1331 }
1332
1333 /// Same as [`Easy2::local_ip`](struct.Easy2.html#method.local_ip)
1334 pub fn local_ip(&mut self) -> Result<Option<&str>, Error> {
1335 self.inner.local_ip()
1336 }
1337
1338 /// Same as [`Easy2::local_port`](struct.Easy2.html#method.local_port)
1339 pub fn local_port(&mut self) -> Result<u16, Error> {
1340 self.inner.local_port()
1341 }
1342
1343 /// Same as [`Easy2::cookies`](struct.Easy2.html#method.cookies)
1344 pub fn cookies(&mut self) -> Result<List, Error> {
1345 self.inner.cookies()
1346 }
1347
1348 /// Same as [`Easy2::pipewait`](struct.Easy2.html#method.pipewait)
1349 pub fn pipewait(&mut self, wait: bool) -> Result<(), Error> {
1350 self.inner.pipewait(wait)
1351 }
1352
1353 /// Same as [`Easy2::http_09_allowed`](struct.Easy2.html#method.http_09_allowed)
1354 pub fn http_09_allowed(&mut self, allow: bool) -> Result<(), Error> {
1355 self.inner.http_09_allowed(allow)
1356 }
1357
1358 // =========================================================================
1359 // Other methods
1360
1361 /// Same as [`Easy2::perform`](struct.Easy2.html#method.perform)
1362 pub fn perform(&self) -> Result<(), Error> {
1363 assert!(self.inner.get_ref().borrowed.get().is_null());
1364 self.do_perform()
1365 }
1366
1367 fn do_perform(&self) -> Result<(), Error> {
1368 // We don't allow recursive invocations of `perform` because we're
1369 // invoking `FnMut`closures behind a `&self` pointer. This flag acts as
1370 // our own `RefCell` borrow flag sorta.
1371 if self.inner.get_ref().running.get() {
1372 return Err(Error::new(curl_sys::CURLE_FAILED_INIT));
1373 }
1374
1375 self.inner.get_ref().running.set(true);
1376 struct Reset<'a>(&'a Cell<bool>);
1377 impl<'a> Drop for Reset<'a> {
1378 fn drop(&mut self) {
1379 self.0.set(false);
1380 }
1381 }
1382 let _reset = Reset(&self.inner.get_ref().running);
1383
1384 self.inner.perform()
1385 }
1386
1387 /// Creates a new scoped transfer which can be used to set callbacks and
1388 /// data which only live for the scope of the returned object.
1389 ///
1390 /// An `Easy` handle is often reused between different requests to cache
1391 /// connections to servers, but often the lifetime of the data as part of
1392 /// each transfer is unique. This function serves as an ability to share an
1393 /// `Easy` across many transfers while ergonomically using possibly
1394 /// stack-local data as part of each transfer.
1395 ///
1396 /// Configuration can be set on the `Easy` and then a `Transfer` can be
1397 /// created to set scoped configuration (like callbacks). Finally, the
1398 /// `perform` method on the `Transfer` function can be used.
1399 ///
1400 /// When the `Transfer` option is dropped then all configuration set on the
1401 /// transfer itself will be reset.
1402 pub fn transfer<'data, 'easy>(&'easy mut self) -> Transfer<'easy, 'data> {
1403 assert!(!self.inner.get_ref().running.get());
1404 Transfer {
1405 data: Box::new(Callbacks::default()),
1406 easy: self,
1407 }
1408 }
1409
1410 /// Same as [`Easy2::upkeep`](struct.Easy2.html#method.upkeep)
1411 #[cfg(feature = "upkeep_7_62_0")]
1412 pub fn upkeep(&self) -> Result<(), Error> {
1413 self.inner.upkeep()
1414 }
1415
1416 /// Same as [`Easy2::unpause_read`](struct.Easy2.html#method.unpause_read)
1417 pub fn unpause_read(&self) -> Result<(), Error> {
1418 self.inner.unpause_read()
1419 }
1420
1421 /// Same as [`Easy2::unpause_write`](struct.Easy2.html#method.unpause_write)
1422 pub fn unpause_write(&self) -> Result<(), Error> {
1423 self.inner.unpause_write()
1424 }
1425
1426 /// Same as [`Easy2::url_encode`](struct.Easy2.html#method.url_encode)
1427 pub fn url_encode(&mut self, s: &[u8]) -> String {
1428 self.inner.url_encode(s)
1429 }
1430
1431 /// Same as [`Easy2::url_decode`](struct.Easy2.html#method.url_decode)
1432 pub fn url_decode(&mut self, s: &str) -> Vec<u8> {
1433 self.inner.url_decode(s)
1434 }
1435
1436 /// Same as [`Easy2::reset`](struct.Easy2.html#method.reset)
1437 pub fn reset(&mut self) {
1438 self.inner.reset()
1439 }
1440
1441 /// Same as [`Easy2::recv`](struct.Easy2.html#method.recv)
1442 pub fn recv(&mut self, data: &mut [u8]) -> Result<usize, Error> {
1443 self.inner.recv(data)
1444 }
1445
1446 /// Same as [`Easy2::send`](struct.Easy2.html#method.send)
1447 pub fn send(&mut self, data: &[u8]) -> Result<usize, Error> {
1448 self.inner.send(data)
1449 }
1450
1451 /// Same as [`Easy2::raw`](struct.Easy2.html#method.raw)
1452 pub fn raw(&self) -> *mut curl_sys::CURL {
1453 self.inner.raw()
1454 }
1455
1456 /// Same as [`Easy2::take_error_buf`](struct.Easy2.html#method.take_error_buf)
1457 pub fn take_error_buf(&self) -> Option<String> {
1458 self.inner.take_error_buf()
1459 }
1460}
1461
1462impl EasyData {
1463 /// An unsafe function to get the appropriate callback field.
1464 ///
1465 /// We can have callbacks configured from one of two different sources.
1466 /// We could either have a callback from the `borrowed` field, callbacks on
1467 /// an ephemeral `Transfer`, or the `owned` field which are `'static`
1468 /// callbacks that live for the lifetime of this `EasyData`.
1469 ///
1470 /// The first set of callbacks are unsafe to access because they're actually
1471 /// owned elsewhere and we're just aliasing. Additionally they don't
1472 /// technically live long enough for us to access them, so they're hidden
1473 /// behind unsafe pointers and casts.
1474 ///
1475 /// This function returns `&'a mut T` but that's actually somewhat of a lie.
1476 /// The value should **not be stored to** nor should it be used for the full
1477 /// lifetime of `'a`, but rather immediately in the local scope.
1478 ///
1479 /// Basically this is just intended to acquire a callback, invoke it, and
1480 /// then stop. Nothing else. Super unsafe.
1481 unsafe fn callback<'a, T, F>(&'a mut self, f: F) -> Option<&'a mut T>
1482 where
1483 F: for<'b> Fn(&'b mut Callbacks<'static>) -> &'b mut Option<T>,
1484 {
1485 let ptr = self.borrowed.get();
1486 if !ptr.is_null() {
1487 let val = f(&mut *ptr);
1488 if val.is_some() {
1489 return val.as_mut();
1490 }
1491 }
1492 f(&mut self.owned).as_mut()
1493 }
1494}
1495
1496impl Handler for EasyData {
1497 fn write(&mut self, data: &[u8]) -> Result<usize, WriteError> {
1498 unsafe {
1499 match self.callback(|s| &mut s.write) {
1500 Some(write) => write(data),
1501 None => Ok(data.len()),
1502 }
1503 }
1504 }
1505
1506 fn read(&mut self, data: &mut [u8]) -> Result<usize, ReadError> {
1507 unsafe {
1508 match self.callback(|s| &mut s.read) {
1509 Some(read) => read(data),
1510 None => Ok(0),
1511 }
1512 }
1513 }
1514
1515 fn seek(&mut self, whence: SeekFrom) -> SeekResult {
1516 unsafe {
1517 match self.callback(|s| &mut s.seek) {
1518 Some(seek) => seek(whence),
1519 None => SeekResult::CantSeek,
1520 }
1521 }
1522 }
1523
1524 fn debug(&mut self, kind: InfoType, data: &[u8]) {
1525 unsafe {
1526 match self.callback(|s| &mut s.debug) {
1527 Some(debug) => debug(kind, data),
1528 None => handler::debug(kind, data),
1529 }
1530 }
1531 }
1532
1533 fn header(&mut self, data: &[u8]) -> bool {
1534 unsafe {
1535 match self.callback(|s| &mut s.header) {
1536 Some(header) => header(data),
1537 None => true,
1538 }
1539 }
1540 }
1541
1542 fn progress(&mut self, dltotal: f64, dlnow: f64, ultotal: f64, ulnow: f64) -> bool {
1543 unsafe {
1544 match self.callback(|s| &mut s.progress) {
1545 Some(progress) => progress(dltotal, dlnow, ultotal, ulnow),
1546 None => true,
1547 }
1548 }
1549 }
1550
1551 fn ssl_ctx(&mut self, cx: *mut c_void) -> Result<(), Error> {
1552 unsafe {
1553 match self.callback(|s| &mut s.ssl_ctx) {
1554 Some(ssl_ctx) => ssl_ctx(cx),
1555 None => handler::ssl_ctx(cx),
1556 }
1557 }
1558 }
1559}
1560
1561impl fmt::Debug for EasyData {
1562 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1563 "callbacks ...".fmt(f)
1564 }
1565}
1566
1567impl<'easy, 'data> Transfer<'easy, 'data> {
1568 /// Same as `Easy::write_function`, just takes a non `'static` lifetime
1569 /// corresponding to the lifetime of this transfer.
1570 pub fn write_function<F>(&mut self, f: F) -> Result<(), Error>
1571 where
1572 F: FnMut(&[u8]) -> Result<usize, WriteError> + 'data,
1573 {
1574 self.data.write = Some(Box::new(f));
1575 Ok(())
1576 }
1577
1578 /// Same as `Easy::read_function`, just takes a non `'static` lifetime
1579 /// corresponding to the lifetime of this transfer.
1580 pub fn read_function<F>(&mut self, f: F) -> Result<(), Error>
1581 where
1582 F: FnMut(&mut [u8]) -> Result<usize, ReadError> + 'data,
1583 {
1584 self.data.read = Some(Box::new(f));
1585 Ok(())
1586 }
1587
1588 /// Same as `Easy::seek_function`, just takes a non `'static` lifetime
1589 /// corresponding to the lifetime of this transfer.
1590 pub fn seek_function<F>(&mut self, f: F) -> Result<(), Error>
1591 where
1592 F: FnMut(SeekFrom) -> SeekResult + 'data,
1593 {
1594 self.data.seek = Some(Box::new(f));
1595 Ok(())
1596 }
1597
1598 /// Same as `Easy::progress_function`, just takes a non `'static` lifetime
1599 /// corresponding to the lifetime of this transfer.
1600 pub fn progress_function<F>(&mut self, f: F) -> Result<(), Error>
1601 where
1602 F: FnMut(f64, f64, f64, f64) -> bool + 'data,
1603 {
1604 self.data.progress = Some(Box::new(f));
1605 Ok(())
1606 }
1607
1608 /// Same as `Easy::ssl_ctx_function`, just takes a non `'static`
1609 /// lifetime corresponding to the lifetime of this transfer.
1610 pub fn ssl_ctx_function<F>(&mut self, f: F) -> Result<(), Error>
1611 where
1612 F: FnMut(*mut c_void) -> Result<(), Error> + Send + 'data,
1613 {
1614 self.data.ssl_ctx = Some(Box::new(f));
1615 Ok(())
1616 }
1617
1618 /// Same as `Easy::debug_function`, just takes a non `'static` lifetime
1619 /// corresponding to the lifetime of this transfer.
1620 pub fn debug_function<F>(&mut self, f: F) -> Result<(), Error>
1621 where
1622 F: FnMut(InfoType, &[u8]) + 'data,
1623 {
1624 self.data.debug = Some(Box::new(f));
1625 Ok(())
1626 }
1627
1628 /// Same as `Easy::header_function`, just takes a non `'static` lifetime
1629 /// corresponding to the lifetime of this transfer.
1630 pub fn header_function<F>(&mut self, f: F) -> Result<(), Error>
1631 where
1632 F: FnMut(&[u8]) -> bool + 'data,
1633 {
1634 self.data.header = Some(Box::new(f));
1635 Ok(())
1636 }
1637
1638 /// Same as `Easy::perform`.
1639 pub fn perform(&self) -> Result<(), Error> {
1640 let inner = self.easy.inner.get_ref();
1641
1642 // Note that we're casting a `&self` pointer to a `*mut`, and then
1643 // during the invocation of this call we're going to invoke `FnMut`
1644 // closures that we ourselves own.
1645 //
1646 // This should be ok, however, because `do_perform` checks for recursive
1647 // invocations of `perform` and disallows them. Our type also isn't
1648 // `Sync`.
1649 inner.borrowed.set(&*self.data as *const _ as *mut _);
1650
1651 // Make sure to reset everything back to the way it was before when
1652 // we're done.
1653 struct Reset<'a>(&'a Cell<*mut Callbacks<'static>>);
1654 impl<'a> Drop for Reset<'a> {
1655 fn drop(&mut self) {
1656 self.0.set(ptr::null_mut());
1657 }
1658 }
1659 let _reset = Reset(&inner.borrowed);
1660
1661 self.easy.do_perform()
1662 }
1663
1664 /// Same as `Easy::upkeep`
1665 #[cfg(feature = "upkeep_7_62_0")]
1666 pub fn upkeep(&self) -> Result<(), Error> {
1667 self.easy.upkeep()
1668 }
1669
1670 /// Same as `Easy::unpause_read`.
1671 pub fn unpause_read(&self) -> Result<(), Error> {
1672 self.easy.unpause_read()
1673 }
1674
1675 /// Same as `Easy::unpause_write`
1676 pub fn unpause_write(&self) -> Result<(), Error> {
1677 self.easy.unpause_write()
1678 }
1679}
1680
1681impl<'easy, 'data> fmt::Debug for Transfer<'easy, 'data> {
1682 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1683 f&mut DebugStruct<'_, '_>.debug_struct("Transfer")
1684 .field(name:"easy", &self.easy)
1685 .finish()
1686 }
1687}
1688
1689impl<'easy, 'data> Drop for Transfer<'easy, 'data> {
1690 fn drop(&mut self) {
1691 // Extra double check to make sure we don't leak a pointer to ourselves.
1692 assert!(self.easy.inner.get_ref().borrowed.get().is_null());
1693 }
1694}
1695