df_web/
body.rs

1use std::fs;
2use std::fs::DirBuilder;
3use json::{array, JsonValue, object};
4
5pub struct Body {}
6
7impl Body {
8    /// 内容信息处理
9    pub fn def(header: JsonValue, body: Vec<u8>) -> JsonValue {
10        let content_type = header["content-type"].as_str().unwrap();
11        let content_length = header["content-length"].to_string().parse::<usize>().unwrap();
12        let mut body_list = object! {
13            get: object! {},
14            post: object! {},
15            files: object! {},
16        };
17        body_list["get"] = Body::query(header["uri"].clone().to_string());
18        match content_type {
19            "multipart/form-data" => {
20                body_list = Body::multipart(header.clone(), body.clone(), body_list.clone());
21            }
22            "application/x-www-form-urlencoded" => {
23                if content_length == 0 {
24                    return body_list;
25                }
26                let text: String = body.iter().map(|&c| c as char).collect();
27
28
29                let text: Vec<&str> = text.split("&").collect();
30                for item in text.iter() {
31                    let row: Vec<&str> = item.split("=").collect();
32                    body_list["post"][row[0].clone()] = row[1].clone().into();
33                }
34            }
35            "application/json" => {
36                if content_length == 0 {
37                    return body_list;
38                }
39                let text: String = body.iter().map(|&c| c as char).collect();
40                match json::parse(&*text.clone()) {
41                    Ok(e) => {
42                        body_list["post"] = e.clone();
43                    }
44                    Err(_) => {
45                        let str = unsafe { String::from_utf8_unchecked(body) };
46                        match json::parse(&*str.clone()) {
47                            Ok(e) => {
48                                body_list["post"] = e;
49                            }
50                            Err(_) => {
51                                body_list["post"] = object! {}
52                            }
53                        }
54                    }
55                }
56            }
57            _ => {
58                // println!(">>>>>>> >>>>>>");
59                // println!("{}", data);
60                // println!(">>>>>>> >>>>>>");
61            }
62        }
63        body_list
64    }
65
66    /// 数据提取
67    pub fn multipart(header: JsonValue, data: Vec<u8>, mut body_list: JsonValue) -> JsonValue {
68        let boundary = header["boundary"].as_str().unwrap();
69        let text = unsafe { String::from_utf8_unchecked(data.clone()) };
70        let text = text.trim_start_matches("\r\n");
71        let text = text.trim_end_matches(format!("\r\n--{}--\r\n", boundary.clone()).as_str()).to_string();
72        let fg = format!("--{}\r\n", boundary.clone());
73        let list: Vec<&str> = text.split(fg.as_str().clone()).collect();
74        let mut index = 0;
75        let mut body = data[2 + fg.len()..].to_vec();
76        while index < list.len() {
77            let item = list[index].to_string();
78            let item = item.trim_start_matches(boundary.clone());
79            let len = item.len();
80            if len == 0 {
81                index += 1;
82                continue;
83            }
84            match item.contains("filename=") {
85                false => {
86                    let row: Vec<&str> = item.split("\r\n\r\n").collect();
87                    let field: Vec<&str> = row[0].split("\"").collect();
88                    let name = field[1];
89                    let row: Vec<&str> = row[1].split("\r\n").collect();
90                    let value: Vec<&str> = row[0].split("\"").collect();
91                    body_list["post"][name] = value[0].clone().into();
92                }
93                true => {
94                    let text: Vec<&str> = item.split("\r\n\r\n").collect();
95                    let body = text[1];
96                    let file = body.trim_start_matches("\u{0}");
97                    let file = file.trim_end_matches("\r\n");
98                    let text: Vec<&str> = text[0].split("\r\n").collect();
99                    let name: Vec<&str> = text[0].split("\"").collect();
100                    let types: Vec<&str> = text[1].split(": ").collect();
101                    let types = types[1];
102                    let field = name[1];
103                    let filename = name[3];
104                    fn _content_type_mode(data: &str) -> String {
105                        match data {
106                            "image/png" => "png",
107                            "image/jpeg" => "jpeg",
108                            "image/jpg" => "jpg",
109                            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" => "xlsx",
110                            "image/x-icon" => "ico",
111                            _ => "txt"
112                        }.to_string().clone()
113                    }
114                    let mut file_data = object! {};
115                    file_data["type"] = types.into();
116                    file_data["name"] = filename.into();
117                    file_data["size"] = file.len().into();
118
119
120                    file_data["sha"] = df_crypto::sha::str_to_sha256(file).into();
121                    file_data["mode"] = JsonValue::String(_content_type_mode(types.clone()).clone());
122
123                    let temp_file = format!("{}.{}", file_data["sha"], file_data["mode"]);
124
125                    let public = header["public"].as_str().unwrap();
126                    let temp = format!("{}/../temp", public.clone());
127                    let filename = format!("{}/../temp/{}", public.clone(), temp_file);
128                    file_data["temp"] = filename.clone().into();
129
130                    match DirBuilder::new().recursive(true).create(temp.clone()) {
131                        Ok(_) => true,
132                        Err(_) => false
133                    };
134
135                    match fs::write(file_data["temp"].as_str().unwrap().clone(), file.clone()) {
136                        Ok(_) => {
137                            if body_list["files"][field].is_empty() {
138                                body_list["files"][field] = array![file_data.clone()];
139                            } else {
140                                body_list["files"][field].push(file_data.clone()).unwrap();
141                            }
142                            true
143                        }
144                        Err(_) => {
145                            false
146                        }
147                    };
148                }
149            }
150            index += 1;
151            if index == list.len() {} else {
152                body = body[len + fg.len()..].to_vec();
153            }
154        }
155        body_list
156    }
157    pub fn query(data: String) -> JsonValue {
158        let mut list = object! {};
159        let query: Vec<&str> = data.split("?").collect();
160        if query.len() == 1 {
161            return list;
162        }
163        let query = query[1].clone();
164        if query.is_empty() {
165            return list;
166        }
167        let query: Vec<&str> = query.split("&").collect();
168
169        for item in query.iter() {
170            let row: Vec<&str> = item.split("=").collect();
171            let key = row[0].clone();
172            let value = row[1].clone();
173            list[key] = value.into();
174        }
175        list
176    }
177}