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