feather_runtime/http/
response.rs1use bytes::Bytes;
2use http::{HeaderMap, HeaderName, HeaderValue, StatusCode};
3use serde::Serialize;
4use std::{fmt::Display, str::FromStr};
5
6#[derive(Debug, Clone, Default)]
7pub struct Response {
8 pub status: StatusCode,
11 pub headers: HeaderMap,
14 pub body: Option<Bytes>,
19 pub version: http::Version,
21}
22
23impl Response {
24 pub fn status(&mut self,status: u16) -> &mut Response {
30 self.status = StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
31 self
32 }
33 pub fn add_header(&mut self, key: &str, value: &str) -> Option<()> {
36 if let Ok(val) = HeaderValue::from_str(value) {
37 if let Ok(key) = HeaderName::from_str(key) {
38 self.headers.insert(key, val);
39 }
40 return None;
41 }
42 None
43 }
44 pub fn to_raw(&self) -> String {
46 let mut response = format!(
47 "HTTP/1.1 {} {}\r\n",
48 self.status.as_u16(),
49 self.status.canonical_reason().unwrap_or("Unknown")
50 );
51
52 for (key, value) in &self.headers {
53 response.push_str(&format!("{}: {}\r\n", key, value.to_str().unwrap()));
54 }
55
56 response.push_str("\r\n");
57
58 if let Some(ref body) = self.body {
59 response.push_str(&String::from_utf8_lossy(body));
60 }
61 response
62 }
63
64 pub fn to_bytes(&self) -> Bytes {
66 let mut response = self.to_string().into_bytes();
67 if let Some(ref body) = self.body {
68 response.extend_from_slice(body);
69 }
70
71 Bytes::from(response)
72 }
73
74 pub fn send_text(&mut self, data: impl Into<String>) {
75 let body = data.into();
76 self.body = Some(Bytes::from(body));
77 self.headers
78 .insert("Content-Type", "text/plain".parse().unwrap());
79 self.headers.insert(
80 "Content-Length",
81 self.body
82 .as_ref()
83 .unwrap()
84 .len()
85 .to_string()
86 .parse()
87 .unwrap(),
88 );
89 self.headers.insert(
90 "Date",
91 chrono::Utc::now().to_string().parse().unwrap()
92 );
93 }
94 pub fn send_bytes(&mut self, data: impl Into<Vec<u8>>) {
95 let body = data.into();
96 self.headers.insert(
97 "Date",
98 chrono::Utc::now().to_string().parse().unwrap()
99 );
100 self.body = Some(Bytes::from(body));
101 self.headers.insert(
102 "Content-Length",
103 self.body
104 .as_ref()
105 .unwrap()
106 .len()
107 .to_string()
108 .parse()
109 .unwrap(),
110 );
111 }
112 pub fn send_html(&mut self, data: impl Into<String>) {
113 let body = data.into();
114 self.body = Some(Bytes::from(body));
115 self.headers.insert(
116 "Date",
117 chrono::Utc::now().to_string().parse().unwrap()
118 );
119 self.headers
120 .insert("Content-Type", "text/html".parse().unwrap());
121 self.headers.insert(
122 "Content-Length",
123 self.body
124 .as_ref()
125 .unwrap()
126 .len()
127 .to_string()
128 .parse()
129 .unwrap(),
130 );
131 }
132 pub fn send_json<T: Serialize>(&mut self, data: T) {
133 match serde_json::to_string(&data) {
134 Ok(json) => {
135 self.body = Some(Bytes::from(json));
136 self.headers.insert(
137 "Date",
138 chrono::Utc::now().to_string().parse().unwrap()
139 );
140 self.headers
141 .insert("Content-Type", HeaderValue::from_static("application/json"));
142 self.headers.insert(
143 "Content-Length",
144 self.body
145 .as_ref()
146 .unwrap()
147 .len()
148 .to_string()
149 .parse()
150 .unwrap(),
151 );
152
153 }
154 Err(_) => {
155 self.headers.insert(
156 "Date",
157 chrono::Utc::now().to_string().parse().unwrap()
158 );
159 self.status = StatusCode::INTERNAL_SERVER_ERROR;
160 self.body = Some(Bytes::from("Internal Server Error"));
161 self.headers
162 .insert("Content-Type", HeaderValue::from_static("text/plain"));
163 self.headers.insert(
164 "Content-Length",
165 self.body
166 .as_ref()
167 .unwrap()
168 .len()
169 .to_string()
170 .parse()
171 .unwrap(),
172 );
173
174 }
175 }
176 }
177}
178
179
180impl Display for Response {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 write!(f,"{}", self.to_string())
183 }
184}