Skip to main content

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