Savarese Software Research Corporation
ServletRunner.cc
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 
00017 #include <ssrc/wispers/fcgi_lua/ServletRunner.h>
00018 
00019 __BEGIN_NS_SSRC_WSPR_FCGI_LUA
00020 
00021 using namespace Lua;
00022 using namespace NS_SSRC_WSPR_LUA;
00023 
00024 const char * const ServletRunner::ServletFunctions[MethodNum] = {
00025   "http_delete", "http_get", "http_head", "http_options", "http_post",
00026   "http_put", "http_trace"
00027 };
00028 
00029 ServletRunner::ServletRunner(caller_type & caller,
00030                              const ServletRunnerInitializer & initializer)
00031   SSRC_DECL_THROW(LoadError) :
00032   super(caller), _lua_state(Lua::luaL_newstate())
00033 {
00034   super::add_service_type(WSPR_SERVICE_TYPE(lua_servlet));
00035 
00036   luaL_openlibs(_lua_state);
00037 
00038   NS_SSRC_WSPR_LUA::prepend_package_path(_lua_state,
00039                                          initializer.module_dirs.begin(),
00040                                          initializer.module_dirs.end());
00041   load_servlet(initializer.servlet_file);
00042 
00043   for(unsigned int i = 0; i < MethodNum; ++i) {
00044     lua_getglobal(_lua_state, ServletFunctions[i]);
00045     _method_ref[i] = luaL_ref(_lua_state, LUA_REGISTRYINDEX);
00046   }
00047 }
00048 
00049 ServletRunner::~ServletRunner() {
00050   for(unsigned int i = 0; i < MethodNum; ++i) {
00051     luaL_unref(_lua_state, LUA_REGISTRYINDEX, _method_ref[i]);
00052   }
00053   Lua::lua_close(_lua_state);
00054 }
00055 
00056 void ServletRunner::transition(State state) {
00057   switch(state) {
00058   case Starting:
00059     state = Started;
00060     break;
00061   case Stopping:
00062     state = Stopped;
00063     break;
00064   default:
00065     break;
00066   }
00067 
00068   super::transition(state);
00069 }
00070 
00071 void ServletRunner::load_servlet(const string & servlet_file)
00072   SSRC_DECL_THROW(LoadError)
00073 {
00074   if(luaL_dofile(_lua_state, servlet_file.c_str()))
00075     throw LoadError(lua_tostring(_lua_state, -1));
00076 }
00077 
00078 void ServletRunner::process_fcgi_request(const fcgx_request_ptr & request) {
00079   using namespace NS_SSRC_WSPR_FCGI;
00080 
00081   request_ptr http_request(new request_type(request));
00082   response_ptr http_response(new response_type(http_request));
00083 
00084   const HTTPRequestMethod method = http_request->http_request_method();
00085 
00086   if(method <= MethodMax) {
00087     const int ref = _method_ref[method];
00088     if(ref != LUA_REFNIL) {
00089       lua_rawgeti(_lua_state, LUA_REGISTRYINDEX, ref);
00090 
00091       try {
00092         pcall_nopop(1, _lua_state, &http_request, &http_response);
00093 
00094         if(!http_response->completed() && !http_response->suspended()) {
00095           std::size_t content_length = 0;
00096           const char *content = lua_tolstring(_lua_state, -1, &content_length);
00097           http_response->complete(content, content_length);
00098         }
00099         lua_pop(_lua_state, 1);
00100       } catch(const LuaCallError & lce) {
00101 #ifdef WSPR_DEBUG
00102         std::cerr << "ERROR!  " << lce.what() << std::endl;
00103 #endif
00104         http_response->send_error(StatusInternalServerError);
00105       }
00106     } else {
00107       http_response->send_error(StatusMethodNotAllowed);
00108     }
00109   } else {
00110     http_response->send_error(StatusMethodNotImplemented);
00111   }
00112 }
00113 
00114 __END_NS_SSRC_WSPR_FCGI_LUA

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