Savarese Software Research Corporation
renderer/service.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2009 Savarese Software Research Corporation
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     https://www.savarese.com/software/ApacheLicense-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00022 #ifndef __SSRC_WSPR_RENDERER_SERVICE_H
00023 #define __SSRC_WSPR_RENDERER_SERVICE_H
00024 
00025 #include <vector>
00026 
00027 #include <boost/regex.hpp>
00028 #include <boost/filesystem/path.hpp>
00029 
00030 #include <ssrc/wispers/service/service.h>
00031 #include <ssrc/wispers/fcgi/HTTPServlet.h>
00032 #include <ssrc/wispers/fcgi/FCGIResponse.h>
00033 #include <ssrc/wispers/fcgi/FCGIServiceInitializer.h>
00034 #include <ssrc/wispers/utility/LoadError.h>
00035 #include <ssrc/wispers/lua/lua.h>
00036 #include <ssrc/wispers/renderer/protocol.h>
00037 
00038 __BEGIN_NS_SSRC_WSPR_RENDERER
00039 
00040 using std::string;
00041 using boost::filesystem::path;
00042 using NS_SSRC_WISP_PROTOCOL::MessageInfo;
00043 using NS_SSRC_WSPR_SERVICE::ServiceProtocolProcessor;
00044 using NS_SSRC_WSPR_FCGI::HTTPStatusCode;
00045 using NS_SSRC_WSPR_FCGI::HTTPServlet;
00046 using NS_SSRC_WSPR_FCGI::fcgx_request_ptr;
00047 using NS_SSRC_WSPR_FCGI::FCGIRequest;
00048 using NS_SSRC_WSPR_FCGI::FCGIResponse;
00049 using NS_SSRC_WSPR_UTILITY::LoadError;
00050 using NS_SSRC_WSPR_LUA::LuaCallError;
00051 
00052 struct RendererInitializer : NS_SSRC_WSPR_FCGI::FCGIServiceInitializer {
00053   typedef std::vector<string> dir_list;
00054 
00056   string global_env;
00057 
00059   string template_dir;
00060 
00062   string get_leaf_pattern;
00063 
00065   dir_list content_dirs;
00066 
00068   dir_list module_dirs;
00069 };
00070 
00071 class Renderer :
00072   public HTTPServlet<FCGIRequest, FCGIResponse>,
00073   public ServiceProtocolProcessor
00074 {
00075   friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>;
00076   typedef RendererProtocol protocol_traits;
00077 
00078   void load_config(Lua::lua_State *state) SSRC_DECL_THROW(LoadError);
00079   void reload_config();
00080 
00081   void ref_globals(Lua::lua_State *state);
00082   void unref_globals(Lua::lua_State *state);
00083 
00084 protected:
00085   typedef HTTPServlet<FCGIRequest, FCGIResponse> super_fcgi;
00086   typedef ServiceProtocolProcessor super_service;
00087 
00088   WISP_IMPORT(protocol_traits, MessageReloadConfig);
00089 
00090   string _global_env_file;
00091   string _template_prefix;
00092   path _template_dir;
00093   boost::regex _get_path_pattern;
00094 
00095   Lua::lua_State *_lua_state;
00096   int _lua_render_ref;
00097   int _lua_load_environment_ref;
00098   int _lua_uncache_template_ref;
00099   int _lua_uncache_environment_ref;
00100   int _lua_clear_rendering_cache_ref;
00101   int _lua_init_global_environment_ref;
00102 
00103   virtual void transition(State state);
00104 
00105   virtual utility::properties_ptr get_status();
00106 
00107   virtual void set_lua_state(Lua::lua_State *state) {
00108     _lua_state = state;
00109   }
00110 
00111   void render_and_cache(const request_ptr & request, response_ptr & response,
00112                         const bool flush = true);
00113 
00114   path find_error_template(const path & error_template,
00115                            const path & parent_path);
00116 
00117   path find_error_template(const path & parent_path) {
00118     return find_error_template(NS_SSRC_WSPR_LUA::get_value<string>(_lua_state, "wspr", "template", "error"), parent_path);
00119   }
00120 
00121   path find_error_template(const path & parent_path, int index) {
00122     return find_error_template(NS_SSRC_WSPR_LUA::get_field<string>(_lua_state, index, "wspr", "template", "error"), parent_path);
00123   }
00124 
00125   void send_error(const HTTPStatusCode status,
00126                   const request_ptr & request,
00127                   response_ptr & response,
00128                   const path & error_template);
00129 
00130   void load_environment(const string & environment_name,
00131                         const bool cache_template)
00132     SSRC_DECL_THROW(LuaCallError)
00133   {
00134     Lua::lua_rawgeti(_lua_state, LUA_REGISTRYINDEX, _lua_load_environment_ref);
00135     NS_SSRC_WSPR_LUA::pcall_nopop(1, _lua_state,
00136                                   environment_name, cache_template);
00137   }
00138 
00139   void uncache_template(const string & template_name)
00140     SSRC_DECL_THROW(LuaCallError)
00141   {
00142     Lua::lua_rawgeti(_lua_state, LUA_REGISTRYINDEX, _lua_uncache_template_ref);
00143     NS_SSRC_WSPR_LUA::pcall(_lua_state, template_name);
00144   }
00145 
00146   void uncache_environment(const string & environment_name)
00147     SSRC_DECL_THROW(LuaCallError)
00148   {
00149     Lua::lua_rawgeti(_lua_state, LUA_REGISTRYINDEX,
00150                      _lua_uncache_environment_ref);
00151     NS_SSRC_WSPR_LUA::pcall(_lua_state, environment_name);
00152   }
00153 
00154   void clear_template_cache();
00155 
00156   path load_template_args(const path & template_path,
00157                           const char * template_key,
00158                           const bool cache_environment = false,
00159                           const bool cache_template = true)
00160     SSRC_DECL_THROW(LoadError);
00161 
00162   path load_template_args(const path & template_path,
00163                           const bool cache_environment = false,
00164                           const bool cache_template = true)
00165     SSRC_DECL_THROW(LoadError)
00166   {
00167     return
00168       load_template_args(template_path, template_path.extension().c_str() + 1,
00169                          cache_environment, cache_template);
00170   }
00171 
00172   virtual void process_request(const MessageReloadConfig & msg,
00173                                const MessageInfo &)
00174   {
00175     reload_config();
00176   }
00177 
00178 public:
00179 
00180   Renderer(caller_type & caller, const RendererInitializer & initializer)
00181     SSRC_DECL_THROW(LoadError, std::invalid_argument);
00182 
00183   virtual ~Renderer();
00184 
00185   virtual void http_get(const request_ptr & request, response_ptr & response) {
00186     render_and_cache(request, response);
00187   }
00188 
00189   virtual void http_head(const request_ptr & request, response_ptr & response) {
00190     render_and_cache(request, response, false);
00191   }
00192 
00193   void process_fcgi_request(const fcgx_request_ptr & request);
00194 };
00195 
00196 __END_NS_SSRC_WSPR_RENDERER
00197 
00198 #endif

Savarese Software Research Corporation
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.