rust_web_server/app/controller/directory_listing/
mod.rs1use file_ext::FileExt;
2use crate::controller::Controller;
3use crate::mime_type::MimeType;
4use crate::range::Range;
5use crate::request::{METHOD, Request};
6use crate::response::{Response, STATUS_CODE_REASON_PHRASE};
7use crate::server::ConnectionInfo;
8
9#[cfg(test)]
10mod tests;
11
12pub struct DirectoryListingAssetsController;
25
26impl DirectoryListingAssetsController {
27 pub const CSS_FILEPATH: &'static str = "rws-directory-listing.css";
28 pub const JS_FILEPATH: &'static str = "rws-directory-listing.js";
29
30 fn serve(filepath: &'static str, embedded: &'static [u8], mime_type: &str, mut response: Response) -> Response {
31 response.status_code = *STATUS_CODE_REASON_PHRASE.n200_ok.status_code;
32 response.reason_phrase = STATUS_CODE_REASON_PHRASE.n200_ok.reason_phrase.to_string();
33
34 if FileExt::does_file_exist(filepath) {
35 let boxed_content_range = Range::get_content_range_of_a_file(filepath);
36
37 if boxed_content_range.is_ok() {
38 response.content_range_list = vec![boxed_content_range.unwrap()];
39 } else {
40 let error = boxed_content_range.err().unwrap();
41 let content_range = Range::get_content_range(
42 Vec::from(error.as_bytes()),
43 MimeType::TEXT_HTML.to_string(),
44 );
45 response.content_range_list = vec![content_range];
46 response.status_code = *STATUS_CODE_REASON_PHRASE.n500_internal_server_error.status_code;
47 response.reason_phrase = STATUS_CODE_REASON_PHRASE.n500_internal_server_error.reason_phrase.to_string();
48 }
49 } else {
50 let content_range = Range::get_content_range(embedded.to_vec(), mime_type.to_string());
51 response.content_range_list = vec![content_range];
52 }
53
54 response
55 }
56}
57
58impl Controller for DirectoryListingAssetsController {
59 fn is_matching(request: &Request, _connection: &ConnectionInfo) -> bool {
60 request.method == METHOD.get
62 && matches!(request.request_uri.strip_prefix('/'), Some(p) if p == Self::CSS_FILEPATH || p == Self::JS_FILEPATH)
63 }
64
65 fn process(request: &Request, response: Response, _connection: &ConnectionInfo) -> Response {
66 if request.request_uri.strip_prefix('/') == Some(Self::CSS_FILEPATH) {
67 let embedded = include_bytes!("directory_listing.css");
68 Self::serve(Self::CSS_FILEPATH, embedded, MimeType::TEXT_CSS, response)
69 } else {
70 let embedded = include_bytes!("directory_listing.js");
71 Self::serve(Self::JS_FILEPATH, embedded, MimeType::TEXT_JAVASCRIPT, response)
72 }
73 }
74}