little_hyper/
response.rs

1use crate::Headers;
2use std::io::prelude::*;
3use std::net::TcpStream;
4
5/// Response
6///
7///
8#[derive(Debug)]
9pub struct Response {
10    stream: TcpStream,
11    pub headers: Headers,
12    contents: String,
13    status_code: usize,
14}
15
16impl Response {
17    pub fn new(stream: TcpStream) -> Self {
18        Self {
19            stream,
20            headers: Headers::default(),
21            contents: String::new(),
22            status_code: 200,
23        }
24    }
25
26    // /// Get Headers
27    // ///
28    // pub fn get_headers(&self) -> &Headers {
29    //     &self.headers
30    // }
31    // /// Get Header
32    // ///
33    // /// Get header value.
34    // pub fn get_header(&self, key: &str) -> Option<&String> {
35    //     self.headers.get(key)
36    // }
37    // /// Set Header
38    // ///
39    // /// Set header value.
40    // pub fn set_header(&mut self, key: &str, value: &str) {
41    //     self.headers.set(key, value);
42    // }
43    /// Set Content Type
44    ///
45    /// Set content type in header.
46    pub fn set_content_type(&mut self, content_type: &str) {
47        self.headers.set_content_type(content_type);
48    }
49
50    /// Status
51    ///
52    /// Get status code.
53    pub fn status(&self) -> usize {
54        self.status_code
55    }
56
57    /// Set Status
58    ///
59    /// Set status code.
60    pub fn set_status(&mut self, status_code: usize) {
61        self.status_code = status_code;
62    }
63}
64
65impl Response {
66    /// Raw Response
67    ///
68    /// That will send back to client.
69    fn raw_response(&self) -> String {
70        format!(
71            "{version} {status_code} {status_phrase}\r\n{headers}\r\n\r\n{contents}",
72            version = "HTTP/1.1",
73            status_code = self.status_code,
74            status_phrase = "OK",
75            headers = self.headers.raw_headers(),
76            contents = self.contents
77        )
78    }
79
80    /// Write
81    ///
82    /// Write data to client and flush out.
83    fn write(&mut self, contents: &str) {
84        // Set content and content len.
85        self.contents.push_str(contents);
86        self.headers.set_content_len(&self.contents.len().to_string());
87
88        // Set content type, If there in None.
89        if self.headers.content_type().is_none() {
90            self.headers.set_content_type("plain/text");
91        }
92
93        self.stream
94            .write_all(self.raw_response().as_bytes())
95            .expect("ERROR: WriteResponse.");
96        self.stream.flush().expect("ERROR: FlushResponse.");
97    }
98
99    /// Send
100    ///
101    /// Send data to client.
102    pub fn send(&mut self, data: &str) {
103        self.write(data);
104    }
105
106    /// Json
107    ///
108    /// Send JSON file.
109    pub fn json(&mut self, json: &str) {
110        self.set_content_type("application/json");
111
112        self.write(json);
113    }
114
115    /// Html
116    ///
117    /// Send HTML file.
118    pub fn html(&mut self, html: &str) {
119        self.set_content_type("text/html");
120
121        self.write(html);
122    }
123
124    /// File
125    ///
126    /// Send File contents.
127    ///
128    /// - `Content-Type` file extension or text/html.
129    pub fn file(&mut self, path: &str) {
130        self.set_content_type("plain/text");
131
132        let contents = std::fs::read_to_string(path).expect("ERROR: ReadFile.");
133
134        self.write(&contents)
135    }
136}