1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::sync::{Arc, Mutex};

use std::io::Write;
use std::str::FromStr;

use httparse;

use server::Stream;
use error::Result;
use error::Error;

pub use self::request::Request;
pub use self::response::Response;
pub use self::http_code::StatusCode;
pub use self::http_method::Method;
use self::http_date::HTTPDate;

mod http_code;
mod http_date;
mod http_method;
mod request;
mod response;

pub struct Http {
    stream: Arc<Mutex<Stream>>,
}

impl Http {
    pub fn new(stream: Arc<Mutex<Stream>>) -> Http {
        Http {
            stream: stream,
        }
    }

    pub fn decode(&mut self) -> Result<Option<Request>> {
        let mut stream = self.stream.lock().unwrap();

        let (method, path, headers, amt) = {
            let mut headers = [httparse::EMPTY_HEADER; 24];
            let mut req = httparse::Request::new(&mut headers);
            let res = req.parse(&mut stream.reader)?;

            let amt = match res {
                httparse::Status::Complete(amt) => amt,
                httparse::Status::Partial => return Err(Error::Error("Http paser error".to_owned()))
            };

            let method = req.method.unwrap().to_owned();
            let path = req.path.unwrap().to_owned();
            let headers = req.headers.iter().map(|h| (h.name.to_owned(), String::from_utf8_lossy(h.value).to_string())).collect();

            (method, path, headers, amt)
        };

        let remote_addr = stream.remote_addr();

        let mut request = Request::new(
            method.parse().unwrap(),
            path,
            headers,
            remote_addr,
            Vec::new()
        );

        if let Some(len) = request.get_header("Content-Length") {
            let len: usize = usize::from_str(&len)?;
            if len > stream.reader.len() - amt {
                return Ok(None)
            }
        }

        request.data = stream.reader.split_off(amt);
        stream.reader.clear();

        Ok(Some(request))
    }

    pub fn encode(&mut self, response: Response) {
        let mut stream = self.stream.lock().unwrap();

        write!(stream, "HTTP/1.1 {} {}\r\n", response.status_code.0, response.status_code.default_reason_phrase()).unwrap();
        write!(stream, "Data: {}\r\n", HTTPDate::new().to_string()).unwrap();
        write!(stream, "Server: Sincere\r\n").unwrap();

        if let Some(data_length) = response.data_length {
            write!(stream, "Content-Length: {}\r\n", data_length).unwrap();
        }

        for (key, value) in response.headers {
            write!(stream, "{}: {}\r\n", key, value).unwrap();
        }

        write!(stream, "\r\n").unwrap();

        stream.write(&response.data).unwrap();
    }
}