PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/boost/cgi/scgi/request_service.hpp

http://github.com/darrengarvey/cgi
C++ Header | 213 lines | 154 code | 36 blank | 23 comment | 4 complexity | 79a565231da52c6ea5ed90fc6e78380b MD5 | raw file
  1. // -- scgi/request_service.hpp --
  2. //
  3. // Copyright (c) Darren Garvey 2010.
  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_SCGI_REQUEST_SERVICE_HPP_INCLUDED__
  10. #define CGI_SCGI_REQUEST_SERVICE_HPP_INCLUDED__
  11. #include <boost/version.hpp>
  12. #include <boost/logic/tribool.hpp>
  13. #include <boost/fusion/include/vector.hpp>
  14. #include <boost/fusion/support.hpp>
  15. #include <boost/system/error_code.hpp>
  16. ////////////////////////////////////////////////////////////////
  17. #include "boost/cgi/common/form_parser.hpp"
  18. #include "boost/cgi/common/map.hpp"
  19. #include "boost/cgi/common/parse_options.hpp"
  20. #include "boost/cgi/common/request_base.hpp"
  21. #include "boost/cgi/common/role_type.hpp"
  22. #include "boost/cgi/common/source_enums.hpp"
  23. #include "boost/cgi/common/tags.hpp"
  24. #include "boost/cgi/connections/tcp_socket.hpp"
  25. #include "boost/cgi/detail/service_base.hpp"
  26. #include "boost/cgi/detail/throw_error.hpp"
  27. #include "boost/cgi/scgi/client.hpp"
  28. #include "boost/cgi/scgi/request_parser.hpp"
  29. #include "boost/cgi/http/status_code.hpp"
  30. #include "boost/cgi/import/read.hpp"
  31. #include "boost/cgi/import/io_service.hpp"
  32. BOOST_CGI_NAMESPACE_BEGIN
  33. namespace scgi {
  34. /// The IoObjectService class for a SCGI basic_request<>s
  35. template<typename Protocol>
  36. class scgi_request_service
  37. : public common::request_base<Protocol>
  38. , public detail::service_base<scgi_request_service<Protocol> >
  39. {
  40. public:
  41. typedef scgi_request_service<Protocol> self_type;
  42. typedef scgi_request_service<Protocol> full_type;
  43. typedef common::request_base<Protocol> base_type;
  44. typedef typename base_type::traits traits;
  45. typedef typename base_type::client_type client_type;
  46. typedef typename base_type::string_type string_type;
  47. typedef typename base_type::mutable_buffers_type mutable_buffers_type;
  48. typedef typename traits::header_buffer_type header_buffer_type;
  49. /// The actual implementation date for an SCGI request.
  50. struct implementation_type
  51. : base_type::impl_base
  52. {
  53. typedef typename base_type::traits traits;
  54. typedef typename base_type::client_type client_type;
  55. typedef typename base_type::buffer_type buffer_type;
  56. typedef typename base_type::mutable_buffers_type mutable_buffers_type;
  57. typedef typename client_type::header_buffer_type header_buffer_type;
  58. typedef request_parser request_parser_type;
  59. implementation_type()
  60. : id_(0)
  61. {
  62. }
  63. boost::uint16_t id_;
  64. header_buffer_type header_buf_;
  65. // Buffer to hold param records and filter data, etc.
  66. buffer_type param_buffer_;
  67. boost::shared_ptr<boost::array<char, 8192> > buffer_;
  68. /// Whether the request is valid or not.
  69. boost::tribool valid_request_;
  70. /// The parser for the incoming request.
  71. request_parser_type request_parser_;
  72. mutable_buffers_type prepare_misc(std::size_t size)
  73. {
  74. // Make sure we're not trying to make a zero-sized buffer.
  75. BOOST_ASSERT(size && "Attempting to allocate a zero-sized buffer.");
  76. std::size_t bufsz(param_buffer_.size());
  77. param_buffer_.resize(bufsz + size);
  78. return boost::asio::buffer(&param_buffer_[bufsz], size);
  79. }
  80. };
  81. template<typename Service>
  82. struct callback_functor
  83. {
  84. callback_functor(implementation_type& impl, Service* service)
  85. : impl_(impl)
  86. , service_(service)
  87. {
  88. }
  89. std::size_t operator()(boost::system::error_code& ec)
  90. {
  91. return service_->read_some(impl_, ec);
  92. }
  93. private:
  94. implementation_type& impl_;
  95. Service* service_;
  96. };
  97. scgi_request_service(::BOOST_CGI_NAMESPACE::common::io_service& ios)
  98. : detail::service_base<scgi_request_service<Protocol> >(ios)
  99. , strand_(ios)
  100. {
  101. }
  102. ~scgi_request_service()
  103. {
  104. }
  105. void construct(implementation_type& impl)
  106. {
  107. impl.client_.set_connection(
  108. implementation_type::connection_type::create(this->get_io_service())
  109. );
  110. }
  111. void shutdown_service()
  112. {
  113. }
  114. /// Close the request.
  115. int close(implementation_type& impl,
  116. common::http::status_code hsc = common::http::ok
  117. , int program_status = 0);
  118. /// Close the request.
  119. int close(implementation_type& impl,
  120. common::http::status_code hsc
  121. , int program_status, boost::system::error_code& ec);
  122. /// Clear all request data (object is then safe to reuse).
  123. void clear(implementation_type& impl);
  124. /// Load the request to a point where it can be usefully used.
  125. boost::system::error_code
  126. load(implementation_type& impl, common::parse_options opts
  127. , boost::system::error_code& ec);
  128. /// Read and parse the cgi POST meta variables (greedily)
  129. template<typename RequestImpl>
  130. boost::system::error_code
  131. parse_post_vars(RequestImpl& impl, boost::system::error_code& ec)
  132. {
  133. // Return an error, except ignore EOF, as this is expected.
  134. if (ec)
  135. {
  136. if (ec == boost::cgi::common::error::eof)
  137. ec = boost::system::error_code();
  138. else
  139. return ec;
  140. }
  141. return base_type::parse_post_vars(
  142. impl,
  143. callback_functor<self_type>(impl, this),
  144. ec
  145. );
  146. }
  147. // **FIXME**
  148. template<typename Handler>
  149. void async_load(implementation_type& impl, common::parse_options opts, Handler handler);
  150. /// Returns true if the request environment params have been read.
  151. bool params_read(implementation_type& impl);
  152. common::role_type role(implementation_type const& impl) const
  153. {
  154. return common::responder;
  155. }
  156. client_type&
  157. client(implementation_type& impl)
  158. {
  159. return impl.client_;
  160. }
  161. private:
  162. template<typename Handler>
  163. void do_load(
  164. implementation_type& impl, common::parse_options opts,
  165. Handler handler, boost::system::error_code& ec
  166. );
  167. private:
  168. boost::asio::io_service::strand strand_;
  169. };
  170. } // namespace scgi
  171. BOOST_CGI_NAMESPACE_END
  172. #include "boost/cgi/scgi/request.hpp"
  173. #include "boost/cgi/basic_request.hpp"
  174. #if !defined( BOOST_CGI_BUILD_LIB )
  175. # include "boost/cgi/scgi/request_service.ipp"
  176. #endif
  177. #endif // CGI_SCGI_REQUEST_SERVICE_HPP_INCLUDED__