1extern crate libc;
2extern crate serde_json;
3
4use std::collections::HashMap;
5use std::error::Error;
6use std::ffi::CString;
7use std::ptr;
8use std::str;
9
10use serde_json::{Map, Value};
11
12pub struct CRequest {
13 pub method: CString,
14 pub uri: CString,
15 pub headers: HashMap<CString, CString>,
16 pub body: CString,
17}
18
19impl CRequest {
20 pub fn get_method(&self) -> Result<&str, str::Utf8Error> {
21 self.method.to_str()
22 }
23
24 pub fn get_uri(&self) -> Result<&str, str::Utf8Error> {
25 self.uri.to_str()
26 }
27
28 pub fn get_header(&self, key: &str) -> Option<&str> {
29 let key_cstring = match CString::new(key.as_bytes()) {
30 Ok(cs) => cs,
31 Err(_) => return None,
32 };
33 self.headers.get(&key_cstring).and_then(|v| v.to_str().ok())
34 }
35
36 pub fn get_headers(&self) -> Result<String, Box<dyn Error>> {
37 let mut map = Map::<String, Value>::new();
38 for (key, value) in self.headers.iter() {
39 map.insert(
40 key.to_str()?.to_string(),
41 Value::from(value.to_str()?.to_string()),
42 );
43 }
44 Ok(serde_json::to_string(&map)?)
45 }
46
47 pub fn get_body(&self) -> Result<&str, str::Utf8Error> {
48 self.body.to_str()
49 }
50}
51
52#[allow(dead_code)]
56#[no_mangle]
57pub unsafe extern "C" fn request_get_method(req: *const CRequest) -> *const libc::c_char {
58 let request = match req.as_ref() {
59 Some(r) => r,
60 None => {
61 return ptr::null();
62 }
63 };
64 request.method.as_ptr()
65}
66
67#[allow(dead_code)]
71#[no_mangle]
72pub unsafe extern "C" fn request_get_uri(req: *const CRequest) -> *const libc::c_char {
73 let request = match req.as_ref() {
74 Some(r) => r,
75 None => {
76 return ptr::null();
77 }
78 };
79 request.uri.as_ptr()
80}
81
82#[allow(dead_code)]
87#[no_mangle]
88pub unsafe extern "C" fn request_get_header(
89 req: *const CRequest,
90 key: *mut libc::c_char,
91) -> *const libc::c_char {
92 let request = match req.as_ref() {
93 Some(r) => r,
94 None => {
95 return ptr::null();
96 }
97 };
98 let cstring = CString::from_raw(key);
99 let header = match request.headers.get(&cstring) {
100 Some(h) => h,
101 None => {
102 return ptr::null();
103 }
104 };
105 header.as_ptr()
106}
107
108#[allow(dead_code)]
112#[no_mangle]
113pub unsafe extern "C" fn request_get_body(req: *const CRequest) -> *const libc::c_char {
114 let request = match req.as_ref() {
115 Some(r) => r,
116 None => {
117 return ptr::null();
118 }
119 };
120 request.body.as_ptr()
121}