request_parser.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //
  2. // request_parser.hpp
  3. // ~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 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. #ifndef HTTP_REQUEST_PARSER_HPP
  11. #define HTTP_REQUEST_PARSER_HPP
  12. #include <tuple>
  13. namespace http {
  14. namespace server {
  15. struct request;
  16. /// Parser for incoming requests.
  17. class request_parser
  18. {
  19. public:
  20. /// Construct ready to parse the request method.
  21. request_parser();
  22. /// Reset to initial parser state.
  23. void reset();
  24. /// Result of parse.
  25. enum result_type { good, bad, indeterminate };
  26. /// Parse some data. The enum return value is good when a complete request has
  27. /// been parsed, bad if the data is invalid, indeterminate when more data is
  28. /// required. The InputIterator return value indicates how much of the input
  29. /// has been consumed.
  30. template <typename InputIterator>
  31. std::tuple<result_type, InputIterator> parse(request& req,
  32. InputIterator begin, InputIterator end)
  33. {
  34. while (begin != end)
  35. {
  36. result_type result = consume(req, *begin++);
  37. if (result == good || result == bad)
  38. return std::make_tuple(result, begin);
  39. }
  40. return std::make_tuple(indeterminate, begin);
  41. }
  42. private:
  43. /// Handle the next character of input.
  44. result_type consume(request& req, char input);
  45. /// Check if a byte is an HTTP character.
  46. static bool is_char(int c);
  47. /// Check if a byte is an HTTP control character.
  48. static bool is_ctl(int c);
  49. /// Check if a byte is defined as an HTTP tspecial character.
  50. static bool is_tspecial(int c);
  51. /// Check if a byte is a digit.
  52. static bool is_digit(int c);
  53. /// The current state of the parser.
  54. enum state
  55. {
  56. method_start,
  57. method,
  58. uri,
  59. http_version_h,
  60. http_version_t_1,
  61. http_version_t_2,
  62. http_version_p,
  63. http_version_slash,
  64. http_version_major_start,
  65. http_version_major,
  66. http_version_minor_start,
  67. http_version_minor,
  68. expecting_newline_1,
  69. header_line_start,
  70. header_lws,
  71. header_name,
  72. space_before_header_value,
  73. header_value,
  74. expecting_newline_2,
  75. expecting_newline_3
  76. } state_;
  77. };
  78. } // namespace server
  79. } // namespace http
  80. #endif // HTTP_REQUEST_PARSER_HPP