dynamic/
dynamic.rs

1extern crate milstian_internet_framework;
2
3use std::collections::HashMap;
4use std::net::SocketAddr;
5use std::thread;
6use std::time::Duration;
7
8use milstian_internet_framework::application_layer::http::request;
9use milstian_internet_framework::application_layer::http::request::BodyContentType;
10use milstian_internet_framework::application_layer::http::response;
11use milstian_internet_framework::response::tcp::http::ResponderInterface;
12use milstian_internet_framework::{Application, Config};
13
14#[derive(Clone)]
15pub struct Responder {
16    pub route: Option<String>,
17}
18
19impl Responder {
20    pub fn new() -> Responder {
21        Responder { route: None }
22    }
23}
24
25impl ResponderInterface for Responder {
26    fn matches(
27        &mut self,
28        request_message: &request::Message,
29        _application: &Application,
30        _socket: &SocketAddr,
31        _overflow_bytes: &u64,
32    ) -> bool {
33        match request_message.request_line.query_arguments.get("test") {
34            Some(value) => {
35                self.route = Some(value.clone());
36                return true;
37            }
38            None => {
39                return false;
40            }
41        }
42    }
43
44    fn respond(
45        &self,
46        request_message: &request::Message,
47        _application: &Application,
48        _socket: &SocketAddr,
49        overflow_bytes: &u64,
50    ) -> Result<response::Message, String> {
51        if let Some(route) = &self.route {
52            let protocol =
53                request::Message::get_protocol_text(&request_message.request_line.protocol);
54            let mut headers: HashMap<String, String> = HashMap::new();
55            headers.insert("Content-Type".to_string(), "text/html".to_string());
56
57            let upload = match request_message.body {
58                BodyContentType::MultiPart(ref body) => match body.get(&"file".to_string()) {
59                    Some(value) => match String::from_utf8(value.body.clone()) {
60                        Ok(utf8_value) => utf8_value,
61                        _ => format!("no UTF-8 file data in: {:?}", &value.body),
62                    },
63                    _ => format!("no file data in {:?}", request_message),
64                },
65                _ => "no data".to_string(),
66            };
67
68            let upload2 = match request_message.body {
69                BodyContentType::MultiPart(ref body) => match body.get(&"file2".to_string()) {
70                    Some(value) => match String::from_utf8(value.body.clone()) {
71                        Ok(utf8_value) => utf8_value,
72                        _ => format!("no UTF-8 file data in: {:?}", &value.body),
73                    },
74                    _ => format!("no file data in {:?}", request_message),
75                },
76                _ => "no data".to_string(),
77            };
78
79            // NOTE uncomment to test concurrency
80            // thread::sleep(Duration::from_secs(2));
81
82            let mut overflow_upload = "Upload did not overflow server byte limit!";
83            if overflow_bytes > &0 {
84                overflow_upload = "Your upload exceeded server byte limit!";
85            }
86
87            let output = format!("<html><head><title>Milstian Internet Framework - Dynamic Example</title><link rel='stylesheet' href='/css/style.css' /></head><body><div class='wrapper'><h1>Milstian Web Framework</h1><img alt='' src='/img/logo1-modified.jpg' /><p><strong>Query argument:</strong> {}</p><div><strong>File upload 1:</strong><br /><pre>{}</pre></div><div><strong>File upload 2:</strong><br /><pre>{}</pre></div><h2>Dynamic Test</h2><form action='' method='post' enctype='multipart/form-data'><fieldset><legend>File upload</legend><div><label>Select file 1<br /><input type='file' name='file' /></label></div><div><label>Select file 2<br /><input type='file' name='file2' /></label></div><p>{}</p><div><input type='submit' value='Upload' /></div></fieldset></form></div></body></html>", route, &upload, &upload2, &overflow_upload);
88
89            return Ok(response::Message::new(
90                protocol.to_string(),
91                "200 OK".to_string(),
92                headers,
93                output.as_bytes().to_vec(),
94            ));
95        } else {
96            Err("No result".to_string())
97        }
98    }
99}
100
101fn main() {
102    let config = Config::from_env().expect("Failed to get configuration from environment");
103    Application::new(config).tcp_http_with_legacy_and_custom_responders(Box::new(Responder::new()));
104}