• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // request_parser.hpp
3 // ~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef HTTP_REQUEST_PARSER_HPP
12 #define HTTP_REQUEST_PARSER_HPP
13 
14 #include <boost/logic/tribool.hpp>
15 #include <boost/tuple/tuple.hpp>
16 
17 namespace http {
18 namespace server {
19 
20 struct request;
21 
22 /// Parser for incoming requests.
23 class request_parser
24 {
25 public:
26   /// Construct ready to parse the request method.
27   request_parser();
28 
29   /// Reset to initial parser state.
30   void reset();
31 
32   /// Parse some data. The tribool return value is true when a complete request
33   /// has been parsed, false if the data is invalid, indeterminate when more
34   /// data is required. The InputIterator return value indicates how much of the
35   /// input has been consumed.
36   template <typename InputIterator>
parse(request & req,InputIterator begin,InputIterator end)37   boost::tuple<boost::tribool, InputIterator> parse(request& req,
38       InputIterator begin, InputIterator end)
39   {
40     while (begin != end)
41     {
42       boost::tribool result = consume(req, *begin++);
43       if (result || !result)
44         return boost::make_tuple(result, begin);
45     }
46     boost::tribool result = boost::indeterminate;
47     return boost::make_tuple(result, begin);
48   }
49 
50 private:
51   /// Handle the next character of input.
52   boost::tribool consume(request& req, char input);
53 
54   /// Check if a byte is an HTTP character.
55   static bool is_char(int c);
56 
57   /// Check if a byte is an HTTP control character.
58   static bool is_ctl(int c);
59 
60   /// Check if a byte is defined as an HTTP tspecial character.
61   static bool is_tspecial(int c);
62 
63   /// Check if a byte is a digit.
64   static bool is_digit(int c);
65 
66   /// The current state of the parser.
67   enum state
68   {
69     method_start,
70     method,
71     uri,
72     http_version_h,
73     http_version_t_1,
74     http_version_t_2,
75     http_version_p,
76     http_version_slash,
77     http_version_major_start,
78     http_version_major,
79     http_version_minor_start,
80     http_version_minor,
81     expecting_newline_1,
82     header_line_start,
83     header_lws,
84     header_name,
85     space_before_header_value,
86     header_value,
87     expecting_newline_2,
88     expecting_newline_3
89   } state_;
90 };
91 
92 } // namespace server
93 } // namespace http
94 
95 #endif // HTTP_REQUEST_PARSER_HPP
96