Add http::Response::format_default_response

This commit is contained in:
2021-05-16 12:34:25 +02:00
parent 782ad13e48
commit c3fe62275f

View File

@ -100,31 +100,39 @@ pub struct Status {
} }
impl Status { impl Status {
pub fn from_code(status_code: u16) -> Status { pub fn from_code(status_code: u16) -> Option<Status> {
for (code, class, msg, desc) in &consts::HTTP_STATUSES { for (code, class, msg, desc) in &consts::HTTP_STATUSES {
if *code == status_code { if *code == status_code {
return Status { return Some(Status {
code: status_code, code: status_code,
message: msg.to_string(), message: msg.to_string(),
desc, desc,
class: class.clone(), class: class.clone(),
}; });
} }
} }
panic!("invalid status code"); None
} }
pub fn new_custom(status_code: u16, message: &str) -> Status { pub fn new_custom(status_code: u16, message: &str) -> Status {
if status_code < 100 || status_code > 599 { if status_code < 100 || status_code > 599 {
panic!("invalid status code"); panic!("invalid status code");
} }
let status = Status::from_code(status_code); if let Some(status) = Status::from_code(status_code) {
Status { Status {
code: status_code, code: status_code,
message: message.to_string(), message: message.to_string(),
desc: status.desc, desc: status.desc,
class: status.class, class: status.class,
} }
} else {
Status {
code: status_code,
message: message.to_string(),
desc: "",
class: StatusClass::from_code(status_code),
}
}
} }
} }
@ -156,13 +164,13 @@ impl Response {
pub fn new() -> Response { pub fn new() -> Response {
Response { Response {
version: "1.1".to_string(), version: "1.1".to_string(),
status: Status::from_code(200), status: Status::from_code(200).unwrap(),
header_fields: Vec::new(), header_fields: Vec::new(),
} }
} }
pub fn status(&mut self, status_code: u16) { pub fn status(&mut self, status_code: u16) {
self.status = Status::from_code(status_code) self.status = Status::from_code(status_code).unwrap()
} }
pub fn add_header(&mut self, name: &str, value: &str) { pub fn add_header(&mut self, name: &str, value: &str) {
@ -197,33 +205,11 @@ impl Response {
let mut buf = None; let mut buf = None;
if let None = self.find_header("Content-Length") { if let None = self.find_header("Content-Length") {
let (doc, color_name, color) = match self.status.class { let new_buf = self.format_default_response();
StatusClass::Informational => (consts::INFO_DOCUMENT, "info", "#606060"), self.add_header(
StatusClass::Success => (consts::SUCCESS_DOCUMENT, "success", "#008000"), "Content-Length",
StatusClass::Redirection => (consts::WARNING_DOCUMENT, "warning", "#E0C000"), new_buf.as_bytes().len().to_string().as_str(),
StatusClass::ClientError => (consts::ERROR_DOCUMENT, "error", "#C00000"), );
StatusClass::ServerError => (consts::ERROR_DOCUMENT, "error", "#C00000"),
};
let new_buf = consts::DEFAULT_DOCUMENT
.replace("{status_code}", self.status.code.to_string().as_str())
.replace("{status_message}", self.status.message.as_str())
.replace("{hostname}", "localhost") // TODO hostname
.replace("{theme_color}", color)
.replace("{color_name}", color_name)
.replace("{server_str}", "Locutus server") // TODO server string
.replace(
"{doc}",
doc.replace("{code}", self.status.code.to_string().as_str())
.replace("{message}", self.status.message.as_str())
.replace("{desc}", self.status.desc)
.replace("{info}", "") // TODO info string
.as_str(),
)
.replace("{{", "{")
.replace("}}", "}");
self.add_header("Content-Length", new_buf.len().to_string().as_str());
self.add_header("Content-Type", "text/html; charset=utf-8"); self.add_header("Content-Type", "text/html; charset=utf-8");
buf = Some(new_buf); buf = Some(new_buf);
} }
@ -243,6 +229,34 @@ impl Response {
} }
Ok(()) Ok(())
} }
fn format_default_response(&self) -> String {
let (doc, color_name, color) = match self.status.class {
StatusClass::Informational => (consts::INFO_DOCUMENT, "info", "#606060"),
StatusClass::Success => (consts::SUCCESS_DOCUMENT, "success", "#008000"),
StatusClass::Redirection => (consts::WARNING_DOCUMENT, "warning", "#E0C000"),
StatusClass::ClientError => (consts::ERROR_DOCUMENT, "error", "#C00000"),
StatusClass::ServerError => (consts::ERROR_DOCUMENT, "error", "#C00000"),
};
consts::DEFAULT_DOCUMENT
.replace("{status_code}", self.status.code.to_string().as_str())
.replace("{status_message}", self.status.message.as_str())
.replace("{hostname}", "localhost") // TODO hostname
.replace("{theme_color}", color)
.replace("{color_name}", color_name)
.replace("{server_str}", "Locutus server") // TODO server string
.replace(
"{doc}",
doc.replace("{code}", self.status.code.to_string().as_str())
.replace("{message}", self.status.message.as_str())
.replace("{desc}", self.status.desc)
.replace("{info}", "") // TODO info string
.as_str(),
)
.replace("{{", "{")
.replace("}}", "}")
}
} }
impl Stream { impl Stream {