avx_browser/protocols/
mod.rs1use std::collections::BTreeMap;
24
25#[derive(Debug)]
27pub struct HttpProtocol {
28 pub version: HttpVersion,
29 pub persistent_connections: bool,
30 pub max_pipeline: usize,
31}
32
33#[derive(Debug, Clone, Copy, PartialEq)]
34pub enum HttpVersion {
35 Http10,
36 Http11,
37 Http2,
38 Http3, }
40
41impl HttpProtocol {
42 pub fn new() -> Self {
43 Self {
44 version: HttpVersion::Http11,
45 persistent_connections: true,
46 max_pipeline: 6,
47 }
48 }
49
50 pub fn build_request(
52 &self,
53 method: &str,
54 url: &str,
55 headers: &BTreeMap<String, String>,
56 body: &[u8],
57 ) -> Vec<u8> {
58 let mut request = format!("{} {} HTTP/1.1\r\n", method, url);
59
60 for (key, value) in headers {
62 request.push_str(&format!("{}: {}\r\n", key, value));
63 }
64
65 if !body.is_empty() {
67 request.push_str(&format!("Content-Length: {}\r\n", body.len()));
68 }
69
70 request.push_str("\r\n");
71
72 let mut result = request.into_bytes();
73 result.extend_from_slice(body);
74 result
75 }
76
77 pub fn parse_response(&self, data: &[u8]) -> Result<ParsedResponse, ProtocolError> {
79 let response_str = String::from_utf8_lossy(data);
80
81 let parts: Vec<&str> = response_str.splitn(2, "\r\n\r\n").collect();
83
84 if parts.is_empty() {
85 return Err(ProtocolError::InvalidResponse);
86 }
87
88 let lines: Vec<&str> = parts[0].lines().collect();
90 if lines.is_empty() {
91 return Err(ProtocolError::InvalidResponse);
92 }
93
94 let status_parts: Vec<&str> = lines[0].split_whitespace().collect();
95 let status_code = if status_parts.len() >= 2 {
96 status_parts[1].parse::<u16>().unwrap_or(500)
97 } else {
98 500
99 };
100
101 let mut headers = BTreeMap::new();
103 for line in lines.iter().skip(1) {
104 if let Some(pos) = line.find(':') {
105 let key = line[..pos].trim().to_string();
106 let value = line[pos + 1..].trim().to_string();
107 headers.insert(key, value);
108 }
109 }
110
111 let body = if parts.len() > 1 {
113 parts[1].as_bytes().to_vec()
114 } else {
115 Vec::new()
116 };
117
118 Ok(ParsedResponse {
119 status_code,
120 headers,
121 body,
122 })
123 }
124}
125
126#[derive(Debug)]
127pub struct ParsedResponse {
128 pub status_code: u16,
129 pub headers: BTreeMap<String, String>,
130 pub body: Vec<u8>,
131}
132
133#[derive(Debug)]
143pub struct QuicProtocol {
144 pub connection_id: u64,
145 pub zero_rtt_enabled: bool,
146}
147
148impl QuicProtocol {
149 pub fn new() -> Self {
150 Self {
151 connection_id: 0,
152 zero_rtt_enabled: true,
153 }
154 }
155
156 pub fn connect(&mut self, _server: &str) -> Result<(), ProtocolError> {
162 self.connection_id = generate_connection_id();
163 Ok(())
164 }
165}
166
167#[derive(Debug)]
171pub struct DohProtocol {
172 pub resolver: String, }
174
175impl DohProtocol {
176 pub fn new() -> Self {
177 Self {
178 resolver: "https://1.1.1.1/dns-query".to_string(), }
180 }
181
182 pub fn resolve(&self, _domain: &str) -> Result<Vec<[u8; 4]>, ProtocolError> {
184 Ok(vec![[127, 0, 0, 1]])
187 }
188}
189
190#[derive(Debug)]
192pub struct WebSocketProtocol {
193 pub is_connected: bool,
194 pub frame_queue: Vec<WebSocketFrame>,
195}
196
197#[derive(Debug, Clone)]
198pub struct WebSocketFrame {
199 pub opcode: u8,
200 pub payload: Vec<u8>,
201 pub is_final: bool,
202}
203
204impl WebSocketProtocol {
205 pub fn new() -> Self {
206 Self {
207 is_connected: false,
208 frame_queue: Vec::new(),
209 }
210 }
211
212 pub fn send_frame(&mut self, data: Vec<u8>) {
213 self.frame_queue.push(WebSocketFrame {
214 opcode: 0x1, payload: data,
216 is_final: true,
217 });
218 }
219}
220
221#[derive(Debug)]
222pub enum ProtocolError {
223 InvalidResponse,
224 ConnectionFailed,
225 TimeoutError,
226}
227
228fn generate_connection_id() -> u64 {
229 12345
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236
237 #[test]
238 fn test_http_request_building() {
239 let protocol = HttpProtocol::new();
240 let mut headers = BTreeMap::new();
241 headers.insert("Host".to_string(), "example.com".to_string());
242
243 let request = protocol.build_request("GET", "/", &headers, b"");
244 let request_str = String::from_utf8_lossy(&request);
245
246 assert!(request_str.contains("GET / HTTP/1.1"));
247 assert!(request_str.contains("Host: example.com"));
248 }
249
250 #[test]
251 fn test_doh_resolver() {
252 let doh = DohProtocol::new();
253 assert!(doh.resolver.starts_with("https://"));
254 }
255}
256
257
258
259
260