#include "Domain.h" #include "LuaHttp.h" #include "LuaHandle.h" #include "LuaTask.h" #define DOMAIN_REGISTRY "DOMAINS_KEYS" #define export_enum(L, n) \ L->push(#n); \ L->push((lua_Number) HttpResponse::n); \ L->settable(LUA_GLOBALSINDEX); LuaHttpResponse::LuaHttpResponse(HttpResponse * _r) : r(_r) { } enum HttpResponse_method_t { HTTPRESPONSE_INDEX = 0, HTTPRESPONSE_NEWINDEX, }; enum HttpResponse_functions_t { HTTPRESPONSE_NEWHTTPRESPONSE = 0, HTTPRESPONSE_REGISTERDOMAIN, }; struct lua_functypes_t HttpResponse_methods[] = { { HTTPRESPONSE_INDEX, "index", 1, 1, { LUA_STRING } }, { HTTPRESPONSE_NEWINDEX, "newindex", 2, 2, { LUA_STRING, LUA_ANY } }, { -1, 0, 0, 0, 0 } }; struct lua_functypes_t HttpResponse_functions[] = { { HTTPRESPONSE_NEWHTTPRESPONSE, "HttpResponse", 0, 0, { } }, { HTTPRESPONSE_REGISTERDOMAIN, "RegisterDomain", 2, 2, { LUA_STRING, LUA_FUNCTION } }, { -1, 0, 0, 0, 0 } }; class sLua_HttpResponse : public Base { public: DECLARE_METHOD(HttpResponse, HTTPRESPONSE_INDEX); DECLARE_METHOD(HttpResponse, HTTPRESPONSE_NEWINDEX); DECLARE_FUNCTION(HttpResponse, HTTPRESPONSE_NEWHTTPRESPONSE); DECLARE_FUNCTION(HttpResponse, HTTPRESPONSE_REGISTERDOMAIN); private: static int HttpResponse_proceed(Lua * L, int n, HttpResponse * obj, int caller); static int HttpResponse_proceed_statics(Lua * L, int n, int caller); }; void LuaHttpResponse::pushmembers(Lua * L) { pushme(L, r); PUSH_METAMETHOD(HttpResponse, HTTPRESPONSE_INDEX); PUSH_METAMETHOD(HttpResponse, HTTPRESPONSE_NEWINDEX); } void LuaHttpResponse::pushstatics(Lua * L) throw (GeneralException) { CHECK_METHODS(HttpResponse); CHECK_FUNCTIONS(HttpResponse); PUSH_FUNCTION(HttpResponse, HTTPRESPONSE_NEWHTTPRESPONSE); PUSH_FUNCTION(HttpResponse, HTTPRESPONSE_REGISTERDOMAIN); export_enum(L, HTTP_200_OK); export_enum(L, HTTP_301_PERM_MOVED); export_enum(L, HTTP_302_FOUND); export_enum(L, HTTP_400_BAD_REQUEST); export_enum(L, HTTP_401_UNAUTHORIZED); export_enum(L, HTTP_403_FORBIDDEN); export_enum(L, HTTP_404_NOT_FOUND); export_enum(L, HTTP_500_INTERNAL_ERROR); export_enum(L, HTTP_503_SERVICE_UNAVAILABLE); L->push(DOMAIN_REGISTRY); L->newtable(); L->settable(LUA_REGISTRYINDEX); } int sLua_HttpResponse::HttpResponse_proceed(Lua * L, int n, HttpResponse * res, int caller) { String i; int r = 0; switch (caller) { case HTTPRESPONSE_INDEX: i = L->tostring(2); if (i == "mime_type") { L->push(res->mime_type); } else if (i == "location") { L->push(res->location); } else if (i == "server_name") { L->push(res->server_name); } else if (i == "return_code") { L->push((lua_Number) res->return_code); } else if (i == "last_modified") { L->push((lua_Number) res->last_modified); } else if (i == "contents") { { LuaBuffer b(&res->contents); b.push(L); } } else if (i == "cache") { L->push(res->cache); } else { L->error("Unknow field in HttpResponse object: " + i); } r = 1; break; case HTTPRESPONSE_NEWINDEX: i = L->tostring(2); if (i == "mime_type") { res->mime_type = L->tostring(3); } else if (i == "location") { res->location = L->tostring(3); } else if (i == "server_name") { res->server_name = L->tostring(3); } else if (i == "return_code") { res->return_code = HttpResponse::return_code_t(L->tonumber(3)); } else if (i == "last_modified") { res->last_modified = L->tonumber(3); } else if (i == "contents") { L->error("Can't alter field buffer in HttpResponse."); } else if (i == "cache") { res->cache = L->toboolean(3); } else { L->error("Unknow field in HttpResponse object: " + i); } break; } return r; } class LuaDomain : public Domain { public: LuaDomain(Lua * _L, String r) : Domain(r), L(_L) { id = max_id++; L->push(DOMAIN_REGISTRY); L->gettable(LUA_REGISTRYINDEX); L->push((lua_Number) id); L->copy(2); L->settable(); L->pop(); } virtual ~LuaDomain() { L->push(DOMAIN_REGISTRY); L->gettable(LUA_REGISTRYINDEX); L->push((lua_Number) id); L->push(); L->settable(); L->pop(); } virtual void Do(const HttpRequest & req, HttpResponse * res) throw (GeneralException) { int i; L->push(DOMAIN_REGISTRY); L->gettable(LUA_REGISTRYINDEX); L->push((lua_Number) id); L->gettable(); L->remove(); L->newtable(); L->push("vars"); L->newtable(); for (i = 0; i < req.vars->GetNb(); i++) { char * v = (*(req.vars))[i].strdup(), * p; p = strchr(v, '='); *p = 0; p++; L->push(v); L->push(p); L->settable(); free(v); } L->settable(); L->push("headers"); L->newtable(); for (i = 0; i < req.headers->GetNb(); i++) { char * v = (*(req.headers))[i].strdup(), * p; p = strchr(v, '='); *p = 0; p++; L->push(v); L->push(p); L->settable(); free(v); } L->settable(); L->push("uri"); L->push(req.uri); L->settable(); LuaHttpResponse r(res); r.push(L); res->builder = new LuaTask(L, 2); } private: Lua * L; static int max_id; int id; }; int LuaDomain::max_id = 1; int sLua_HttpResponse::HttpResponse_proceed_statics(Lua * L, int n, int caller) { int r = 0; switch (caller) { case HTTPRESPONSE_NEWHTTPRESPONSE: { LuaHttpResponse r(new HttpResponse()); r.pushdestruct(L); } r = 1; break; case HTTPRESPONSE_REGISTERDOMAIN: new LuaDomain(L, L->tostring(1)); } return r; }