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