http_pull_parser/
parser.rs

1use std::fmt;
2use std;
3use http_parser::{HttpParser, HttpParserType};
4use token::HttpToken;
5use parser_handler::{ParserHandler, ParserType};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
8pub struct ParserError {
9    pub error: String,
10}
11
12impl fmt::Display for ParserError {
13    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14        write!(f, "{}", self.error)
15    }
16}
17
18impl std::error::Error for ParserError {
19    fn description(&self) -> &str {
20        &self.error[..]
21    }
22}
23
24pub struct Parser {
25    parser: HttpParser,
26    handler: ParserHandler,
27}
28
29impl Parser {
30    pub fn request() -> Parser {
31        Parser {
32            parser: HttpParser::new(HttpParserType::Request),
33            handler: ParserHandler::new(ParserType::Request),
34        }
35    }
36
37    pub fn response() -> Parser {
38        Parser {
39            parser: HttpParser::new(HttpParserType::Response),
40            handler: ParserHandler::new(ParserType::Response),
41        }
42    }
43
44    pub fn next_token(&mut self, data: Option<&[u8]>)
45                      -> (Result<Option<HttpToken>, ParserError>, usize) {
46        let mut nparsed = 0;
47        if self.parser.errno.is_none() {
48            if let Some(data) = data {
49                if data.len() > 0 {
50                    nparsed = self.parser.execute(&mut self.handler, data);
51                }
52            }
53        }
54
55        if let Some(token) = self.handler.tokens.pop_front() {
56            return (Ok(Some(token)), nparsed);
57        } else {
58            if let Some(ref e) = self.parser.errno {
59                return (Err(ParserError { error: format!("{}", e) }), nparsed);
60            } else {
61                return (Ok(None), nparsed);
62            }
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70    use token::HttpToken;
71
72    #[test]
73    fn simple() {
74        let mut parser = Parser::request();
75        let mut tokens = Vec::new();
76        let mut http_request: Vec<_> = b"GET /te".iter()
77            .cloned().collect();
78
79        loop {
80            let (t, nparsed) = parser.next_token(Some(&http_request));
81            http_request.drain(..nparsed);
82            if let Ok(Some(t)) = t {
83                tokens.push(t);
84            } else {
85                break;
86            }
87        }
88
89        http_request.extend(b"st HTTP/1.0\r\n\
90                              Cont".iter().cloned());
91
92        loop {
93            let (t, nparsed) = parser.next_token(Some(&http_request));
94            http_request.drain(..nparsed);
95            if let Ok(Some(t)) = t {
96                tokens.push(t);
97            } else {
98                break;
99            }
100        }
101
102        http_request.extend(b"ent-Length: 00".iter().cloned());
103
104        loop {
105            let (t, nparsed) = parser.next_token(Some(&http_request));
106            http_request.drain(..nparsed);
107            if let Ok(Some(t)) = t {
108                tokens.push(t);
109            } else {
110                break;
111            }
112        }
113
114        http_request.extend(b"00\r\n\r\n".iter().cloned());
115
116        loop {
117            let (t, nparsed) = parser.next_token(Some(&http_request));
118            http_request.drain(..nparsed);
119            if let Ok(Some(t)) = t {
120                tokens.push(t);
121            } else {
122                break;
123            }
124        }
125
126        assert_eq!(tokens,
127                   [HttpToken::Method("GET".to_string()),
128                    HttpToken::Url("/test".to_string()),
129                    HttpToken::Field("Content-Length".to_string(),
130                                     "0000".to_string()),
131                    HttpToken::EndOfMessage]);
132        assert_eq!(parser.next_token(None), (Ok(None), 0));
133    }
134}