Skip to main content

relay_core_lib/proxy/
body_codec.rs

1use data_encoding::BASE64;
2
3/// Helper to process body bytes into BodyData content and encoding
4pub fn process_body(bytes: &[u8], headers: &[(String, String)]) -> (String, String) {
5    // 1. Check content-type header
6    let content_type = headers.iter()
7        .find(|(k, _)| k.eq_ignore_ascii_case("content-type"))
8        .map(|(_, v)| v.to_lowercase())
9        .unwrap_or_default();
10
11    // Heuristic 1: If explicit charset is present, treat as text
12    if content_type.contains("charset=utf-8") || content_type.contains("charset=us-ascii") || content_type.contains("text/") || content_type.contains("application/json") || content_type.contains("application/xml") || content_type.contains("application/javascript") {
13        // Try UTF-8 decode first to be safe, if fails, fallback to base64
14        match std::str::from_utf8(bytes) {
15            Ok(s) => return ("utf-8".to_string(), s.to_string()),
16            Err(_) => return ("base64".to_string(), BASE64.encode(bytes)),
17        }
18    }
19
20    // Heuristic 2: Known binary types
21    if content_type.starts_with("image/") || 
22       content_type.starts_with("audio/") || 
23       content_type.starts_with("video/") ||
24       content_type.contains("application/octet-stream") ||
25       content_type.contains("application/pdf") ||
26       content_type.contains("application/zip") {
27        return ("base64".to_string(), BASE64.encode(bytes));
28    }
29
30    // Heuristic 3: Try UTF-8 decode as fallback
31    match std::str::from_utf8(bytes) {
32        Ok(s) => ("utf-8".to_string(), s.to_string()),
33        Err(_) => ("base64".to_string(), BASE64.encode(bytes)),
34    }
35}