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 | |