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_SERVER4_REQUEST_PARSER_HPP 12 #define HTTP_SERVER4_REQUEST_PARSER_HPP 13 14 #include <string> 15 #include <boost/logic/tribool.hpp> 16 #include <boost/tuple/tuple.hpp> 17 #include <boost/asio/coroutine.hpp> 18 19 namespace http { 20 namespace server4 { 21 22 struct request; 23 24 /// Parser for incoming requests. 25 class request_parser : boost::asio::coroutine 26 { 27 public: 28 /// Parse some data. The tribool return value is true when a complete request 29 /// has been parsed, false if the data is invalid, indeterminate when more 30 /// data is required. The InputIterator return value indicates how much of the 31 /// input has been consumed. 32 template <typename InputIterator> parse(request & req,InputIterator begin,InputIterator end)33 boost::tuple<boost::tribool, InputIterator> parse(request& req, 34 InputIterator begin, InputIterator end) 35 { 36 while (begin != end) 37 { 38 boost::tribool result = consume(req, *begin++); 39 if (result || !result) 40 return boost::make_tuple(result, begin); 41 } 42 boost::tribool result = boost::indeterminate; 43 return boost::make_tuple(result, begin); 44 } 45 46 private: 47 /// The name of the content length header. 48 static std::string content_length_name_; 49 50 /// Content length as decoded from headers. Defaults to 0. 51 std::size_t content_length_; 52 53 /// Handle the next character of input. 54 boost::tribool consume(request& req, char input); 55 56 /// Check if a byte is an HTTP character. 57 static bool is_char(int c); 58 59 /// Check if a byte is an HTTP control character. 60 static bool is_ctl(int c); 61 62 /// Check if a byte is defined as an HTTP tspecial character. 63 static bool is_tspecial(int c); 64 65 /// Check if a byte is a digit. 66 static bool is_digit(int c); 67 68 /// Check if two characters are equal, without regard to case. 69 static bool tolower_compare(char a, char b); 70 71 /// Check whether the two request header names match. 72 bool headers_equal(const std::string& a, const std::string& b); 73 }; 74 75 } // namespace server4 76 } // namespace http 77 78 #endif // HTTP_SERVER4_REQUEST_PARSER_HPP 79