http_pull_parser/
parser.rs1use 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}