http_tunnel_common/protocol/
request.rs1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct HttpRequest {
7 pub request_id: String,
9
10 pub method: String,
12
13 pub uri: String,
16
17 pub headers: HashMap<String, Vec<String>>,
20
21 #[serde(default)]
24 pub body: String,
25
26 pub timestamp: u64,
28}
29
30impl HttpRequest {
31 pub fn new(method: String, uri: String, request_id: String, timestamp: u64) -> Self {
33 Self {
34 request_id,
35 method,
36 uri,
37 headers: HashMap::new(),
38 body: String::new(),
39 timestamp,
40 }
41 }
42
43 pub fn has_body(&self) -> bool {
45 !self.body.is_empty()
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test_http_request_creation() {
55 let req = HttpRequest::new(
56 "GET".to_string(),
57 "/api/users".to_string(),
58 "req_123".to_string(),
59 1234567890,
60 );
61
62 assert_eq!(req.method, "GET");
63 assert_eq!(req.uri, "/api/users");
64 assert_eq!(req.request_id, "req_123");
65 assert_eq!(req.timestamp, 1234567890);
66 assert!(req.headers.is_empty());
67 assert!(!req.has_body());
68 }
69
70 #[test]
71 fn test_http_request_with_headers() {
72 let mut headers = HashMap::new();
73 headers.insert(
74 "content-type".to_string(),
75 vec!["application/json".to_string()],
76 );
77 headers.insert(
78 "authorization".to_string(),
79 vec!["Bearer token123".to_string()],
80 );
81
82 let req = HttpRequest {
83 request_id: "req_123".to_string(),
84 method: "POST".to_string(),
85 uri: "/api/data".to_string(),
86 headers,
87 body: "eyJ0ZXN0IjoidmFsdWUifQ==".to_string(), timestamp: 1234567890,
89 };
90
91 assert_eq!(req.headers.len(), 2);
92 assert!(req.has_body());
93 }
94
95 #[test]
96 fn test_http_request_serialization() {
97 let mut headers = HashMap::new();
98 headers.insert("host".to_string(), vec!["example.com".to_string()]);
99
100 let req = HttpRequest {
101 request_id: "req_abc123".to_string(),
102 method: "GET".to_string(),
103 uri: "/path?query=value".to_string(),
104 headers,
105 body: String::new(),
106 timestamp: 1234567890000,
107 };
108
109 let json = serde_json::to_string(&req).unwrap();
110 assert!(json.contains(r#""request_id":"req_abc123"#));
111 assert!(json.contains(r#""method":"GET"#));
112 assert!(json.contains(r#""uri":"/path?query=value"#));
113
114 let parsed: HttpRequest = serde_json::from_str(&json).unwrap();
115 assert_eq!(parsed.request_id, req.request_id);
116 assert_eq!(parsed.method, req.method);
117 assert_eq!(parsed.uri, req.uri);
118 assert_eq!(parsed.timestamp, req.timestamp);
119 }
120
121 #[test]
122 fn test_http_request_multiple_header_values() {
123 let mut headers = HashMap::new();
124 headers.insert(
125 "cookie".to_string(),
126 vec!["session=abc".to_string(), "token=xyz".to_string()],
127 );
128
129 let req = HttpRequest {
130 request_id: "req_123".to_string(),
131 method: "GET".to_string(),
132 uri: "/".to_string(),
133 headers,
134 body: String::new(),
135 timestamp: 1234567890,
136 };
137
138 assert_eq!(req.headers.get("cookie").unwrap().len(), 2);
139
140 let json = serde_json::to_string(&req).unwrap();
141 let parsed: HttpRequest = serde_json::from_str(&json).unwrap();
142 assert_eq!(parsed.headers.get("cookie").unwrap().len(), 2);
143 }
144
145 #[test]
146 fn test_http_request_body_default() {
147 let json = r#"{
148 "request_id": "req_123",
149 "method": "GET",
150 "uri": "/test",
151 "headers": {},
152 "timestamp": 1234567890
153 }"#;
154
155 let parsed: HttpRequest = serde_json::from_str(json).unwrap();
156 assert_eq!(parsed.body, "");
157 assert!(!parsed.has_body());
158 }
159}