response.rs (6356B)
1 use std::str::FromStr; 2 3 use log::{debug}; 4 5 use tiny_http::{ 6 StatusCode, 7 Request, 8 Response, 9 Header, 10 HeaderField, 11 }; 12 use ascii::AsciiString; 13 14 use mime::Mime; 15 use mime::TEXT; 16 17 use crate::record::{ 18 RequestResult, 19 RequestResultType, 20 }; 21 22 23 pub fn origin_headers() -> Vec<Header> { 24 let mut headers: Vec<Header> = vec!(); 25 headers.push(Header{ 26 field: HeaderField::from_str("Access-Control-Allow-Origin").unwrap(), 27 value: AsciiString::from_ascii("*").unwrap(), 28 }); 29 headers.push(Header{ 30 field: HeaderField::from_str("Access-Control-Allow-Methods").unwrap(), 31 value: AsciiString::from_ascii("OPTIONS, PUT, GET").unwrap(), 32 }); 33 headers.push(Header{ 34 field: HeaderField::from_str("Access-Control-Allow-Headers").unwrap(), 35 value: AsciiString::from_ascii("Content-Type,Authorization,X-Filename,X-Wala-Trace").unwrap(), 36 }); 37 38 let server_header_v = format!("wala/{}, tiny_http (Rust)", env!("CARGO_PKG_VERSION")); 39 headers.push(Header{ 40 field: HeaderField::from_str("Server").unwrap(), 41 value: AsciiString::from_ascii(server_header_v).unwrap(), 42 }); 43 44 let mut cap_headers: Vec<String> = vec!(); 45 #[cfg(feature="pgpauth")] 46 { 47 let h = String::from("auth_pgp"); 48 cap_headers.push(h); 49 }; 50 51 #[cfg(feature="magic")] 52 { 53 let h = String::from("magic"); 54 cap_headers.push(h); 55 }; 56 57 #[cfg(feature="meta")] 58 { 59 let h = String::from("meta"); 60 cap_headers.push(h); 61 }; 62 63 if cap_headers.len() == 0 { 64 cap_headers.push(String::from("default")); 65 } 66 67 let v = cap_headers.join(","); 68 headers.push(Header{ 69 field: HeaderField::from_str("X-Wala-Cap").unwrap(), 70 value: AsciiString::from_ascii(v).unwrap(), 71 }); 72 headers 73 } 74 75 pub fn preflight_response(req: Request) { 76 let auth_origin_headers = origin_headers(); 77 let res_status = StatusCode(200); 78 let mut res = Response::empty(res_status); 79 for v in auth_origin_headers.iter() { 80 res.add_header(v.clone()); 81 } 82 req.respond(res); 83 debug!("served options request"); 84 return; 85 } 86 87 pub fn exec_response(req: Request, r: RequestResult) { 88 let res_status: StatusCode; 89 match r.typ { 90 RequestResultType::Found => { 91 res_status = StatusCode(200); 92 }, 93 RequestResultType::Changed => { 94 res_status = StatusCode(200); 95 }, 96 RequestResultType::WriteError => { 97 res_status = StatusCode(500); 98 }, 99 RequestResultType::AuthError => { 100 res_status = StatusCode(403); 101 }, 102 RequestResultType::InputError => { 103 res_status = StatusCode(400); 104 }, 105 RequestResultType::RecordError => { 106 res_status = StatusCode(404); 107 }, 108 _ => { 109 res_status = StatusCode(500); 110 }, 111 } 112 113 let auth_origin_headers = origin_headers(); 114 115 match r.v { 116 Some(v) => { 117 let mut res = Response::from_string(v); 118 res = res.with_status_code(res_status); 119 for v in auth_origin_headers.iter() { 120 res.add_header(v.clone()); 121 } 122 req.respond(res); 123 return; 124 }, 125 None => { 126 match r.f { 127 Some(v) => { 128 let mut content_type = String::new(); 129 let mut res = Response::from_file(v); 130 match r.m { 131 Some(v) => { 132 content_type.push_str(v.as_ref()); 133 let h = Header{ 134 field: HeaderField::from_str("Content-Type").unwrap(), 135 value: AsciiString::from_ascii(content_type.clone()).unwrap(), 136 }; 137 res.add_header(h); 138 }, 139 _ => { 140 content_type.push_str("application/octet-stream"); 141 }, 142 }; 143 match r.n { 144 Some(v) => { 145 let s = format!("attachment; filename=\"{}\"", &v); 146 let h = Header{ 147 field: HeaderField::from_str("Content-Disposition").unwrap(), 148 value: AsciiString::from_ascii(s.as_str()).unwrap(), 149 }; 150 res.add_header(h); 151 }, 152 _ => { 153 let m = mime::Mime::from_str(&content_type).unwrap(); 154 let s = match m.type_() { 155 mime::TEXT => { 156 String::from("inline") 157 }, 158 mime::IMAGE => { 159 String::from("inline") 160 }, 161 _ => { 162 String::from("attachment") 163 }, 164 }; 165 let h = Header{ 166 field: HeaderField::from_str("Content-Disposition").unwrap(), 167 value: AsciiString::from_ascii(s.as_str()).unwrap(), 168 }; 169 res.add_header(h); 170 }, 171 }; 172 173 res = res.with_status_code(res_status); 174 for v in auth_origin_headers.iter() { 175 res.add_header(v.clone()); 176 } 177 req.respond(res); 178 return; 179 }, 180 None => { 181 let mut res = Response::empty(res_status); 182 for v in auth_origin_headers.iter() { 183 res.add_header(v.clone()); 184 } 185 req.respond(res); 186 return; 187 }, 188 } 189 } 190 } 191 } 192 193 #[cfg(test)] 194 mod tests { 195 use tiny_http::Request; 196 use crate::record::RequestResult; 197 use super::exec_response; 198 199 #[test] 200 fn test_response_get_filename() { 201 // let r = Request{} 202 } 203 }