1use crate::Headers;
2use std::io::prelude::*;
3use std::net::TcpStream;
4
5#[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 pub fn set_content_type(&mut self, content_type: &str) {
47 self.headers.set_content_type(content_type);
48 }
49
50 pub fn status(&self) -> usize {
54 self.status_code
55 }
56
57 pub fn set_status(&mut self, status_code: usize) {
61 self.status_code = status_code;
62 }
63}
64
65impl Response {
66 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 fn write(&mut self, contents: &str) {
84 self.contents.push_str(contents);
86 self.headers.set_content_len(&self.contents.len().to_string());
87
88 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 pub fn send(&mut self, data: &str) {
103 self.write(data);
104 }
105
106 pub fn json(&mut self, json: &str) {
110 self.set_content_type("application/json");
111
112 self.write(json);
113 }
114
115 pub fn html(&mut self, html: &str) {
119 self.set_content_type("text/html");
120
121 self.write(html);
122 }
123
124 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}