taubyte_sdk/http/event/
headers.rs

1use super::{imports, Event, EventHeaders};
2use crate::errno::Error;
3use crate::utils::codec;
4
5impl Event {
6    pub fn headers(&self) -> EventHeaders {
7        EventHeaders {
8            event: (self.event),
9        }
10    }
11}
12
13impl EventHeaders {
14    fn set_unsafe(&self, key: &str, value: &str) -> Error {
15        #[allow(unused_unsafe)]
16        unsafe {
17            imports::eventHttpHeaderAdd(
18                self.event,
19                key.as_ptr(),
20                key.len(),
21                value.as_ptr(),
22                value.len(),
23            )
24        }
25    }
26
27    pub fn set(&self, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error>> {
28        if key.len() == 0 {
29            Err("Cannot set header with empty key".into())
30        } else {
31            let err0 = self.set_unsafe(key, value);
32            if err0.is_err() {
33                Err(format!("Setting header failed with: {}", err0).into())
34            } else {
35                Ok(())
36            }
37        }
38    }
39
40    fn get_size_unsafe(&self, size: *mut usize, key: &str) -> Error {
41        #[allow(unused_unsafe)]
42        unsafe {
43            imports::getHttpEventHeadersSize(self.event, size, key.as_ptr(), key.len())
44        }
45    }
46
47    fn get_unsafe(&self, key: &str, buf_ptr: &mut [u8], buf_size: usize) -> Error {
48        #[allow(unused_unsafe)]
49        unsafe {
50            imports::getHttpEventHeaders(
51                self.event,
52                key.as_ptr(),
53                key.len(),
54                buf_ptr.as_mut_ptr(),
55                buf_size,
56            )
57        }
58    }
59
60    // TODO this should return a Vec<String> need to change on vm and go-sdk
61    pub fn get(&self, key: &str) -> Result<String, Box<dyn std::error::Error>> {
62        let mut size: usize = 0;
63        let err0 = self.get_size_unsafe(&mut size, key);
64        if err0.is_err() {
65            return Err(format!(
66                "Getting Header Size By Name for key:`{}` Failed with: {}",
67                key, err0
68            )
69            .into());
70        }
71        if size == 0 {
72            return Ok("".to_string());
73        }
74
75        let mut buf: Vec<u8> = vec![0; size];
76        let err0 = self.get_unsafe(key, &mut buf, size);
77        if err0.is_err() {
78            return Err(format!(
79                "Getting Header By Name for key:`{}` Failed with: {}",
80                key, err0
81            )
82            .into());
83        }
84
85        let s = String::from_utf8(buf);
86        if s.is_err() {
87            Err(format!(
88                "Converting header slice to string slice failed with: {}",
89                s.err().unwrap()
90            )
91            .into())
92        } else {
93            Ok(s.unwrap())
94        }
95    }
96
97    fn list_size_unsafe(&self, size: *mut usize) -> Error {
98        #[allow(unused_unsafe)]
99        unsafe {
100            imports::getHttpEventRequestHeaderKeysSize(self.event, size)
101        }
102    }
103
104    fn list_unsafe(&self, buf_ptr: &mut [u8]) -> Error {
105        #[allow(unused_unsafe)]
106        unsafe {
107            imports::getHttpEventRequestHeaderKeys(self.event, buf_ptr.as_mut_ptr(), buf_ptr.len())
108        }
109    }
110
111    pub fn list(&self) -> Result<Vec<String>, Box<dyn std::error::Error>> {
112        let mut size: usize = 0;
113        let err0 = self.list_size_unsafe(&mut size);
114        if err0.is_err() {
115            return Err(format!("Getting Header Keys Size Failed with: {}", err0).into());
116        }
117        if size == 0 {
118            return Ok(Vec::<String>::new());
119        }
120
121        let mut buf: Vec<u8> = vec![0; size];
122        let err0 = self.list_unsafe(&mut buf);
123        if err0.is_err() {
124            Err(format!("Getting Header Keys Failed with: {}", err0).into())
125        } else {
126            Ok(codec::string_slice::to(buf))
127        }
128    }
129}
130
131#[cfg(test)]
132pub mod test {
133    use crate::http::Event;
134    pub static EXPECTED_ID: u32 = 0;
135    pub static EXPECTED_KEY: &str = "Content-Type";
136    pub static EXPECTED_VALUE: &str = "text/html";
137
138    #[test]
139    fn test_set() {
140        let http: Event = Event {
141            event: (EXPECTED_ID),
142        };
143
144        let headers = http.headers();
145        let err0 = headers.set(EXPECTED_KEY, EXPECTED_VALUE);
146        if err0.is_err() {
147            panic!("Error setting header: {}", err0.err().unwrap());
148        }
149    }
150
151    #[test]
152    fn test_get() {
153        let http: Event = Event {
154            event: (EXPECTED_ID),
155        };
156
157        let headers = http.headers();
158        let err = headers.set(EXPECTED_KEY, EXPECTED_VALUE);
159        if err.is_err() {
160            panic!("Error setting header: {}", err.err().unwrap());
161        }
162
163        let value = headers.get(EXPECTED_KEY).unwrap_or_else(|err| {
164            panic!("{}", err);
165        });
166
167        assert_eq!(value, EXPECTED_VALUE);
168    }
169
170    pub static EXPECTED_KEYS: [&str; 2] = ["Content-Type", "User-Agent"];
171    #[test]
172    fn test_list() {
173        let http: Event = Event {
174            event: (EXPECTED_ID),
175        };
176
177        let headers = http.headers();
178        let value = headers.list().unwrap_or_else(|err| {
179            panic!("{}", err);
180        });
181
182        assert_eq!(value.len(), EXPECTED_KEYS.len());
183        for i in 0..EXPECTED_KEYS.len() {
184            assert_eq!(value[i], EXPECTED_KEYS[i]);
185        }
186    }
187}