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