Skip to main content

df_http/
lib.rs

1use std::fs::File;
2use std::time::Duration;
3use curl::easy::{Easy, List};
4use json::{JsonValue, object};
5use std::io::{Read, Write};
6use std::str;
7use log::info;
8
9pub struct Http {
10    url: String,
11    curl: Easy,
12    body: String,
13    headers: Vec<String>,
14    cookies: Vec<String>,
15    pub res_headers: JsonValue,
16    filepath: String,
17    pub res_cookies: JsonValue,
18}
19
20impl Http {
21    /// 请求地址
22    pub fn url(url: &str) -> Self {
23        Self {
24            url: url.to_string(),
25            curl: Easy::new(),
26            body: String::new(),
27            headers: Vec::new(),
28            cookies: Vec::new(),
29            res_headers: object! {},
30            filepath: String::new(),
31            res_cookies: object! {},
32        }
33    }
34    /// Bearer认证
35    pub fn authorization_bearer(&mut self, token: &str) -> &mut Self {
36        self.set_headers("Authorization", format!("Bearer {}", token).as_str());
37        self
38    }
39    /// 调试
40    /// 控制台将输出大量的信息以供
41    pub fn debug(&mut self, open: bool) -> &mut Self {
42        self.curl.verbose(open).unwrap();
43        self
44    }
45    /// 是否显示进程表
46    pub fn progress(&mut self, open: bool) -> &mut Self {
47        self.curl.progress(open).unwrap();
48        let mut i = 0.0;
49        self.curl.progress_function(move |total_download_bytes, cur_download_bytes, _total_upload_bytes, _cur_upload_bytes| {
50            if total_download_bytes > 0.0 {
51                if i != cur_download_bytes / total_download_bytes * 100.0 {
52                    i = cur_download_bytes / total_download_bytes * 100.0;
53                    println!("已下载:{}%", i);
54                }
55            } else {
56                if i > 0.0 {} else {
57                    i = 1.0;
58                    println!("已下载:0%");
59                }
60            }
61            true
62        }).expect("进度执行失败");
63        self
64    }
65    /// 设置头信息
66    pub fn set_headers(&mut self, key: &str, value: &str) -> &mut Self {
67        self.headers.push(format!("{}:{}", key, value));
68        self
69    }
70    /// 设置cookie
71    pub fn set_cookies(&mut self, key: &str, value: &str) -> &mut Self {
72        self.cookies.push(format!("{}={}", key, value));
73        self
74    }
75    /// 设置认证账号
76    pub fn auth(&mut self, username: &str, password: &str) -> &mut Self {
77        self.curl.username(username).unwrap();
78        self.curl.password(password).unwrap();
79        self
80    }
81
82    /// POST 发送
83    pub fn post(&mut self, data: JsonValue) -> &mut Self {
84        self.body = data.dump();
85        self.curl.post(true).unwrap();
86        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();
87        self
88    }
89
90    /// POST 发送
91    pub fn post_form(&mut self, data: JsonValue) -> &mut Self {
92        self.set_headers("content-type", "application/x-www-form-urlencoded");
93        self.body = data.dump();
94        self.curl.post(true).unwrap();
95        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();
96        self
97    }
98    /// POST json 发送
99    pub fn post_json(&mut self, data: JsonValue) -> &mut Self {
100        self.set_headers("content-type", "application/json");
101        self.body = data.dump();
102        self.curl.post(true).unwrap();
103        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();
104
105        self
106    }
107    /// patch 请求
108    pub fn patch(&mut self, body: JsonValue) -> &mut Self {
109        self.curl.custom_request("PATCH").unwrap();
110        self.set_headers("content-type", "application/json");
111        self.body = body.dump();
112        self.curl.post_field_size(self.body.as_bytes().len() as u64).unwrap();
113        self
114    }
115
116    /// GET 请求
117    pub fn get(&mut self, data: JsonValue) -> &mut Self {
118        self.curl.get(true).unwrap();
119        if !data.is_empty() {
120            let mut url = "".to_string();
121            for (k, v) in data.entries() {
122                if url == "" {
123                    url = format!("{}={}", k, v);
124                } else {
125                    url = format!("{}&{}={}", url, k, v);
126                }
127            }
128            self.url = format!("{}?{}", self.url, url);
129        }
130        self
131    }
132    /// download 下载
133    pub fn download(&mut self, filepath: &str) -> &mut Self {
134        self.filepath = filepath.to_string();
135        self
136    }
137    /// 返回
138    pub fn response(&mut self) -> JsonValue {
139        let mut headers = List::new();
140        for header in self.headers.clone() {
141            headers.append(header.as_str()).unwrap();
142        }
143        if !self.headers.is_empty() {
144            self.curl.http_headers(headers).unwrap();
145        }
146        let mut cookies = "".to_string();
147        for cookie in self.cookies.clone() {
148            if cookies == "" {
149                cookies = format!("{}", cookie);
150            } else {
151                cookies = format!("{};{}", cookies, cookie);
152            }
153        }
154        if !self.cookies.is_empty() {
155            self.curl.cookie(&*cookies).unwrap();
156        }
157
158
159        // self.curl.show_header(true).unwrap();
160        self.curl.accept_encoding("zlib,gzip,identity").unwrap();
161        self.curl.timeout(Duration::from_micros(5)).unwrap();
162        self.curl.connect_timeout(Duration::from_micros(5)).unwrap();
163
164        self.curl.url(self.url.as_str()).unwrap();
165
166        let mut body = Vec::new();
167        {
168            let mut transfer = self.curl.transfer();
169
170            transfer.header_function(|data| {
171                let str = str::from_utf8(data).unwrap();
172                let data: Vec<&str> = str.split(":").collect();
173                let key = data[0].to_lowercase();
174                match key.as_str() {
175                    "set-cookie" => {
176                        let kv: Vec<&str> = data[1].split(";").collect();
177                        let cookie = kv[0].trim();
178                        let kv: Vec<&str> = cookie.split("=").collect();
179                        for index in 0..kv.len() {
180                            let k = kv[0].clone();
181                            if index == 0 {
182                                self.res_cookies[k] = "".into();
183                            } else {
184                                if kv[index] == "" {
185                                    self.res_cookies[k] = format!("{}=", self.res_cookies[k]).into();
186                                } else {
187                                    self.res_cookies[k] = format!("{}", kv[index]).into();
188                                }
189                            }
190                        }
191                    }
192                    _ => {}
193                }
194                true
195            }).unwrap();
196
197            transfer.read_function(|data| {
198                Ok(self.body.as_bytes().read(data).unwrap())
199            }).unwrap();
200
201            transfer.write_function(|data| {
202                body.extend_from_slice(data.clone());
203                Ok(data.len())
204            }).unwrap();
205
206            transfer.perform().unwrap();
207        }
208        self._state();
209        let data = String::from_utf8_lossy(&body);
210        let data = &data as &str;
211        match self.res_headers["type"].as_str().unwrap() {
212            "json" => {
213                return json::parse(data).unwrap();
214            }
215            "text" => {
216                return JsonValue::from(data);
217            }
218            "jpeg" => {
219                df_file::create_dir(self.filepath.as_str());
220                let mut file = File::create(self.filepath.as_str()).unwrap();
221                file.write(&body).unwrap();
222                let res = df_file::is_file(self.filepath.as_str());
223                return JsonValue::Boolean(res);
224            }
225            _ => {
226                println!("{:#}", self.res_headers);
227            }
228        }
229        return object! {};
230    }
231    /// 状态处理
232    fn _state(&mut self) {
233        self.res_headers["code"] = self.curl.response_code().unwrap().into();
234        self.res_headers["content-type"] = self.curl.content_type().unwrap().into();
235        let content_type = self.res_headers["content-type"].to_string();
236        let data: Vec<&str> = content_type.split(";").collect();
237        match data[0] {
238            "application/json" => {
239                self.res_headers["type"] = "json".into();
240            }
241            "text/html" => {
242                self.res_headers["type"] = "text".into();
243            }
244            "image/jpeg" => {
245                self.res_headers["type"] = "jpeg".into();
246            }
247            _ => {
248                info!("{:#?}", data);
249                self.res_headers["type"] = "text".into();
250            }
251        }
252    }
253}