df-helper 0.2.26

df helper tools db cache
Documentation
use std::fs::File;
use std::time::Duration;
use curl::easy::{Easy, List};
use json::{JsonValue, object};
use std::io::{Read, Write};
use std::str;

use crate::{files, tools};
use crate::files::file;


pub struct Http {
    url: String,
    curl: Easy,
    body: String,
    headers: Vec<String>,
    cookies: Vec<String>,
    pub res_headers: JsonValue,
    filepath: String,
    pub res_cookies: JsonValue,
}

impl Http {
    /// 请求地址
    pub fn url(url: &str) -> Self {
        Self {
            url: url.to_string(),
            curl: Easy::new(),
            body: String::new(),
            headers: Vec::new(),
            cookies: Vec::new(),
            res_headers: object! {},
            filepath: String::new(),
            res_cookies: object! {},
        }
    }
    /// Bearer认证
    pub fn authorization_bearer(&mut self, token: &str) -> &mut Self {
        self.set_headers("Authorization", format!("Bearer {}", token).as_str());
        self
    }
    /// 调试
    /// 控制台将输出大量的信息以供
    pub fn debug(&mut self, open: bool) -> &mut Self {
        self.curl.verbose(open).unwrap();
        self
    }
    /// 是否显示进程表
    pub fn progress(&mut self, open: bool) -> &mut Self {
        self.curl.progress(open).unwrap();
        let mut i = 0.0;
        self.curl.progress_function(move |total_download_bytes, cur_download_bytes, _total_upload_bytes, _cur_upload_bytes| {
            if total_download_bytes > 0.0 {
                if i != cur_download_bytes / total_download_bytes * 100.0 {
                    i = cur_download_bytes / total_download_bytes * 100.0;
                    println!("已下载:{}%", i);
                }
            } else {
                if i > 0.0 {} else {
                    i = 1.0;
                    println!("已下载:0%");
                }
            }
            true
        }).expect("进度执行失败");
        self
    }
    /// 设置头信息
    pub fn set_headers(&mut self, key: &str, value: &str) -> &mut Self {
        self.headers.push(format!("{}:{}", key, value));
        self
    }
    /// 设置cookie
    pub fn set_cookies(&mut self, key: &str, value: &str) -> &mut Self {
        self.cookies.push(format!("{}={}", key, value));
        self
    }
    /// 设置认证账号
    pub fn auth(&mut self, username: &str, password: &str) -> &mut Self {
        self.curl.username(username).unwrap();
        self.curl.password(password).unwrap();
        self
    }

    /// POST 发送
    pub fn post(&mut self, data: JsonValue) -> &mut Self {
        self.body = data.dump();
        self.curl.post(true).unwrap();
        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();
        self
    }

    /// POST 发送
    pub fn post_form(&mut self, data: JsonValue) -> &mut Self {
        self.set_headers("content-type", "application/x-www-form-urlencoded");
        self.body = data.dump();
        self.curl.post(true).unwrap();
        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();
        self
    }
    /// POST json 发送
    pub fn post_json(&mut self, data: JsonValue) -> &mut Self {
        self.set_headers("content-type", "application/json");
        self.body = data.dump();
        self.curl.post(true).unwrap();
        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();

        self
    }
    /// patch 请求
    pub fn patch(&mut self, body: JsonValue) -> &mut Self {
        self.curl.custom_request("PATCH").unwrap();
        self.set_headers("content-type", "application/json");
        self.body = body.dump();
        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();
        self
    }

