From a366b099a895e01e1d77d7ed2325ea5df9b0b689 Mon Sep 17 00:00:00 2001 From: pixel Date: Mon, 21 May 2007 16:05:58 +0000 Subject: Adding full LUA control for HTTP requests. --- include/LuaHttp.h | 16 ++++ lib/LuaHttp.cc | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 include/LuaHttp.h create mode 100644 lib/LuaHttp.cc diff --git a/include/LuaHttp.h b/include/LuaHttp.h new file mode 100644 index 0000000..6d7af10 --- /dev/null +++ b/include/LuaHttp.h @@ -0,0 +1,16 @@ +#ifndef __LUAHTTP_H__ +#define __LUAHTTP_H__ + +#include +#include + +class LuaHttpResponse : public LuaObject { + public: + static void pushstatics(Lua *) throw (GeneralException); + LuaHttpResponse(HttpResponse *); + protected: + virtual void pushmembers(Lua *); + HttpResponse * r; +}; + +#endif diff --git a/lib/LuaHttp.cc b/lib/LuaHttp.cc new file mode 100644 index 0000000..6b376a6 --- /dev/null +++ b/lib/LuaHttp.cc @@ -0,0 +1,217 @@ +#include "Domain.h" +#include "LuaHttp.h" +#include "LuaHandle.h" + +#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); + 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); + + 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("DOMAINS_KEYS"); + 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("DOMAINS_KEYS"); + L->gettable(LUA_REGISTRYINDEX); + L->push((lua_Number) id); + L->copy(3); + L->settable(); + } + virtual ~LuaDomain() { } + virtual void Do(const HttpRequest & req, HttpResponse * res) throw (GeneralException) { + int i; + + L->push("DOMAINS_KEYS"); + L->gettable(LUA_REGISTRYINDEX); + L->push((lua_Number) id); + L->gettable(); + + 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); + + L->call(2, 0); + + } + 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(2)); + } + + return r; +} -- cgit v1.2.3