summaryrefslogtreecommitdiffstats
path: root/vendor/curl/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/curl/src/lib.rs')
-rw-r--r--vendor/curl/src/lib.rs184
1 files changed, 184 insertions, 0 deletions
diff --git a/vendor/curl/src/lib.rs b/vendor/curl/src/lib.rs
new file mode 100644
index 0000000..2965e2b
--- /dev/null
+++ b/vendor/curl/src/lib.rs
@@ -0,0 +1,184 @@
+//! Rust bindings to the libcurl C library
+//!
+//! This crate contains bindings for an HTTP/HTTPS client which is powered by
+//! [libcurl], the same library behind the `curl` command line tool. The API
+//! currently closely matches that of libcurl itself, except that a Rustic layer
+//! of safety is applied on top.
+//!
+//! [libcurl]: https://curl.haxx.se/libcurl/
+//!
+//! # The "Easy" API
+//!
+//! The easiest way to send a request is to use the `Easy` api which corresponds
+//! to `CURL` in libcurl. This handle supports a wide variety of options and can
+//! be used to make a single blocking request in a thread. Callbacks can be
+//! specified to deal with data as it arrives and a handle can be reused to
+//! cache connections and such.
+//!
+//! ```rust,no_run
+//! use std::io::{stdout, Write};
+//!
+//! use curl::easy::Easy;
+//!
+//! // Write the contents of rust-lang.org to stdout
+//! let mut easy = Easy::new();
+//! easy.url("https://www.rust-lang.org/").unwrap();
+//! easy.write_function(|data| {
+//! stdout().write_all(data).unwrap();
+//! Ok(data.len())
+//! }).unwrap();
+//! easy.perform().unwrap();
+//! ```
+//!
+//! # What about multiple concurrent HTTP requests?
+//!
+//! One option you have currently is to send multiple requests in multiple
+//! threads, but otherwise libcurl has a "multi" interface for doing this
+//! operation. Initial bindings of this interface can be found in the `multi`
+//! module, but feedback is welcome!
+//!
+//! # Where does libcurl come from?
+//!
+//! This crate links to the `curl-sys` crate which is in turn responsible for
+//! acquiring and linking to the libcurl library. Currently this crate will
+//! build libcurl from source if one is not already detected on the system.
+//!
+//! There is a large number of releases for libcurl, all with different sets of
+//! capabilities. Robust programs may wish to inspect `Version::get()` to test
+//! what features are implemented in the linked build of libcurl at runtime.
+//!
+//! # Initialization
+//!
+//! The underlying libcurl library must be initialized before use and has
+//! certain requirements on how this is done. Check the documentation for
+//! [`init`] for more details.
+
+#![deny(missing_docs, missing_debug_implementations)]
+#![doc(html_root_url = "https://docs.rs/curl/0.4")]
+
+use std::ffi::CStr;
+use std::str;
+use std::sync::Once;
+
+pub use crate::error::{Error, FormError, MultiError, ShareError};
+mod error;
+
+pub use crate::version::{Protocols, Version};
+mod version;
+
+pub mod easy;
+pub mod multi;
+mod panic;
+
+#[cfg(test)]
+static INITIALIZED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
+
+/// Initializes the underlying libcurl library.
+///
+/// The underlying libcurl library must be initialized before use, and must be
+/// done so on the main thread before any other threads are created by the
+/// program. This crate will do this for you automatically in the following
+/// scenarios:
+///
+/// - Creating a new [`Easy`][easy::Easy] or [`Multi`][multi::Multi] handle
+/// - At program startup on Windows, macOS, Linux, Android, or FreeBSD systems
+///
+/// This should be sufficient for most applications and scenarios, but in any
+/// other case, it is strongly recommended that you call this function manually
+/// as soon as your program starts.
+///
+/// Calling this function more than once is harmless and has no effect.
+#[inline]
+pub fn init() {
+ /// Used to prevent concurrent or duplicate initialization.
+ static INIT: Once = Once::new();
+
+ INIT.call_once(|| {
+ #[cfg(need_openssl_init)]
+ openssl_probe::init_ssl_cert_env_vars();
+ #[cfg(need_openssl_init)]
+ openssl_sys::init();
+
+ unsafe {
+ assert_eq!(curl_sys::curl_global_init(curl_sys::CURL_GLOBAL_ALL), 0);
+ }
+
+ #[cfg(test)]
+ {
+ INITIALIZED.store(true, std::sync::atomic::Ordering::SeqCst);
+ }
+
+ // Note that we explicitly don't schedule a call to
+ // `curl_global_cleanup`. The documentation for that function says
+ //
+ // > You must not call it when any other thread in the program (i.e. a
+ // > thread sharing the same memory) is running. This doesn't just mean
+ // > no other thread that is using libcurl.
+ //
+ // We can't ever be sure of that, so unfortunately we can't call the
+ // function.
+ });
+}
+
+/// An exported constructor function. On supported platforms, this will be
+/// invoked automatically before the program's `main` is called. This is done
+/// for the convenience of library users since otherwise the thread-safety rules
+/// around initialization can be difficult to fulfill.
+///
+/// This is a hidden public item to ensure the symbol isn't optimized away by a
+/// rustc/LLVM bug: https://github.com/rust-lang/rust/issues/47384. As long as
+/// any item in this module is used by the final binary (which `init` will be)
+/// then this symbol should be preserved.
+#[used]
+#[doc(hidden)]
+#[cfg_attr(
+ any(target_os = "linux", target_os = "freebsd", target_os = "android"),
+ link_section = ".init_array"
+)]
+#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
+#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
+pub static INIT_CTOR: extern "C" fn() = {
+ /// This is the body of our constructor function.
+ #[cfg_attr(
+ any(target_os = "linux", target_os = "android"),
+ link_section = ".text.startup"
+ )]
+ extern "C" fn init_ctor() {
+ init();
+ }
+
+ init_ctor
+};
+
+unsafe fn opt_str<'a>(ptr: *const libc::c_char) -> Option<&'a str> {
+ if ptr.is_null() {
+ None
+ } else {
+ Some(str::from_utf8(CStr::from_ptr(ptr).to_bytes()).unwrap())
+ }
+}
+
+fn cvt(r: curl_sys::CURLcode) -> Result<(), Error> {
+ if r == curl_sys::CURLE_OK {
+ Ok(())
+ } else {
+ Err(Error::new(r))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ #[cfg(any(
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "windows",
+ target_os = "freebsd",
+ target_os = "android"
+ ))]
+ fn is_initialized_before_main() {
+ assert!(INITIALIZED.load(std::sync::atomic::Ordering::SeqCst));
+ }
+}