Line data Source code
1 : #ifndef HTTP_REQUEST_PARSER_HPP
2 : #define HTTP_REQUEST_PARSER_HPP
3 :
4 : #include <memory>
5 : #include <boost/logic/tribool.hpp>
6 : #include <boost/tuple/tuple.hpp>
7 : #include <boost/lexical_cast.hpp>
8 :
9 : namespace thinger::http {
10 :
11 : class http_request;
12 :
13 : /// Parser for incoming requests.
14 : class request_factory {
15 : public:
16 : /// Construct ready to parse the http_request method.
17 : request_factory();
18 :
19 : /// Parse some data. The tribool return value is true when a complete http_request
20 : /// has been parsed, false if the data is invalid, indeterminate when more
21 : /// data is required. The InputIterator return value indicates how much of the
22 : /// input has been consumed.
23 : template<typename InputIterator>
24 2256 : boost::tribool parse(InputIterator& begin, InputIterator end) {
25 105092 : while (begin != end) {
26 103750 : boost::tribool result = consume(*begin++);
27 : // parsed completed or parse failed
28 103750 : if (result || !result)
29 914 : return result;
30 : }
31 : // still not finished
32 1342 : return boost::indeterminate;
33 : }
34 :
35 854 : void set_headers_only(bool headers_only) {
36 854 : headers_only_ = headers_only;
37 854 : }
38 :
39 6 : bool get_headers_only() const {
40 6 : return headers_only_;
41 : }
42 :
43 : std::shared_ptr<http_request> consume_request();
44 :
45 :
46 : void on_http_method(const std::string& method);
47 :
48 : void on_http_status_code(unsigned short status_code);
49 :
50 : void on_http_uri(const std::string& uri);
51 :
52 : void on_http_major_version(uint8_t major);
53 :
54 : void on_http_minor_version(uint16_t minor);
55 :
56 : void on_http_header(const std::string& name, const std::string& value);
57 :
58 : void on_content(char content);
59 :
60 : size_t get_content_length();
61 :
62 : size_t get_content_read();
63 :
64 : bool empty_headers();
65 :
66 : private:
67 : /// Handle the next character of input.
68 : boost::tribool consume(char input);
69 :
70 : /// Check if a byte is an HTTP character.
71 : static bool is_char(int c);
72 :
73 : /// Check if a byte is an HTTP control character.
74 : static bool is_ctl(int c);
75 :
76 : /// Check if a byte is defined as an HTTP special character.
77 : static bool is_tspecial(int c);
78 :
79 : /// Check if a byte is a digit.
80 : static bool is_digit(int c);
81 :
82 : std::shared_ptr<http_request> req;
83 :
84 : std::string tempString1_;
85 : std::string tempString2_;
86 : size_t tempInt_;
87 : bool headers_only_ = false;
88 :
89 : /// The current state of the parser.
90 : enum state {
91 : method_start,
92 : method,
93 : uri,
94 : http_version_h,
95 : http_version_t_1,
96 : http_version_t_2,
97 : http_version_p,
98 : http_version_slash,
99 : http_version_major_start,
100 : http_version_major,
101 : http_version_minor_start,
102 : http_version_minor,
103 : expecting_newline_1,
104 : header_line_start,
105 : header_lws,
106 : header_name,
107 : space_before_header_value,
108 : header_value,
109 : expecting_newline_2,
110 : expecting_newline_3,
111 : content
112 : } state_;
113 : };
114 : }
115 :
116 : #endif // HTTP_REQUEST_PARSER_HPP
|