From 1e7c0b1d89c8e4f1d00749e918a2662bee5b21e7 Mon Sep 17 00:00:00 2001 From: Julian Scheid Date: Sun, 17 Nov 2024 10:35:21 +0100 Subject: [PATCH] Add function into_inner to Easy and Easy2 (#586) --- src/easy/handler.rs | 97 +++++++++++++++++++++++++++++++-------------- src/multi.rs | 5 +++ 2 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/easy/handler.rs b/src/easy/handler.rs index 7be38450e..d0172e05b 100644 --- a/src/easy/handler.rs +++ b/src/easy/handler.rs @@ -379,8 +379,12 @@ pub struct Easy2 { inner: Box>, } +/// A thin wrapper around a low-level Easy handle that performs +/// cleanup when dropped. +struct CURLPtr(*mut curl_sys::CURL); + struct Inner { - handle: *mut curl_sys::CURL, + handle: CURLPtr, header_list: Option, resolve_list: Option, connect_to_list: Option, @@ -590,7 +594,7 @@ impl Easy2 { assert!(!handle.is_null()); let mut ret = Easy2 { inner: Box::new(Inner { - handle, + handle: CURLPtr(handle), header_list: None, resolve_list: None, connect_to_list: None, @@ -611,7 +615,7 @@ impl Easy2 { /// cache, the dns cache, and cookies. pub fn reset(&mut self) { unsafe { - curl_sys::curl_easy_reset(self.inner.handle); + curl_sys::curl_easy_reset(self.inner.handle.as_ptr()); } self.default_configure(); } @@ -838,6 +842,11 @@ impl Easy2 { &mut self.inner.handler } + /// Consumes the Easy handle, returning the underlying handler. + pub fn into_inner(self) -> H { + self.inner.handler + } + // ========================================================================= // Error options @@ -3119,7 +3128,7 @@ impl Easy2 { unsafe { let mut list = ptr::null_mut(); let rc = curl_sys::curl_easy_getinfo( - self.inner.handle, + self.inner.handle.as_ptr(), curl_sys::CURLINFO_COOKIELIST, &mut list, ); @@ -3189,7 +3198,7 @@ impl Easy2 { /// call methods like `unpause_write` and `unpause_read` while a transfer is /// in progress. pub fn perform(&self) -> Result<(), Error> { - let ret = unsafe { self.cvt(curl_sys::curl_easy_perform(self.inner.handle)) }; + let ret = unsafe { self.cvt(curl_sys::curl_easy_perform(self.inner.handle.as_ptr())) }; panic::propagate(); ret } @@ -3204,7 +3213,7 @@ impl Easy2 { /// called, an HTTP/2 PING frame is sent on the connection. #[cfg(feature = "upkeep_7_62_0")] pub fn upkeep(&self) -> Result<(), Error> { - let ret = unsafe { self.cvt(curl_sys::curl_easy_upkeep(self.inner.handle)) }; + let ret = unsafe { self.cvt(curl_sys::curl_easy_upkeep(self.inner.handle.as_ptr())) }; panic::propagate(); return ret; } @@ -3225,7 +3234,10 @@ impl Easy2 { /// this function returns. pub fn unpause_read(&self) -> Result<(), Error> { unsafe { - let rc = curl_sys::curl_easy_pause(self.inner.handle, curl_sys::CURLPAUSE_RECV_CONT); + let rc = curl_sys::curl_easy_pause( + self.inner.handle.as_ptr(), + curl_sys::CURLPAUSE_RECV_CONT, + ); self.cvt(rc) } } @@ -3246,7 +3258,10 @@ impl Easy2 { /// paused. pub fn unpause_write(&self) -> Result<(), Error> { unsafe { - let rc = curl_sys::curl_easy_pause(self.inner.handle, curl_sys::CURLPAUSE_SEND_CONT); + let rc = curl_sys::curl_easy_pause( + self.inner.handle.as_ptr(), + curl_sys::CURLPAUSE_SEND_CONT, + ); self.cvt(rc) } } @@ -3258,7 +3273,7 @@ impl Easy2 { } unsafe { let p = curl_sys::curl_easy_escape( - self.inner.handle, + self.inner.handle.as_ptr(), s.as_ptr() as *const _, s.len() as c_int, ); @@ -3291,7 +3306,7 @@ impl Easy2 { unsafe { let mut len = 0; let p = curl_sys::curl_easy_unescape( - self.inner.handle, + self.inner.handle.as_ptr(), s.as_ptr() as *const _, orig_len as c_int, &mut len, @@ -3340,7 +3355,7 @@ impl Easy2 { unsafe { let mut n = 0; let r = curl_sys::curl_easy_recv( - self.inner.handle, + self.inner.handle.as_ptr(), data.as_mut_ptr() as *mut _, data.len(), &mut n, @@ -3361,7 +3376,7 @@ impl Easy2 { unsafe { let mut n = 0; let rc = curl_sys::curl_easy_send( - self.inner.handle, + self.inner.handle.as_ptr(), data.as_ptr() as *const _, data.len(), &mut n, @@ -3373,7 +3388,7 @@ impl Easy2 { /// Get a pointer to the raw underlying CURL handle. pub fn raw(&self) -> *mut curl_sys::CURL { - self.inner.handle + self.inner.handle.as_ptr() } #[cfg(unix)] @@ -3392,7 +3407,13 @@ impl Easy2 { } fn setopt_long(&mut self, opt: curl_sys::CURLoption, val: c_long) -> Result<(), Error> { - unsafe { self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, val)) } + unsafe { + self.cvt(curl_sys::curl_easy_setopt( + self.inner.handle.as_ptr(), + opt, + val, + )) + } } fn setopt_str(&mut self, opt: curl_sys::CURLoption, val: &CStr) -> Result<(), Error> { @@ -3400,7 +3421,13 @@ impl Easy2 { } fn setopt_ptr(&self, opt: curl_sys::CURLoption, val: *const c_char) -> Result<(), Error> { - unsafe { self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, val)) } + unsafe { + self.cvt(curl_sys::curl_easy_setopt( + self.inner.handle.as_ptr(), + opt, + val, + )) + } } fn setopt_off_t( @@ -3409,7 +3436,7 @@ impl Easy2 { val: curl_sys::curl_off_t, ) -> Result<(), Error> { unsafe { - let rc = curl_sys::curl_easy_setopt(self.inner.handle, opt, val); + let rc = curl_sys::curl_easy_setopt(self.inner.handle.as_ptr(), opt, val); self.cvt(rc) } } @@ -3421,7 +3448,13 @@ impl Easy2 { flags: curl_sys::CURL_BLOB_COPY, }; let blob_ptr = &blob as *const curl_sys::curl_blob; - unsafe { self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, blob_ptr)) } + unsafe { + self.cvt(curl_sys::curl_easy_setopt( + self.inner.handle.as_ptr(), + opt, + blob_ptr, + )) + } } fn getopt_bytes(&self, opt: curl_sys::CURLINFO) -> Result, Error> { @@ -3438,7 +3471,7 @@ impl Easy2 { fn getopt_ptr(&self, opt: curl_sys::CURLINFO) -> Result<*const c_char, Error> { unsafe { let mut p = ptr::null(); - let rc = curl_sys::curl_easy_getinfo(self.inner.handle, opt, &mut p); + let rc = curl_sys::curl_easy_getinfo(self.inner.handle.as_ptr(), opt, &mut p); self.cvt(rc)?; Ok(p) } @@ -3458,7 +3491,7 @@ impl Easy2 { fn getopt_long(&self, opt: curl_sys::CURLINFO) -> Result { unsafe { let mut p = 0; - let rc = curl_sys::curl_easy_getinfo(self.inner.handle, opt, &mut p); + let rc = curl_sys::curl_easy_getinfo(self.inner.handle.as_ptr(), opt, &mut p); self.cvt(rc)?; Ok(p) } @@ -3467,7 +3500,7 @@ impl Easy2 { fn getopt_double(&self, opt: curl_sys::CURLINFO) -> Result { unsafe { let mut p = 0 as c_double; - let rc = curl_sys::curl_easy_getinfo(self.inner.handle, opt, &mut p); + let rc = curl_sys::curl_easy_getinfo(self.inner.handle.as_ptr(), opt, &mut p); self.cvt(rc)?; Ok(p) } @@ -3513,20 +3546,12 @@ impl Easy2 { impl fmt::Debug for Easy2 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Easy") - .field("handle", &self.inner.handle) + .field("handle", &self.inner.handle.as_ptr()) .field("handler", &self.inner.handler) .finish() } } -impl Drop for Easy2 { - fn drop(&mut self) { - unsafe { - curl_sys::curl_easy_cleanup(self.inner.handle); - } - } -} - extern "C" fn header_cb( buffer: *mut c_char, size: size_t, @@ -3698,6 +3723,20 @@ fn double_seconds_to_duration_sub_second2() { assert_eq!(dur.subsec_nanos(), 500_000_000); } +impl CURLPtr { + fn as_ptr(&self) -> *mut curl_sys::CURL { + self.0 + } +} + +impl Drop for CURLPtr { + fn drop(&mut self) { + unsafe { + curl_sys::curl_easy_cleanup(self.0); + } + } +} + impl Auth { /// Creates a new set of authentications with no members. /// diff --git a/src/multi.rs b/src/multi.rs index d6dae5943..31b76799f 100644 --- a/src/multi.rs +++ b/src/multi.rs @@ -982,6 +982,11 @@ impl Easy2Handle { self.easy.get_mut() } + /// Consumes the Easy2 handle, returning the underlying handler. + pub fn into_inner(self) -> H { + self.easy.into_inner() + } + /// Same as `EasyHandle::set_token` pub fn set_token(&mut self, token: usize) -> Result<(), Error> { unsafe {