pub mod curl;
pub mod error;
pub mod types;
#[cfg(feature = "python")]
pub mod python;
pub use curl::Curl;
pub use error::{CurlError, Result};
pub use types::{Browser, CurlInfo, CurlOpt, HttpVersion};
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub struct Request {
url: String,
data: Option<String>,
impersonate: Option<Browser>,
proxies: Option<String>,
}
impl Request {
pub fn get(url: impl Into<String>) -> Self {
Self {
url: url.into(),
data: None,
impersonate: None,
proxies: None,
}
}
pub fn post(url: impl Into<String>, data: impl Into<String>) -> Self {
Self {
url: url.into(),
data: Some(data.into()),
impersonate: None,
proxies: None,
}
}
pub fn impersonate(mut self, browser: Browser) -> Self {
self.impersonate = Some(browser);
self
}
pub fn proxies(mut self, proxy: impl Into<String>) -> Self {
self.proxies = Some(proxy.into());
self
}
pub fn send(self) -> Result<Vec<u8>> {
let mut curl = Curl::new()?;
if let Some(browser) = self.impersonate {
curl.set_browser_impersonation(browser)?;
}
if let Some(proxy) = &self.proxies {
curl.set_proxy(proxy)?;
}
curl.set_url(&self.url)?;
if let Some(data) = &self.data {
curl.set_post_data(data)?;
}
let mut buffer = Vec::new();
curl.perform(&mut buffer)?;
Ok(buffer)
}
}
pub fn get(url: &str) -> Result<Vec<u8>> {
Request::get(url).send()
}
pub fn post(url: &str, data: &str) -> Result<Vec<u8>> {
Request::post(url, data).send()
}
use std::sync::Once;
static INIT: Once = Once::new();
pub(crate) fn init_curl() {
INIT.call_once(|| unsafe {
curl_sys::curl_global_init(curl_sys::CURL_GLOBAL_DEFAULT);
});
}
pub fn version() -> String {
init_curl();
unsafe {
let version_ptr = curl_sys::curl_version();
std::ffi::CStr::from_ptr(version_ptr)
.to_string_lossy()
.into_owned()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_version() {
let ver = version();
assert!(ver.contains("curl") || ver.contains("libcurl"));
}
}