1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use std::net::SocketAddr;
use std::io::Read;

use hyper::server::request::Request as HyperRequest;
use hyper::method::Method;
use hyper::version::HttpVersion;
use hyper::header::Headers;
use hyper::uri::RequestUri;
use typemap::TypeMap;

/// Sapper request struct
pub struct SapperRequest<'a, 'b: 'a> {
    raw_req: Box<HyperRequest<'a, 'b>>,
    ext: TypeMap
} 

impl<'a, 'b: 'a> SapperRequest<'a, 'b> {
    /// constructor
    pub fn new(req: Box<HyperRequest<'a, 'b>>) -> SapperRequest<'a, 'b> {
        SapperRequest {
            raw_req: req,
            ext: TypeMap::new()
        }
    }
    
    /// get remote ip address
    pub fn remote_addr(&self) -> SocketAddr {
        self.raw_req.remote_addr
    }
    
    /// get http method
    pub fn method(&self) -> &Method {
        &self.raw_req.method
    }
    
    /// get http version
    pub fn version(&self) -> HttpVersion {
        self.raw_req.version
    }
    
    /// get http headers referrence
    pub fn headers(&self) -> &Headers {
        &self.raw_req.headers
    }
    
    /// get request path, and query parts
    // TODO: optimize to (&str, Option<&str>)
    // uri() -> (path, query)
    pub fn uri(&self) -> (String, Option<String>) {
        match self.raw_req.uri {
            RequestUri::AbsolutePath(ref uri) => {
                
                let pathvec: Vec<&str> = uri[..].split('?').collect();
                let path = pathvec[0].to_owned();
                let mut query = None;

                // if has query_string
                if pathvec.len() > 1 {
                    query = Some(pathvec[1].to_owned());
                }
                
                (path, query)
            },
            //_ => unreachable!()
            _ => {
                ("".to_owned(), None)
            }
        }
    }
    
    /// get the raw body vec of this request
    // here, we read it all for simplify upload biz
    pub fn body(&mut self) -> Option<Vec<u8>> {
        let mut body_vec: Vec<u8> = vec![];
        match self.raw_req.read_to_end(&mut body_vec) {
            Ok(n) => {
                if n > 0 {
                    Some(body_vec)
                }
                else {
                    None
                }
            },
            Err(_) => {
                println!("request body reading error!");
                None
            }
        }
    }
    
    /// get request struct ext ref
    pub fn ext(&self) -> &TypeMap {
        &self.ext
    }
    
    /// get request struct ext mut ref
    pub fn ext_mut(&mut self) -> &mut TypeMap {
        &mut self.ext
    }
}