feather_runtime/http/
response.rs1use bytes::Bytes;
2use http::{HeaderMap, HeaderName, HeaderValue, StatusCode};
3use serde::Serialize;
4use std::{fmt::Display, fs::File, io::Read, str::FromStr};
5
6#[derive(Debug, Clone, Default)]
7pub struct Response {
8 pub status: StatusCode,
11 pub headers: HeaderMap,
14 pub body: Option<Bytes>,
18 pub version: http::Version,
20}
21
22impl Response {
23 pub fn set_status(&mut self, status: u16) -> &mut Response {
29 self.status = StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
30 self
31 }
32 pub fn add_header(&mut self, key: &str, value: &str) -> Option<()> {
35 if let Ok(val) = HeaderValue::from_str(value) {
36 if let Ok(key) = HeaderName::from_str(key) {
37 self.headers.insert(key, val);
38 }
39 return None;
40 }
41 None
42 }
43 pub fn to_raw(&self) -> Bytes {
45 let mut response = format!("HTTP/1.1 {} {}\r\n", self.status.as_u16(), self.status.canonical_reason().unwrap_or("Unknown")).into_bytes();
46
47 for (key, value) in &self.headers {
48 response.extend_from_slice(format!("{}: {}\r\n", key, value.to_str().unwrap()).as_bytes());
49 }
50
51 response.extend_from_slice(b"\r\n");
52
53 if let Some(ref body) = self.body {
54 response.extend_from_slice(body);
55 }
56
57 Bytes::from(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 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.insert("Content-Type", "text/plain;charset=utf-8".parse().unwrap());
74 self.headers.insert("Content-Length", self.body.as_ref().unwrap().len().to_string().parse().unwrap());
75 self.headers.insert("Date", chrono::Utc::now().to_string().parse().unwrap());
76 }
77 pub fn send_bytes(&mut self, data: impl Into<Vec<u8>>) {
79 let body = data.into();
80 self.headers.insert("Date", chrono::Utc::now().to_string().parse().unwrap());
81 self.body = Some(Bytes::from(body));
82 self.headers.insert("Content-Length", self.body.as_ref().unwrap().len().to_string().parse().unwrap());
83 }
84 pub fn send_html(&mut self, data: impl Into<String>) {
86 let body = data.into();
87 self.body = Some(Bytes::from(body));
88 self.headers.insert("Date", chrono::Utc::now().to_string().parse().unwrap());
89 self.headers.insert("Content-Type", "text/html".parse().unwrap());
90 self.headers.insert("Content-Length", self.body.as_ref().unwrap().len().to_string().parse().unwrap());
91 }
92
93 #[cfg(feature = "json")]
95 pub fn send_json<T: Serialize>(&mut self, data: T) {
96 match serde_json::to_string(&data) {
97 Ok(json) => {
98 self.body = Some(Bytes::from(json));
99 self.headers.insert("Date", chrono::Utc::now().to_string().parse().unwrap());
100 self.headers.insert("Content-Type", HeaderValue::from_static("application/json"));
101 self.headers.insert("Content-Length", self.body.as_ref().unwrap().len().to_string().parse().unwrap());
102 }
103 Err(_) => {
104 self.headers.insert("Date", chrono::Utc::now().to_string().parse().unwrap());
105 self.status = StatusCode::INTERNAL_SERVER_ERROR;
106 self.body = Some(Bytes::from("Internal Server Error"));
107 self.headers.insert("Content-Type", HeaderValue::from_static("text/plain"));
108 self.headers.insert("Content-Length", self.body.as_ref().unwrap().len().to_string().parse().unwrap());
109 }
110 }
111 }
112 pub fn send_file(&mut self, mut file: File) {
114 let mut buffer = Vec::new();
115 match file.read_to_end(&mut buffer) {
116 Ok(_) => {
117 self.body = Some(Bytes::from(buffer));
118 self.headers.insert("Date", chrono::Utc::now().to_string().parse().unwrap());
119 self.headers.insert("Content-Length", self.body.as_ref().unwrap().len().to_string().parse().unwrap());
120 }
121 Err(_) => {
122 self.status = StatusCode::INTERNAL_SERVER_ERROR;
123 self.body = Some(Bytes::from("Internal Server Error"));
124 }
125 }
126 }
127}
128
129impl Display for Response {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 write!(f, "{}", self.to_string())
132 }
133}