wala-rust

Content-adressed HTTP file server
Info | Log | Files | Refs | README | LICENSE

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 }