request_parser.h 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //
  2. // request_parser.hpp
  3. // ~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2010 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 EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_PARSER_H
  11. #define EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_PARSER_H
  12. #include <boost/logic/tribool.hpp>
  13. #include <boost/tuple/tuple.hpp>
  14. namespace http_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. /// Parse some data. The tribool return value is true when a complete request
  25. /// has been parsed, false if the data is invalid, indeterminate when more
  26. /// data is required. The InputIterator return value indicates how much of the
  27. /// input has been consumed.
  28. template<typename InputIterator>
  29. boost::tuple<boost::tribool, InputIterator> parse(request& req,
  30. InputIterator begin, InputIterator end)
  31. {
  32. while(begin != end)
  33. {
  34. boost::tribool result = consume(req, *begin++);
  35. if(result || !result)
  36. return boost::make_tuple(result, begin);
  37. }
  38. boost::tribool result = boost::indeterminate;
  39. return boost::make_tuple(result, begin);
  40. }
  41. private:
  42. /// Handle the next character of input.
  43. boost::tribool consume(request& req, char input);
  44. /// Check if a byte is an HTTP character.
  45. static bool is_char(int c);
  46. /// Check if a byte is an HTTP control character.
  47. static bool is_ctl(int c);
  48. /// Check if a byte is defined as an HTTP tspecial character.
  49. static bool is_tspecial(int c);
  50. /// Check if a byte is a digit.
  51. static bool is_digit(int c);
  52. /// The current state of the parser.
  53. enum state
  54. {
  55. method_start,
  56. method,
  57. uri_start,
  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 http_server
  79. #endif // EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_PARSER_H