ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

282 lines
8.0 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef CPPCMS_HTTP_CONTEXT_H
  9. #define CPPCMS_HTTP_CONTEXT_H
  10. #include <cppcms/defs.h>
  11. #include <booster/hold_ptr.h>
  12. #include <booster/intrusive_ptr.h>
  13. #include <booster/shared_ptr.h>
  14. #include <booster/enable_shared_from_this.h>
  15. #include <booster/callback.h>
  16. #include <booster/noncopyable.h>
  17. #include <locale>
  18. namespace cppcms {
  19. class service;
  20. class application;
  21. class application_specific_pool;
  22. class cache_interface;
  23. class session_interface;
  24. namespace json { class value; }
  25. namespace impl { namespace cgi { class connection; } }
  26. ///
  27. /// \brief This namespace represent classes that are directly connected to handing HTTP requests and responses
  28. ///
  29. namespace http {
  30. class request;
  31. class response;
  32. class file;
  33. ///
  34. /// \brief context is a central class that holds all specific connection related information.
  35. /// It encapsulates CGI request and response, cache, session and locale information
  36. ///
  37. /// Instance of this class is created upon client requests, it provides access to all
  38. /// connection related interfaces. This class is unique per each applications hierarchy
  39. /// and destroyed when HTTP request/response is completed
  40. ///
  41. class CPPCMS_API context :
  42. public booster::noncopyable,
  43. public booster::enable_shared_from_this<context>
  44. {
  45. public:
  46. /// \cond INTERNAL
  47. context(booster::shared_ptr<impl::cgi::connection> conn);
  48. ~context();
  49. impl::cgi::connection &connection();
  50. void run();
  51. /// \endcond
  52. ///
  53. /// Get an interface to HTTP request
  54. ///
  55. http::request &request();
  56. ///
  57. /// Get an interface to HTTP response
  58. ///
  59. http::response &response();
  60. ///
  61. /// Get global settings. Same as cppcms::service::settings
  62. ///
  63. json::value const &settings();
  64. ///
  65. /// Get an interface to CppCMS Cache
  66. ///
  67. cache_interface &cache();
  68. ///
  69. /// Get an interface to current session
  70. ///
  71. /// Note, when using asynchronous CppCMS applications, session data is not fetched
  72. /// and is not updated, because session access may be not cheap, So when using
  73. /// session_interface in asynchronous application make sure you call session_inerface::load
  74. /// member function
  75. ///
  76. session_interface &session();
  77. ///
  78. /// Get current context locale
  79. ///
  80. std::locale locale();
  81. ///
  82. /// Set locale explicitly. Note, it changes the locale of the response().out() stream as
  83. /// well
  84. ///
  85. void locale(std::locale const &new_locale);
  86. ///
  87. /// Set locale by name. Similar to locale(service().generator(name)).
  88. ///
  89. /// Note: it changes the locale of the response().out() stream as well
  90. ///
  91. void locale(std::string const &name);
  92. ///
  93. /// Get the central service instance
  94. ///
  95. cppcms::service &service();
  96. ///
  97. /// Get current views skin name
  98. ///
  99. std::string skin();
  100. ///
  101. /// Set current views skin name
  102. ///
  103. void skin(std::string const &name);
  104. typedef enum {
  105. operation_completed, ///< Asynchronous operation completed successfully
  106. operation_aborted ///< Asynchronous operation was canceled
  107. } completion_type;
  108. typedef booster::callback<void(completion_type)> handler;
  109. ///
  110. /// Send all pending output data to the client and
  111. /// finalize the connection. Note, you can't use this
  112. /// object for communication any more.
  113. ///
  114. void complete_response();
  115. ///
  116. /// Send all pending output data to the client and
  117. /// finalize the connection. Note, you can't use this
  118. /// object for communication any more.
  119. ///
  120. void async_complete_response();
  121. ///
  122. /// Send all pending data to user, when operation is complete
  123. /// call handler \a h with status.
  124. ///
  125. /// Note: if the status is operation_aborted, you can't use
  126. /// this connection any more, the peer gone.
  127. ///
  128. void async_flush_output(handler const &h);
  129. ///
  130. /// Set handler for peer reset events. It is useful to cleanup
  131. /// connections that had timeout or just disconnected by user
  132. ///
  133. /// Notes:
  134. ///
  135. /// -# if async_complete_response was called, handler would not
  136. /// be called any more.
  137. /// -# If async_flush_output fails, this does not mean that
  138. /// this handler would be called as well, so you need to check both
  139. ///
  140. void async_on_peer_reset(booster::callback<void()> const &h);
  141. ///
  142. /// Submit the context to alternative pool - allows to transfer context from application to application, \a matched_url
  143. /// would be given to application::main for processing
  144. ///
  145. /// Note:
  146. ///
  147. /// - no output should be itransfered on this context
  148. /// - the context MUST be detached for existing application
  149. ///
  150. /// This function can be called from any thread
  151. ///
  152. /// \ver{v1_2}
  153. void submit_to_pool(booster::shared_ptr<application_specific_pool> pool,std::string const &matched_url);
  154. ///
  155. /// Submit the context to alternative application - allows to transfer context from application to application, \a matched_url
  156. /// would be given to application::main for processing
  157. ///
  158. /// Note:
  159. ///
  160. /// - the app should be asynchronous
  161. /// - no output should be itransfered on this context
  162. /// - the context MUST be detached for existing application
  163. ///
  164. /// This function can be called from any thread
  165. ///
  166. /// \ver{v1_2}
  167. void submit_to_asynchronous_application(booster::intrusive_ptr<application> app,std::string const &matched_url);
  168. private:
  169. struct holder { virtual ~holder() {} };
  170. template<typename T>
  171. struct specific_holder : public holder {
  172. specific_holder(T *ptr) : p(ptr) {}
  173. virtual ~specific_holder() {}
  174. booster::hold_ptr<T> p;
  175. };
  176. public:
  177. ///
  178. /// Get context specific value of type T binded to context. If none is stored or
  179. /// type mismatched NULL is returned
  180. ///
  181. /// \ver{v1_2}
  182. template<typename T>
  183. T *get_specific()
  184. {
  185. specific_holder<T> *sh=dynamic_cast<specific_holder<T> *>(get_holder());
  186. if(!sh)
  187. return 0;
  188. return sh->p.get();
  189. }
  190. ///
  191. /// Reset context specific value of type T binded to context. Old value is deleted
  192. ///
  193. /// \ver{v1_2}
  194. template<typename T>
  195. void reset_specific(T *ptr = 0)
  196. {
  197. if(ptr == 0) {
  198. set_holder(0);
  199. return;
  200. }
  201. specific_holder<T> *sh=dynamic_cast<specific_holder<T> *>(get_holder());
  202. if(sh) {
  203. sh->p.reset(ptr);
  204. }
  205. else {
  206. specific_holder<T> *sh = new specific_holder<T>(ptr);
  207. set_holder(sh);
  208. }
  209. }
  210. ///
  211. /// Release context specific value binded to context.
  212. ///
  213. /// \ver{v1_2}
  214. template<typename T>
  215. T *release_specific()
  216. {
  217. T *r = 0;
  218. specific_holder<T> *sh=dynamic_cast<specific_holder<T> *>(get_holder());
  219. if(sh) {
  220. r = sh->p.release();
  221. }
  222. set_holder(0);
  223. return r;
  224. }
  225. // CM-20230904 as usual hiding shtuff just complicates life.
  226. void make_error_message(std::exception const &e);
  227. private:
  228. void set_holder(holder *p);
  229. holder *get_holder();
  230. friend class impl::cgi::connection;
  231. int on_content_progress(size_t n);
  232. int on_headers_ready();
  233. int translate_exception();
  234. void on_request_ready(bool error);
  235. void submit_to_pool_internal(booster::shared_ptr<application_specific_pool> pool,std::string const &matched,bool now);
  236. static void dispatch(booster::shared_ptr<application_specific_pool> const &pool,booster::shared_ptr<context> const &self,std::string const &url);
  237. static void dispatch(booster::intrusive_ptr<application> const &app,std::string const &url,bool syncronous);
  238. void try_restart(bool e);
  239. booster::shared_ptr<context> self();
  240. struct _data;
  241. booster::hold_ptr<_data> d;
  242. booster::shared_ptr<impl::cgi::connection> conn_;
  243. };
  244. }
  245. };
  246. #endif