1use std::fs;
2use std::fs::DirBuilder;
3use json::{array, JsonValue, object};
4
5pub struct Body {}
6
7impl Body {
8 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 }
62 }
63 body_list
64 }
65
66 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}