diff --git a/APIs/extra_mime.lua b/APIs/extra_mime.lua index 9d2376b..b30b505 100644 --- a/APIs/extra_mime.lua +++ b/APIs/extra_mime.lua @@ -32,7 +32,7 @@ function std.mimeOf(name) end end -function std.isBinary(name) +--[[ function std.isBinary(name) local mime = std.mime(name) if mime ~= "application/octet-stream" then return std.is_bin(name) @@ -40,7 +40,7 @@ function std.isBinary(name) local xmime,bin = std.extra_mime(name) return bin end -end +end ]] function std.sendFile(m) local mime = std.mimeOf(m) @@ -48,28 +48,24 @@ function std.sendFile(m) local len = tostring(math.floor(finfo.size)) local len1 = tostring(math.floor(finfo.size - 1)) if mime == "audio/mpeg" then - std.status(200, "OK") - std.custom_header("Pragma", "public") - std.custom_header("Expires", "0") - std.custom_header("Content-Type", mime) - std.custom_header("Content-Length", len) - std.custom_header("Content-Disposition", "inline; filename=" .. std.basename(m)) - std.custom_header("Content-Range:", "bytes 0-" .. len1 .. "/" .. len) - std.custom_header("Accept-Ranges", "bytes") - std.custom_header("X-Pad", "avoid browser bug") - std.custom_header("Content-Transfer-Encoding", "binary") - std.custom_header("Cache-Control", "no-cache, no-store") - std.custom_header("Connection", "Keep-Alive") - std.custom_header("Etag", "a404b-c3f-47c3a14937c80") + std.status(200) + std.header("Pragma", "public") + std.header("Expires", "0") + std.header("Content-Type", mime) + std.header("Content-Length", len) + std.header("Content-Disposition", "inline; filename=" .. std.basename(m)) + std.header("Content-Range:", "bytes 0-" .. len1 .. "/" .. len) + std.header("Accept-Ranges", "bytes") + std.header("X-Pad", "avoid browser bug") + std.header("Content-Transfer-Encoding", "binary") + std.header("Cache-Control", "no-cache, no-store") + std.header("Connection", "Keep-Alive") + std.header("Etag", "a404b-c3f-47c3a14937c80") else - std.status(200, "OK") - std.custom_header("Content-Type", mime) - std.custom_header("Content-Length", len) + std.status(200) + std.header("Content-Type", mime) + std.header("Content-Length", len) end std.header_flush() - if std.is_bin(m) then - std.fb(m) - else - std.f(m) - end + std.f(m) end diff --git a/APIs/std.lua b/APIs/std.lua index f70dc69..ff95d15 100644 --- a/APIs/std.lua +++ b/APIs/std.lua @@ -1,73 +1,103 @@ std = modules.std() bytes = modules.bytes() array = modules.array() -function std.html() - std._html(HTTP_REQUEST.id) -end -function std.text() - std._text(HTTP_REQUEST.id) -end -function std.status(code, msg) - std._status(HTTP_REQUEST.id, code, msg) +RESPONSE_HEADER = { + status = 200, + header = {}, + cookie = {}, + sent = false +} + +function std.status(code) + RESPONSE_HEADER.status=code end function std.custom_header(k,v) - --print(k..":"..v) - std.t(k..": "..v) + std.header(k,v) end function std.header_flush() - std.t("") + std._send_header(HTTP_REQUEST.id,RESPONSE_HEADER.status, RESPONSE_HEADER.header, RESPONSE_HEADER.cookie) + RESPONSE_HEADER.sent = true end ---_redirect -function std.redirect(s) - std._redirect(HTTP_REQUEST.id,s) + +function std.header(k,v) + RESPONSE_HEADER.header[k] = v end -function std.json() - std._json(HTTP_REQUEST.id) + +function std.cjson(ck) + for k,v in pairs(ck) do + std.setCookie(k.."="..v.."; Path=/") + end + std.header("Content-Type","application/json") + std.header_flush() end -function std.jpeg() - std._jpeg(HTTP_REQUEST.id) -end -function std.header(s) - std._header(HTTP_REQUEST.id,s) -end -function std.octstream(s) - std._octstream(HTTP_REQUEST.id,s) -end -function std.textstream() - std._textstream(HTTP_REQUEST.id) -end -function std.ti(v) - std._ti(HTTP_REQUEST.id,v) +function std.chtml(ck) + for k,v in pairs(ck) do + std.setCookie(k.."="..v.."; Path=/") + end + std.header("Content-Type","text/html") + std.header_flush() end function std.t(s) + if RESPONSE_HEADER.sent == false then + std.header_flush() + end std._t(HTTP_REQUEST.id,s) end +function std.b(s) + if RESPONSE_HEADER.sent == false then + std.header_flush() + end + std._b(HTTP_REQUEST.id,s) +end function std.f(v) std._f(HTTP_REQUEST.id,v) end -function std.fb(v) - std._f(HTTP_REQUEST.id,v) + +function std.setCookie(v) + RESPONSE_HEADER.cookie[#RESPONSE_HEADER.cookie] = v end -function std.setCookie(t,v,p) - p = p or "" - std._setCookie(HTTP_REQUEST.id,t,v,p) -end -function std.cjson(v, p) - - std.setCookie("application/json; charset=utf-8",v) -end -function std.chtml(v) - std.setCookie("text/html; charset=utf-8",v) -end -function std.ctext(v) - std.setCookie("text/plain; charset=utf-8",v) + +function std.error(status, msg) + std._error(HTTP_REQUEST.id, status, msg) end --_upload --_route function std.unknow(s) - std._unknow(HTTP_REQUEST.id,s) + std.error(404, "Unknown request") end +--_redirect +--[[ function std.redirect(s) + std._redirect(HTTP_REQUEST.id,s) +end ]] + +function std.html() + std.header("Content-Type","text/html") + std.header_flush() +end +function std.text() + std.header("Content-Type","text/plain") + std.header_flush() +end + +function std.json() + std.header("Content-Type","application/json") + std.header_flush() +end +function std.jpeg() + std.header("Content-Type","image/jpeg") + std.header_flush() +end +function std.octstream(s) + std.header("Content-Type","application/octet-stream") + std.header("Content-Disposition",'attachment; filename="'..s..'"') + std.header_flush() +end +--[[ function std.textstream() + std._textstream(HTTP_REQUEST.id) +end ]] + + function std.readOnly(t) -- bugging local proxy = {} local mt = { -- create metatable diff --git a/APIs/web.lua b/APIs/web.lua index b5dba59..3f32633 100644 --- a/APIs/web.lua +++ b/APIs/web.lua @@ -5,7 +5,7 @@ local wurl = require("wurl") local web = {} -web.undestand = function(proto) +web.understand = function(proto) if proto == "http" or proto == "https" then return true else @@ -15,7 +15,7 @@ end web.get = function(url) local obj = utils.url_parser(url) - if web.undestand(obj.protocol) then + if web.understand(obj.protocol) then return wurl._get(obj.hostname,obj.port, obj.query) else return nil,"Protocol is unsupported: "..obj.protocol @@ -25,7 +25,7 @@ end web.post = function(url,data) local obj = utils.url_parser(url) - if web.undestand(obj.protocol) then + if web.understand(obj.protocol) then if type(data) == "string" then return wurl._post(obj.hostname, obj.port, @@ -44,7 +44,7 @@ end web.download = function(url,to) local obj = utils.url_parser(url) - if web.undestand(obj.protocol) then + if web.understand(obj.protocol) then local file if std.is_dir(to) then -- need to find file name here @@ -64,7 +64,7 @@ end web.upload = function(url,name,file) local obj = utils.url_parser(url) - if web.undestand(obj.protocol) then + if web.understand(obj.protocol) then return wurl._upload(obj.hostname,obj.port,obj.query,name,file) else return nil,"Protocol is unsupported: "..obj.protocol diff --git a/dist/lua-0.5.2b.tar.gz b/dist/lua-0.5.2b.tar.gz index 73e5520..50ea2db 100644 Binary files a/dist/lua-0.5.2b.tar.gz and b/dist/lua-0.5.2b.tar.gz differ diff --git a/lib/wurl/wurl.c b/lib/wurl/wurl.c index 1b6c80d..7f84890 100644 --- a/lib/wurl/wurl.c +++ b/lib/wurl/wurl.c @@ -16,6 +16,7 @@ #include #include "../lualib.h" +#include "../../lua-api.h" #include #define CLIENT_NAME "wurl" @@ -475,26 +476,22 @@ static int l_get(lua_State *L) if(wurl_request(host,port,&rq,1) == 0) { //printf("Content type is %s\n", rq.ctype); - mime_t m = mime_from_type(rq.ctype); + //mime_t m = mime_from_type(rq.ctype); lua_newtable(L); lua_pushstring(L,"contentType"); lua_pushstring(L,rq.ctype); lua_settable(L,-3); + /* lua_pushstring(L,"binary"); lua_pushboolean(L,m.bin); - lua_settable(L,-3); + lua_settable(L,-3);*/ lua_pushstring(L,"data"); - if(m.bin) - { - //printf("Data is binary, encode as base64 %s\n", rq.ctype); - char* dst = (char*) malloc(3*rq.clen/2); - Base64encode(dst, (const char*)rq.data,rq.clen); - lua_pushstring(L,dst); - free(dst); - } else - lua_pushstring(L,(const char*)rq.data); + // byte array, that can be convert to string later + lua_new_byte_array(L,rq.clen); + byte_array_t* arr = l_check_barray(L,-1); + memcpy(arr->data,rq.data,rq.clen); free(rq.data); // be careful lua_settable(L,-3); return 1; @@ -529,20 +526,15 @@ static int l_post(lua_State *L) lua_pushstring(L,rq.ctype); lua_settable(L,-3); - lua_pushstring(L,"binary"); + /*lua_pushstring(L,"binary"); lua_pushboolean(L,m.bin); lua_settable(L,-3); - + */ + lua_pushstring(L,"data"); - if(m.bin) - { - //printf("Data is binary, encode as base64 %s\n", rq.ctype); - char* dst = (char*) malloc(3*rq.clen/2); - Base64encode(dst, (const char*)rq.data,rq.clen); - lua_pushstring(L,dst); - free(dst); - } else - lua_pushstring(L,(const char*)rq.data); + lua_new_byte_array(L,rq.clen); + byte_array_t* arr = l_check_barray(L,-1); + memcpy(arr->data,rq.data,rq.clen); free(rq.data); // be careful lua_settable(L,-3); return 1; diff --git a/lua-api.c b/lua-api.c index 156ff8e..034ac5c 100644 --- a/lua-api.c +++ b/lua-api.c @@ -21,18 +21,18 @@ void init() * Plugin handler, reads request from the server and processes it * */ -static void push_dict_to_lua(lua_State* L, dictionary d) +static void push_dict_to_lua(lua_State* L, dictionary_t d) { lua_newtable(L); - association as; + chain_t as; if(d) for_each_assoc(as, d) { lua_pushstring(L,as->key); //printf("KEY %s\n", as->key); if(EQU(as->key,"COOKIE") || EQU(as->key,"REQUEST_HEADER") || EQU(as->key,"REQUEST_DATA") ) - push_dict_to_lua(L, (dictionary)as->value); + push_dict_to_lua(L, (dictionary_t)as->value); else { lua_pushstring(L,as->value); diff --git a/plugin-wrapper.c b/plugin-wrapper.c index 8c5511e..ee9ffe0 100644 --- a/plugin-wrapper.c +++ b/plugin-wrapper.c @@ -2,64 +2,74 @@ #include "lua-api.h" //void header(int,const char*); +/* static int l_header (lua_State *L) { //int client = (int)luaL_checknumber(L, 1); void* client = lua_touserdata (L, 1); const char* s = luaL_checkstring(L,2); ctype(client,s); - return 0; /* number of results */ + return 0; } +*/ //void redirect(int,const char*); +/* static int l_redirect (lua_State *L) { void* client = lua_touserdata (L, 1); const char* s = luaL_checkstring(L,2); redirect(client,s); - return 0; /* number of results */ -} + return 0; +}*/ -//void html(int); +/* static int l_html (lua_State *L) { void* client = lua_touserdata (L, 1); html(client); - return 0; /* number of results */ + return 0; } +*/ //void text(int); +/* static int l_text (lua_State *L) { void* client = lua_touserdata (L, 1); text(client); - return 0; /* number of results */ + return 0; } +*/ //void json(int); +/* static int l_json (lua_State *L) { void* client = lua_touserdata (L, 1); json(client); - return 0; /* number of results */ -} + return 0; +}*/ //void jpeg(int); +/* static int l_jpeg (lua_State *L) { void* client = lua_touserdata (L, 1); jpeg(client); - return 0; /* number of results */ -} + return 0; +}*/ //void octstream(int, char*); +/* static int l_octstream (lua_State *L) { void* client = lua_touserdata (L, 1); const char* s = luaL_checkstring(L,2); octstream(client,(char*)s); - return 0; /* number of results */ -} + return 0; +}*/ //void textstream(int); +/* static int l_textstream (lua_State *L) { void* client = lua_touserdata (L, 1); textstream(client); - return 0; /* number of results */ -} + return 0; +}*/ // int mime static int l_mime(lua_State* L) { @@ -77,19 +87,22 @@ static int l_ext(lua_State* L) free(e); return 1; } +/* static int l_is_bin(lua_State* L) { const char* file = luaL_checkstring(L,1); lua_pushboolean(L, is_bin(file)); return 1; -} +}*/ //int __ti(int,int); +/* static int l_ti (lua_State *L) { void* client = lua_touserdata (L, 1); int v = (int)luaL_checknumber(L, 2); lua_pushnumber(L, __ti(client,v)); - return 1; /* number of results */ + return 1; } +*/ //int __t(int, const char*,...); static int l_t (lua_State *L) { @@ -99,9 +112,14 @@ static int l_t (lua_State *L) { return 1; /* number of results */ } +// TODO: add __b to LUA //int __b(int, const unsigned char*, int); -//static int l_b (lua_State *L) { -//} +static int l_b (lua_State *L) { + void * client = lua_touserdata(L,1); + byte_array_t * arr = l_check_barray(L,2); + lua_pushnumber(L, __b(client, arr->data,arr->size)); + return 1; +} //int __f(int, const char*); static int l_f (lua_State *L) { @@ -135,31 +153,33 @@ static int l_route (lua_State *L) { } //char* htdocs(const char*); -#ifdef USE_DB +//#ifdef USE_DB //sqldb getdb(); -#endif +//#endif //void set_cookie(int,dictionary); //void unknow(int); +/* static int l_unknow (lua_State *L) { void* client = lua_touserdata (L, 1); unknow(client); return 0; } +*/ static int l_log(lua_State *L) { const char* s = luaL_checkstring(L,1); - LOG("%s",s); + server_log("%s",s); return 0; } -dictionary iterate_lua_table(lua_State *L, int index) +dictionary_t iterate_lua_table(lua_State *L, int index) { // Push another reference to the table on top of the stack (so we know // where it is, and this function can work for negative, positive and // pseudo indices - dictionary dic = dict(); + dictionary_t dic = dict(); lua_pushvalue(L, index); // stack now contains: -1 => table lua_pushnil(L); @@ -175,7 +195,7 @@ dictionary iterate_lua_table(lua_State *L, int index) { // the element is a table // create new dictionary - dictionary cdic = iterate_lua_table(L,-2); + dictionary_t cdic = iterate_lua_table(L,-2); dput(dic,key, cdic); } else @@ -198,11 +218,12 @@ dictionary iterate_lua_table(lua_State *L, int index) return dic; } +/* static int l_set_cookie(lua_State* L) { if (lua_istable(L, 3)) { - dictionary d = iterate_lua_table(L,-2); + dictionary_t d = iterate_lua_table(L,-2); if(d) { void* client = lua_touserdata (L, 1); @@ -213,7 +234,8 @@ static int l_set_cookie(lua_State* L) } } return 0; -} +}*/ + static int l_simple_hash(lua_State* L) { const char* s = luaL_checkstring(L,1); @@ -351,7 +373,7 @@ static int l_ws_read_header(lua_State *L) lua_pushnil(L); return 1; } - dictionary dic = iterate_lua_table(L,2); + dictionary_t dic = iterate_lua_table(L,2); if(dic) { // convert dictionary to header @@ -360,7 +382,7 @@ static int l_ws_read_header(lua_State *L) header->opcode = (uint8_t)(R_INT(dic,"opcode")); header->mask = 1; header->plen = R_INT(dic,"plen"); - dictionary d1 = (dictionary)dvalue(dic,"mask_key"); + dictionary_t d1 = (dictionary_t)dvalue(dic,"mask_key"); if(d1) { header->mask_key[0] = (uint8_t)(R_INT(d1,"0")); @@ -430,14 +452,15 @@ static int l_ws_t(lua_State*L) ws_t(client,str); return 1; } -static int l_status(lua_State*L) +/*static int l_status(lua_State*L) { void* client = lua_touserdata (L, 1); int code = (int) luaL_checknumber(L,2); const char* msg = luaL_checkstring(L,3); set_status(client,code,msg); return 1; -} +}*/ + /* * send a file as binary data */ @@ -482,31 +505,73 @@ static int l_status(lua_State*L) return 1; } +static int l_std_error(lua_State* L) +{ + void* client = lua_touserdata (L, 1); + int status = luaL_checknumber(L,2); + const char* msg = luaL_checkstring(L,3); + antd_error(client, status, msg); + return 1; +} +static int l_send_header(lua_State* L) +{ + if (lua_istable(L, 3)) + { + dictionary_t d = iterate_lua_table(L,-2); + if(d) + { + void* client = lua_touserdata (L, 1); + int status = luaL_checknumber(L,2); + antd_response_header_t h; + h.status = status; + h.header = d; + dictionary_t c = iterate_lua_table(L,-1); + h.cookie = NULL; + if(c) + { + h.cookie = list_init(); + if(h.cookie) + { + chain_t it; + for_each_assoc(it,c) + { + list_put_s(&h.cookie,strdup(it->value)); + } + } + freedict(c); + } + antd_send_header(client, &h); + } + } + return 1; +} static const struct luaL_Reg standard [] = { - {"_header", l_header}, - {"_redirect", l_redirect}, - {"_html", l_html}, - {"_text", l_text}, - {"_json", l_json}, - {"_jpeg", l_jpeg}, + //{"_header", l_header}, + //{"_redirect", l_redirect}, + //{"_html", l_html}, + //{"_text", l_text}, + //{"_json", l_json}, + //{"_jpeg", l_jpeg}, + {"_error", l_std_error}, + {"_send_header", l_send_header}, {"b64encode", l_base64_encode}, {"b64decode", l_base64_decode}, - {"_octstream", l_octstream} , - {"_textstream", l_textstream} , - {"_ti", l_ti} , + //{"_octstream", l_octstream} , + //{"_textstream", l_textstream} , + //{"_ti", l_ti} , {"_t", l_t} , {"_f", l_f} , - //{"_fb", l_fb} , + {"_b", l_b} , {"trim", l_trim}, {"upload", l_upload} , {"route", l_route} , {"mime", l_mime} , - {"is_bin", l_is_bin} , - {"_unknow", l_unknow} , - {"_status", l_status}, + //{"is_bin", l_is_bin} , + //{"_unknow", l_unknow} , + //{"_status", l_status}, {"console", l_log} , - {"_setCookie", l_set_cookie}, + //{"_setCookie", l_set_cookie}, {"hash",l_simple_hash}, {"md5",l_md5}, {"sha1",l_sha1},