df-web 0.1.28

This is an WEB SERVER
Documentation
use std::fs;
use std::fs::DirBuilder;
use json::{array, JsonValue, object};

pub struct Body {}

impl Body {
    /// 内容信息处理
    pub fn def(header: JsonValue, body: Vec<u8>) -> JsonValue {
        let content_type = header["content-type"].as_str().unwrap();
        let content_length = header["content-length"].to_string().parse::<usize>().unwrap();
        let mut body_list = object! {
            get: object! {},
            post: object! {},
            files: object! {},
        };
        body_list["get"] = Body::query(header["uri"].clone().to_string());
        match content_type {
            "multipart/form-data" => {
                body_list = Body::multipart(header.clone(), body.clone(), body_list.clone());
            }
            "application/x-www-form-urlencoded" => {
                if content_length == 0 {
                    return body_list;
                }
                let text: String = body.iter().map(|&c| c as char).collect();


                let text: Vec<&str> = text.split("&").collect();
                for item in text.iter() {
                    let row: Vec<&str> = item.split("=").collect();
                    body_list["post"][row[0].clone()] = row[1].clone().into();
                }
            }
            "application/json" => {
                if content_length == 0 {
                    return body_list;
                }
                let text: String = body.iter().map(|&c| c as char).collect();
                match json::parse(&*text.clone()) {
                    Ok(e) => {
                        body_list["post"] = e.clone();
                    }
                    Err(_) => {
                        let str = unsafe { String::from_utf8_unchecked(body) };
                        match json::parse(&*str.clone()) {
                            Ok(e) => {
                                body_list["post"] = e;
                            }
                            Err(_) => {
                                body_list["post"] = object! {}
                            }
                        }
                    }
                }
            }
            _ => {
                // println!(">>>>>>> >>>>>>");
                // println!("{}", data);
                // println!(">>>>>>> >>>>>>");
            }
        }
        body_list
    }

    /// 数据提取
    pub fn multipart(header: JsonValue, data: Vec<u8>, mut body_list: JsonValue) -> JsonValue {
        let boundary = header["boundary"].as_str().unwrap();
        let text = unsafe { String::from_utf8_unchecked(data.clone()) };
        let text = text.trim_start_matches("\r\n");
        let text = text.trim_end_matches(format!("\r\n--{}--\r\n", boundary.clone()).as_str()).to_string();
        let fg = format!("--{}\r\n", boundary.clone());
        let list: Vec<&str> = text.split(fg.as_str().clone()).collect();
        let mut index = 0;
        let mut body = data[2 + fg.len()..].to_vec();
        while index < list.len() {
            let item = list[index].to_string();
            let item = item.trim_start_matches(boundary.clone());
            let len = item.len();
            if len == 0 {
                index += 1;
                continue;
            }
            match item.contains("filename=") {
                false => {
                    let row: Vec<&str> = item.split("\r\n\r\n").collect();
                    let field: Vec<&str> = row[0].split("\"").collect();
                    let name = field[1];
                    let row: Vec<&str> = row[1].split("\r\n").collect();
                    let value: Vec<&str> = row[0].split("\"").collect();
                    body_list["post"][name] = value[0].clone().into();
                }
                true => {
                    let text: Vec<&str> = item.split("\r\n\r\n").collect();
                    let body = text[1];
                    let file = body.trim_start_matches("\u{0}");
                    let file = file.trim_end_matches("\r\n");
                    let text: Vec<&str> = text[0].split("\r\n").collect();
                    let name: Vec<&str> = text[0].split("\"").collect();
                    let types: Vec<&str> = text[1].split(": ").collect();
                    let types = types[1];
                    let field = name[1];
                    let filename = name[3];
                    fn _content_type_mode(data: &str) -> String {
                        match data {
                            "image/png" => "png",
                            "image/jpeg" => "jpeg",
                            "image/jpg" => "jpg",
                            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" => "xlsx",
                            "image/x-icon" => "ico",
                            _ => "txt"
                        }.to_string().clone()
                    }
                    let mut file_data = object! {};
                    file_data["type"] = types.into();
                    file_data["name"] = filename.into();
                    file_data["size"] = file.len().into();


                    file_data["sha"] = df_crypto::sha::str_to_sha256(file).into();
                    file_data["mode"] = JsonValue::String(_content_type_mode(types.clone()).clone());

                    let temp_file = format!("{}.{}", file_data["sha"], file_data["mode"]);

                    let public = header["public"].as_str().unwrap();
                    let temp = format!("{}/../temp", public.clone());
                    let filename = format!("{}/../temp/{}", public.clone(), temp_file);
                    file_data["temp"] = filename.clone().into();

                    match DirBuilder::new().recursive(true).create(temp.clone()) {
                        Ok(_) => true,
                        Err(_) => false
                    };

                    match fs::write(file_data["temp"].as_str().unwrap().clone(), file.clone()) {
                        Ok(_) => {
                            if body_list["files"][field].is_empty() {
                                body_list["files"][field] = array![file_data.clone()];
                            } else {
                                body_list["files"][field].push(file_data.clone()).unwrap();
                            }
                            true
                        }
                        Err(_) => {
                            false
                        }
                    };
                }
            }
            index += 1;
            if index == list.len() {} else {
                body = body[len + fg.len()..].to_vec();
            }
        }
        body_list
    }
    pub fn query(data: String) -> JsonValue {
        let mut list = object! {};
        let query: Vec<&str> = data.split("?").collect();
        if query.len() == 1 {
            return list;
        }
        let query = query[1].clone();
        if query.is_empty() {
            return list;
        }
        let query: Vec<&str> = query.split("&").collect();

        for item in query.iter() {
            let row: Vec<&str> = item.split("=").collect();
            let key = row[0].clone();
            let value = row[1].clone();
            list[key] = value.into();
        }
        list
    }
}