rust_web_server/app/controller/file/initiate/
mod.rs

1use std::collections::HashMap;
2use crate::controller::Controller;
3use crate::mime_type::MimeType;
4use crate::range::{ContentRange, Range};
5use crate::request::{METHOD, Request};
6use crate::response::{Response, STATUS_CODE_REASON_PHRASE};
7use crate::symbol::SYMBOL;
8use crate::entry_point::get_request_allocation_size;
9use crate::server::ConnectionInfo;
10
11pub struct FileUpload {
12    pub name: String,
13    pub last_modified: u128,
14    pub size: u128
15}
16
17pub struct FileUploadInitiateController;
18
19impl Controller for FileUploadInitiateController {
20    fn is_matching(request: &Request, _connection: &ConnectionInfo) -> bool {
21        let boxed_path = request.get_uri_path();
22        if boxed_path.is_err() {
23            let message = format!("unable to get path {} {} {}", request.method, request.request_uri, boxed_path.err().unwrap());
24            eprintln!("{}", message);
25            return false
26        }
27
28        let path = boxed_path.unwrap();
29
30        path == "/file-upload/initiate" && request.method == METHOD.post
31    }
32
33    fn process(_request: &Request, mut response: Response, _connection: &ConnectionInfo) -> Response {
34        response.status_code = *STATUS_CODE_REASON_PHRASE.n400_bad_request.status_code;
35        response.reason_phrase = STATUS_CODE_REASON_PHRASE.n400_bad_request.reason_phrase.to_string();
36
37
38        let boxed_query_option = _request.get_query();
39        if boxed_query_option.is_err() {
40            let error_message = boxed_query_option.clone().err().unwrap().to_string();
41            eprintln!("unable to extract query from url: {}", error_message)
42        }
43        let query_option = boxed_query_option.unwrap();
44        if query_option.is_none() {
45            return response;
46        }
47
48        let form: HashMap<String, String> = query_option.unwrap();
49        if form.get("name").is_none() {
50            return response;
51        }
52        if form.get("lastModified").is_none() {
53            return response;
54        }
55        if form.get("size").is_none() {
56            return response;
57        }
58
59
60        let mut formatted_list : Vec<String> = vec![];
61        for (key, value) in form.into_iter() {
62            let formatted_output = format!("{} is {}{}", key, value, SYMBOL.new_line_carriage_return);
63            formatted_list.push(formatted_output);
64        }
65
66        let mut request_allocation_size = get_request_allocation_size();
67        let offset = 4000;
68        if request_allocation_size > offset {
69            request_allocation_size = get_request_allocation_size() - offset;
70        }
71        let formatted_output = format!("{} is {}{}", "request_allocation_size_in_bytes", request_allocation_size, SYMBOL.new_line_carriage_return);
72        formatted_list.push(formatted_output);
73
74
75        response.status_code = *STATUS_CODE_REASON_PHRASE.n200_ok.status_code;
76        response.reason_phrase = STATUS_CODE_REASON_PHRASE.n200_ok.reason_phrase.to_string();
77
78        let response_body = formatted_list.join(SYMBOL.empty_string);
79        response.content_range_list = vec![
80            ContentRange{
81                unit: Range::BYTES.to_string(),
82                range: Range { start: 0, end: response_body.len() as u64 },
83                size: response_body.len().to_string(),
84                body: Vec::from(response_body.as_bytes()),
85                content_type: MimeType::TEXT_PLAIN.to_string(),
86            }
87        ];
88
89        response
90    }
91}
92
93//backward compatability
94impl FileUploadInitiateController {
95
96    pub fn is_matching_request(request: &Request) -> bool {
97
98        let boxed_path = request.get_uri_path();
99        if boxed_path.is_err() {
100            let message = format!("unable to get path {} {} {}", request.method, request.request_uri, boxed_path.err().unwrap());
101            eprintln!("{}", message);
102            return false
103        }
104
105        let path = boxed_path.unwrap();
106
107        path == "/file-upload/initiate" && request.method == METHOD.post
108    }
109
110    pub fn process_request(_request: &Request, mut response: Response) -> Response {
111        response.status_code = *STATUS_CODE_REASON_PHRASE.n400_bad_request.status_code;
112        response.reason_phrase = STATUS_CODE_REASON_PHRASE.n400_bad_request.reason_phrase.to_string();
113
114
115        let boxed_query_option = _request.get_uri_query();
116        if boxed_query_option.is_err() {
117            let error_message = boxed_query_option.clone().err().unwrap().to_string();
118            eprintln!("unable to extract query from url: {}", error_message)
119        }
120        let query_option = boxed_query_option.unwrap();
121        if query_option.is_none() {
122            return response;
123        }
124
125        let form: HashMap<String, String> = query_option.unwrap();
126        if form.get("name").is_none() {
127            return response;
128        }
129        if form.get("lastModified").is_none() {
130            return response;
131        }
132        if form.get("size").is_none() {
133            return response;
134        }
135
136
137        let mut formatted_list : Vec<String> = vec![];
138        for (key, value) in form.into_iter() {
139            let formatted_output = format!("{} is {}{}", key, value, SYMBOL.new_line_carriage_return);
140            formatted_list.push(formatted_output);
141        }
142
143        let mut request_allocation_size = get_request_allocation_size();
144        let offset = 4000;
145        if request_allocation_size > offset {
146            request_allocation_size = get_request_allocation_size() - offset;
147        }
148        let formatted_output = format!("{} is {}{}", "request_allocation_size_in_bytes", request_allocation_size, SYMBOL.new_line_carriage_return);
149        formatted_list.push(formatted_output);
150
151
152        response.status_code = *STATUS_CODE_REASON_PHRASE.n200_ok.status_code;
153        response.reason_phrase = STATUS_CODE_REASON_PHRASE.n200_ok.reason_phrase.to_string();
154
155        let response_body = formatted_list.join(SYMBOL.empty_string);
156        response.content_range_list = vec![
157            ContentRange{
158                unit: Range::BYTES.to_string(),
159                range: Range { start: 0, end: response_body.len() as u64 },
160                size: response_body.len().to_string(),
161                body: Vec::from(response_body.as_bytes()),
162                content_type: MimeType::TEXT_PLAIN.to_string(),
163            }
164        ];
165
166        response
167    }
168}