summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2007-05-21 16:05:58 +0000
committerpixel <pixel>2007-05-21 16:05:58 +0000
commita366b099a895e01e1d77d7ed2325ea5df9b0b689 (patch)
tree4525a9ba4c17ac4a17fe8706d5007c0b872fee04
parent84875ddd4f59f89012048ff03fef6508b8b5456a (diff)
Adding full LUA control for HTTP requests.
-rw-r--r--include/LuaHttp.h16
-rw-r--r--lib/LuaHttp.cc217
2 files changed, 233 insertions, 0 deletions
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 <HttpServ.h>
+#include <BLua.h>
+
+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;
+}