reifydb_network/http/
response.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use std::collections::HashMap;
5
6#[derive(Debug, Clone)]
7pub struct HttpResponse {
8	pub status_code: u16,
9	pub status_text: String,
10	pub headers: HashMap<String, String>,
11	pub body: Vec<u8>,
12}
13
14impl HttpResponse {
15	pub fn new(status_code: u16, status_text: String) -> Self {
16		Self {
17			status_code,
18			status_text,
19			headers: HashMap::new(),
20			body: Vec::new(),
21		}
22	}
23
24	pub fn ok() -> Self {
25		Self::new(200, "OK".to_string())
26	}
27
28	pub fn not_found() -> Self {
29		Self::new(404, "Not Found".to_string())
30	}
31
32	pub fn bad_request() -> Self {
33		Self::new(400, "Bad Request".to_string())
34	}
35
36	pub fn internal_server_error() -> Self {
37		Self::new(500, "Internal Server Error".to_string())
38	}
39
40	pub fn with_body(mut self, body: Vec<u8>) -> Self {
41		self.body = body;
42		self
43	}
44
45	pub fn with_json(mut self, json: &str) -> Self {
46		self.headers.insert("Content-Type".to_string(), "application/json".to_string());
47		self.body = json.as_bytes().to_vec();
48		self
49	}
50
51	pub fn with_html(mut self, html: &str) -> Self {
52		self.headers.insert("Content-Type".to_string(), "text/html; charset=utf-8".to_string());
53		self.body = html.as_bytes().to_vec();
54		self
55	}
56
57	pub fn with_header(mut self, key: String, value: String) -> Self {
58		self.headers.insert(key, value);
59		self
60	}
61
62	pub fn with_cors_allow_all(mut self) -> Self {
63		self.headers.insert("Access-Control-Allow-Origin".to_string(), "*".to_string());
64		self.headers.insert(
65			"Access-Control-Allow-Methods".to_string(),
66			"GET, POST, PUT, DELETE, OPTIONS".to_string(),
67		);
68		self.headers.insert("Access-Control-Allow-Headers".to_string(), "*".to_string());
69		self.headers.insert("Access-Control-Max-Age".to_string(), "86400".to_string());
70		self
71	}
72
73	pub fn to_bytes(&self) -> Vec<u8> {
74		let mut response = format!("HTTP/1.1 {} {}\r\n", self.status_code, self.status_text);
75
76		// Add content-length header
77		response.push_str(&format!("Content-Length: {}\r\n", self.body.len()));
78
79		// Add custom headers
80		for (key, value) in &self.headers {
81			response.push_str(&format!("{}: {}\r\n", key, value));
82		}
83
84		// End headers
85		response.push_str("\r\n");
86
87		// Combine header and body
88		let mut bytes = response.into_bytes();
89		bytes.extend_from_slice(&self.body);
90		bytes
91	}
92}