PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/boost/cgi/common/form_parser.hpp

http://github.com/darrengarvey/cgi
C++ Header | 174 lines | 74 code | 24 blank | 76 comment | 0 complexity | 4daa518945eec3d52bad8ff36ee848a6 MD5 | raw file
  1. // -- form_parser.hpp --
  2. //
  3. // Copyright (c) Darren Garvey 2007.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. ////////////////////////////////////////////////////////////////
  9. #ifndef CGI_DETAIL_FORM_PARSER_HPP_INCLUDED__
  10. #define CGI_DETAIL_FORM_PARSER_HPP_INCLUDED__
  11. #include "boost/cgi/detail/push_options.hpp"
  12. ///////////////////////////////////////////////////////////
  13. #include <set>
  14. #include <vector>
  15. #include <string>
  16. ///////////////////////////////////////////////////////////
  17. #include <boost/regex.hpp>
  18. #include <boost/function.hpp>
  19. #include <boost/asio/error.hpp>
  20. #include <boost/asio/buffer.hpp>
  21. #include <boost/algorithm/string/find.hpp>
  22. ///////////////////////////////////////////////////////////
  23. #include "boost/cgi/common/map.hpp"
  24. #include "boost/cgi/common/form_part.hpp"
  25. #include "boost/cgi/config.hpp"
  26. /// Set the directory that uploads are stored in.
  27. /**
  28. * When files are uploaded, using multipart/form-data, uploaded
  29. * files are saved to disk, rather than being held in memory.
  30. *
  31. * This macro determines where uploaded files are stored. It must
  32. * include a trailing slash (eg. "../upload/", which is the default).
  33. *
  34. * Your web server must run as a user that has read and write
  35. * permissions to this directory. You should never allow this to
  36. * be the same directory the FastCGI script is running in, or any
  37. * directory containing executable files.
  38. */
  39. #if !defined(BOOST_CGI_UPLOAD_DIRECTORY)
  40. # define BOOST_CGI_UPLOAD_DIRECTORY "../uploads/"
  41. #endif // BOOST_CGI_UPLOAD_DIRECTORY
  42. BOOST_CGI_NAMESPACE_BEGIN
  43. namespace common {
  44. /// A class for parsing POST data sent to a CGI process.
  45. /**
  46. * Construct this and then call `form_parser::parse` with an
  47. * instance of form_parser::context (or compatible struct).
  48. *
  49. * This is minimal and doesn't extract all meta-data yet, but
  50. * is known to work on Windows XP with MSVC9.0 and Ubuntu linux
  51. * with gcc 4.2.x and 4.3.x.
  52. *
  53. * Valid Form Encodings
  54. * > `application/x-www-form-urlencoded`
  55. * > `multipart/form-data`
  56. * > `application/json`
  57. *
  58. * File uploads (ie. in `multipart/form-data` forms) are saved
  59. * to disk. See the `BOOST_CGI_UPLOAD_DIRECTORY` macro.
  60. *
  61. * Should also work for HTTP POST data. JSON is just stored
  62. * in req.post["POSTDATA"].
  63. *
  64. */
  65. class form_parser
  66. {
  67. public:
  68. /// The callback functor to read more data.
  69. typedef
  70. boost::function<
  71. std::size_t (boost::system::error_code&)
  72. >
  73. callback_type;
  74. typedef common::map map_type;
  75. typedef common::form_part::string_type string_type;
  76. typedef common::form_part::buffer_type buffer_type;
  77. typedef boost::asio::mutable_buffers_1 mutable_buffers_type;
  78. /// The context used for parsing.
  79. struct context
  80. {
  81. string_type& content_type;
  82. string_type& content_length;
  83. buffer_type& buffer;
  84. std::size_t& bytes_left;
  85. common::post_map& data_map;
  86. common::upload_map& uploads_map;
  87. const callback_type callback;
  88. bool& stdin_parsed;
  89. // A random string, used for marking uploaded files.
  90. // Set this to something like the user's REMOTE_ADDR.
  91. string_type random_string;
  92. std::size_t offset;
  93. buffer_type::iterator pos;
  94. string_type boundary_marker;
  95. std::list<string_type> boundary_markers;
  96. };
  97. form_parser() : context_(NULL) {}
  98. /*
  99. form_parser(
  100. buffer_type&, common::post_map&, string_type const&
  101. , callback_type const&, std::size_t&, bool&);
  102. */
  103. string_type buffer_string()
  104. {
  105. return string_type(context_->buffer.begin() + context_->offset
  106. , context_->buffer.end());
  107. }
  108. /// Run the parser on the given `context`.
  109. boost::system::error_code
  110. parse(context ctx, boost::system::error_code& ec);
  111. /// URL-encoded forms.
  112. /**
  113. * Parse forms where the content-type is "application/www-url-encoded".
  114. */
  115. boost::system::error_code
  116. parse_url_encoded_form(boost::system::error_code& ec);
  117. /// Parse a multipart form.
  118. /**
  119. * Parse forms where the content-type is "multipart/form-data".
  120. */
  121. boost::system::error_code
  122. parse_multipart_form(boost::system::error_code& ec);
  123. /// Parse a single form part.
  124. boost::system::error_code
  125. parse_form_part(boost::system::error_code& ec);
  126. /// Erase any front-cruft on the form data.
  127. /**
  128. * In multipart forms, any characters that precede the first form
  129. * boundary are ignored. This function erases those characters.
  130. */
  131. boost::system::error_code
  132. move_to_start_of_first_part(boost::system::error_code& ec);
  133. /// Get the boundary marker from the CONTENT_TYPE header.
  134. boost::system::error_code
  135. parse_boundary_marker(boost::system::error_code& ec);
  136. /// Stores the JSON as POSTDATA for further processing.
  137. /**
  138. * Parse forms where the content-type is "application/json".
  139. */
  140. boost::system::error_code
  141. parse_json_form(boost::system::error_code& ec);
  142. private:
  143. context* context_;
  144. };
  145. } // namespace common
  146. BOOST_CGI_NAMESPACE_END
  147. //#ifndef BOOST_CGI_BUILD_LIB
  148. # include "boost/cgi/impl/form_parser.ipp"
  149. //#endif
  150. #endif // CGI_DETAIL_FORM_PARSER_HPP_INCLUDED__