1 //! Rust bindings to the libcurl C library
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.
8 //! [libcurl]: https://curl.haxx.se/libcurl/
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.
19 //! use std::io::{stdout, Write};
21 //! use curl::easy::Easy;
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())
29 //! easy.perform().unwrap();
32 //! # What about multiple concurrent HTTP requests?
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!
39 //! # Where does libcurl come from?
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.
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.
49 #![deny(missing_docs)]
50 #![doc(html_root_url = "https://docs.rs/curl/0.4")]
52 extern crate curl_sys
;
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
;
64 use std
::sync
::{Once, ONCE_INIT}
;
66 pub use error
::{Error, ShareError, MultiError, FormError}
;
69 pub use version
::{Version, Protocols}
;
76 /// Initializes the underlying libcurl library.
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.
81 static INIT
: Once
= ONCE_INIT
;
85 assert_eq
!(curl_sys
::curl_global_init(curl_sys
::CURL_GLOBAL_ALL
), 0);
88 // Note that we explicitly don't schedule a call to
89 // `curl_global_cleanup`. The documentation for that function says
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.
95 // We can't ever be sure of that, so unfortunately we can't call the
99 #[cfg(all(unix, not(target_os = "macos")))]
104 #[cfg(not(all(unix, not(target_os = "macos"))))]
105 fn platform_init() {}
108 unsafe fn opt_str
<'a
>(ptr
: *const libc
::c_char
) -> Option
<&'a
str> {
112 Some(str::from_utf8(CStr
::from_ptr(ptr
).to_bytes()).unwrap())
116 fn cvt(r
: curl_sys
::CURLcode
) -> Result
<(), Error
> {
117 if r
== curl_sys
::CURLE_OK
{