Skip to main content

rust_web_server/app/
mod.rs

1#[cfg(test)]
2mod tests;
3
4pub mod controller;
5
6use crate::app::controller::favicon::FaviconController;
7use crate::app::controller::health::HealthController;
8use crate::app::controller::ready::ReadyController;
9use crate::app::controller::metrics::MetricsController;
10use crate::app::controller::file::initiate::FileUploadInitiateController;
11use crate::app::controller::form::get_method::FormGetMethodController;
12use crate::app::controller::form::multipart_enctype_post_method::FormMultipartEnctypePostMethodController;
13use crate::app::controller::form::url_encoded_enctype_post_method::FormUrlEncodedEnctypePostMethodController;
14use crate::app::controller::index::IndexController;
15use crate::app::controller::not_found::NotFoundController;
16use crate::app::controller::script::ScriptController;
17use crate::app::controller::static_resource::StaticResourceController;
18use crate::app::controller::style::StyleController;
19use crate::application::Application;
20use crate::controller::Controller;
21use crate::core::{New};
22use crate::header::Header;
23
24use crate::request::{Request};
25use crate::response::{Response, STATUS_CODE_REASON_PHRASE};
26use crate::server::ConnectionInfo;
27
28#[derive(Copy, Clone)]
29pub struct App {}
30
31impl New for App {
32    fn new() -> Self {
33        App{}
34    }
35}
36
37impl Application for App {
38    fn execute(&self, request: &Request, connection: &ConnectionInfo) -> Result<Response, String> {
39        let header_list = Header::get_header_list(&request);
40
41        let mut response: Response = Response::get_response(
42            STATUS_CODE_REASON_PHRASE.n501_not_implemented,
43            Some(header_list),
44            None
45        );
46
47
48
49        if IndexController::is_matching(&request, connection) {
50            response = IndexController::process(&request, response, connection);
51            return Ok(response)
52        }
53
54        if StyleController::is_matching(&request, connection) {
55            response = StyleController::process(&request, response, connection);
56            return Ok(response)
57        }
58
59        if ScriptController::is_matching(&request, connection) {
60            response = ScriptController::process(&request, response, connection);
61            return Ok(response)
62        }
63
64        if FileUploadInitiateController::is_matching(&request, connection) {
65            response = FileUploadInitiateController::process(&request, response, connection);
66            return Ok(response)
67        }
68
69        if FormUrlEncodedEnctypePostMethodController::is_matching(&request, connection) {
70            response = FormUrlEncodedEnctypePostMethodController::process(&request, response, connection);
71            return Ok(response)
72        }
73
74        if FormGetMethodController::is_matching(&request, connection) {
75            response = FormGetMethodController::process(&request, response, connection);
76            return Ok(response)
77        }
78
79        if FormMultipartEnctypePostMethodController::is_matching(&request, connection) {
80            response = FormMultipartEnctypePostMethodController::process(&request, response, connection);
81            return Ok(response)
82        }
83
84        if HealthController::is_matching(&request, connection) {
85            response = HealthController::process(&request, response, connection);
86            return Ok(response)
87        }
88
89        if ReadyController::is_matching(&request, connection) {
90            response = ReadyController::process(&request, response, connection);
91            return Ok(response)
92        }
93
94        if MetricsController::is_matching(&request, connection) {
95            response = MetricsController::process(&request, response, connection);
96            return Ok(response)
97        }
98
99        if FaviconController::is_matching(&request, connection) {
100            response = FaviconController::process(&request, response, connection);
101            return Ok(response)
102        }
103
104        if StaticResourceController::is_matching(&request, connection) {
105            response = StaticResourceController::process(&request, response, connection);
106            return Ok(response)
107        }
108
109        if NotFoundController::is_matching(&request, connection) {
110            response = NotFoundController::process(&request, response, connection);
111            return Ok(response)
112        }
113
114
115        Ok(response)
116    }
117}
118
119impl App {
120    /// Dispatch `request` through the controller chain and return the response.
121    ///
122    /// This is a convenience wrapper over [`Application::execute`] that uses a
123    /// synthetic loopback [`ConnectionInfo`]. Use it in tests or when no real
124    /// connection context is available. Prefer [`TestClient`] for structured
125    /// test code.
126    ///
127    /// [`TestClient`]: crate::test_client::TestClient
128    pub fn handle_request(request: Request) -> (Response, Request) {
129        use crate::server::Address;
130        let conn = ConnectionInfo {
131            client: Address { ip: "127.0.0.1".to_string(), port: 0 },
132            server: Address { ip: "127.0.0.1".to_string(), port: 7878 },
133            request_size: 16000,
134        };
135        let app = App::new();
136        let response = app.execute(&request, &conn).unwrap_or_else(|_| {
137            let header_list = Header::get_header_list(&request);
138            Response::get_response(
139                STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
140                Some(header_list),
141                None,
142            )
143        });
144        (response, request)
145    }
146}