    /// GET 请求
    pub fn get(&mut self, data: JsonValue) -> &mut Self {
        self.curl.get(true).unwrap();
        if !data.is_empty() {
            let mut url = "".to_string();
            for (k, v) in data.entries() {
                if url == "" {
                    url = format!("{}={}", k, v);
                } else {
                    url = format!("{}&{}={}", url, k, v);
                }
            }
            self.url = format!("{}?{}", self.url, url);
        }
        self
    }
    /// download 下载
    pub fn download(&mut self, filepath: &str) -> &mut Self {
        self.filepath = filepath.to_string();
        self
    }
    /// 返回
    pub fn response(&mut self) -> JsonValue {
        let mut headers = List::new();
        for header in self.headers.clone() {
            headers.append(header.as_str()).unwrap();
        }
        if !self.headers.is_empty() {
            self.curl.http_headers(headers).unwrap();
        }
        let mut cookies = "".to_string();
        for cookie in self.cookies.clone() {
            if cookies == "" {
                cookies = format!("{}", cookie);
            } else {
                cookies = format!("{};{}", cookies, cookie);
            }
        }
        if !self.cookies.is_empty() {
            self.curl.cookie(&*cookies).unwrap();
        }


        // self.curl.show_header(true).unwrap();
        self.curl.accept_encoding("zlib,gzip,identity").unwrap();
        self.curl.timeout(Duration::from_micros(5)).unwrap();
        self.curl.connect_timeout(Duration::from_micros(5)).unwrap();

        self.curl.url(self.url.as_str()).unwrap();

        let mut body = Vec::new();
        {
            let mut transfer = self.curl.transfer();

            transfer.header_function(|data| {
                let str = str::from_utf8(data).unwrap();
                let data = tools::string::split(str.to_string(), ":");
                let key = data[0].as_str().unwrap().to_lowercase();
                match key.as_str() {
                    "set-cookie" => {
                        let kv = tools::string::split(data[1].to_string(), ";");
                        let cookie = kv[0].as_str().unwrap().trim();
                        let kv = tools::string::split(cookie.to_string(), "=");
                        for index in 0..kv.len() {
                            let k = kv[0].clone();
                            if index == 0 {
                                self.res_cookies[k.as_str().unwrap()] = "".into();
                            } else {
                                if kv[index] == "" {
                                    self.res_cookies[k.as_str().unwrap()] = format!("{}=", self.res_cookies[k.as_str().unwrap()]).into();
                                } else {
                                    self.res_cookies[k.as_str().unwrap()] = format!("{}", kv[index]).into();
                                }
                            }
                        }
                    }
                    _ => {}
                }
                true
            }).unwrap();

            transfer.read_function(|data| {
                Ok(self.body.as_bytes().read(data).unwrap())
            }).unwrap();

            transfer.write_function(|data| {
                body.extend_from_slice(data.clone());
                Ok(data.len())
            }).unwrap();

            transfer.perform().unwrap();
        }
        self._state();
        let data = String::from_utf8_lossy(&body);
        let data = &data as &str;
        match self.res_headers["type"].as_str().unwrap() {
            "json" => {
                return json::parse(data).unwrap();
            }
            "text" => {
                return JsonValue::from(data);
            }
            "jpeg" => {
                file::create_dir(self.filepath.as_str());
                let mut file = File::create(self.filepath.as_str()).unwrap();
                file.write(&body).unwrap();
                let res = files::file::is_file(self.filepath.as_str());
                return JsonValue::Boolean(res);
            }
            _ => {
                println!("{:#}", self.res_headers);
            }
        }
        return object! {};
    }
    /// 状态处理
    fn _state(&mut self) {
        self.res_headers["code"] = self.curl.response_code().unwrap().into();
        self.res_headers["content-type"] = self.curl.content_type().unwrap().into();
        let data = tools::string::split(self.res_headers["content-type"].to_string(), ";");
        match data[0].as_str().unwrap() {
            "application/json" => {
                self.res_headers["type"] = "json".into();
            }
            "text/html" => {
                self.res_headers["type"] = "text".into();
            }
            "image/jpeg" => {
                self.res_headers["type"] = "jpeg".into();
            }
            _ => {
                println!("{:#}", data);
                self.res_headers["type"] = "text".into();
            }
        }
    }
}