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