]> git.proxmox.com Git - rustc.git/blob - src/vendor/curl/src/lib.rs
New upstream version 1.19.0+dfsg1
[rustc.git] / src / vendor / curl / src / lib.rs
1 //! Rust bindings to the libcurl C library
2 //!
3 //! This crate contains bindings for an HTTP/HTTPS client which is powered by
4 //! [libcurl], the same library behind the `curl` command line tool. The API
5 //! currently closely matches that of libcurl itself, except that a Rustic layer
6 //! of safety is applied on top.
7 //!
8 //! [libcurl]: https://curl.haxx.se/libcurl/
9 //!
10 //! # The "Easy" API
11 //!
12 //! The easiest way to send a request is to use the `Easy` api which corresponds
13 //! to `CURL` in libcurl. This handle supports a wide variety of options and can
14 //! be used to make a single blocking request in a thread. Callbacks can be
15 //! specified to deal with data as it arrives and a handle can be reused to
16 //! cache connections and such.
17 //!
18 //! ```rust,no_run
19 //! use std::io::{stdout, Write};
20 //!
21 //! use curl::easy::Easy;
22 //!
23 //! // Write the contents of rust-lang.org to stdout
24 //! let mut easy = Easy::new();
25 //! easy.url("https://www.rust-lang.org/").unwrap();
26 //! easy.write_function(|data| {
27 //! Ok(stdout().write(data).unwrap())
28 //! }).unwrap();
29 //! easy.perform().unwrap();
30 //! ```
31 //!
32 //! # What about multiple concurrent HTTP requests?
33 //!
34 //! One option you have currently is to send multiple requests in multiple
35 //! threads, but otherwise libcurl has a "multi" interface for doing this
36 //! operation. Initial bindings of this interface can be found in the `multi`
37 //! module, but feedback is welcome!
38 //!
39 //! # Where does libcurl come from?
40 //!
41 //! This crate links to the `curl-sys` crate which is in turn responsible for
42 //! acquiring and linking to the libcurl library. Currently this crate will
43 //! build libcurl from source if one is not already detected on the system.
44 //!
45 //! There is a large number of releases for libcurl, all with different sets of
46 //! capabilities. Robust programs may wish to inspect `Version::get()` to test
47 //! what features are implemented in the linked build of libcurl at runtime.
48
49 #![deny(missing_docs)]
50 #![doc(html_root_url = "https://docs.rs/curl/0.4")]
51
52 extern crate curl_sys;
53 extern crate libc;
54
55 #[cfg(all(unix, not(target_os = "macos")))]
56 extern crate openssl_sys;
57 #[cfg(all(unix, not(target_os = "macos")))]
58 extern crate openssl_probe;
59 #[cfg(windows)]
60 extern crate winapi;
61
62 use std::ffi::CStr;
63 use std::str;
64 use std::sync::{Once, ONCE_INIT};
65
66 pub use error::{Error, ShareError, MultiError, FormError};
67 mod error;
68
69 pub use version::{Version, Protocols};
70 mod version;
71
72 mod panic;
73 pub mod easy;
74 pub mod multi;
75
76 /// Initializes the underlying libcurl library.
77 ///
78 /// It's not required to call this before the library is used, but it's
79 /// recommended to do so as soon as the program starts.
80 pub fn init() {
81 static INIT: Once = ONCE_INIT;
82 INIT.call_once(|| {
83 platform_init();
84 unsafe {
85 assert_eq!(curl_sys::curl_global_init(curl_sys::CURL_GLOBAL_ALL), 0);
86 }
87
88 // Note that we explicitly don't schedule a call to
89 // `curl_global_cleanup`. The documentation for that function says
90 //
91 // > You must not call it when any other thread in the program (i.e. a
92 // > thread sharing the same memory) is running. This doesn't just mean
93 // > no other thread that is using libcurl.
94 //
95 // We can't ever be sure of that, so unfortunately we can't call the
96 // function.
97 });
98
99 #[cfg(all(unix, not(target_os = "macos")))]
100 fn platform_init() {
101 openssl_sys::init();
102 }
103
104 #[cfg(not(all(unix, not(target_os = "macos"))))]
105 fn platform_init() {}
106 }
107
108 unsafe fn opt_str<'a>(ptr: *const libc::c_char) -> Option<&'a str> {
109 if ptr.is_null() {
110 None
111 } else {
112 Some(str::from_utf8(CStr::from_ptr(ptr).to_bytes()).unwrap())
113 }
114 }
115
116 fn cvt(r: curl_sys::CURLcode) -> Result<(), Error> {
117 if r == curl_sys::CURLE_OK {
118 Ok(())
119 } else {
120 Err(Error::new(r))
121 }
122 }