/*Export kore's functions to lua*/ #include #include #ifdef BUILD_PROD #include #endif #include #include #include //#include //linux only I guess #include "libkore.h" #include #define LUA_PUSH_CONST(L,a) lua_pushnumber(L,a); lua_setfield(L,-2,#a); struct http_request* luaL_checkrequest(lua_State *L, int pos){ if(!lua_isuserdata(L,pos)){ lua_pushstring(L,"Bad argument, expected userdata, got "); lua_pushstring(L,lua_typename(L,lua_type(L,pos))); lua_concat(L,2); lua_error(L); } return lua_touserdata(L,pos); } /* http_response(request::userdata, errcode::number, data::string) */ int lhttp_response(lua_State *L){ size_t size; const char *data = luaL_checklstring(L,-1,&size); int httpcode = luaL_checkint(L,-2); struct http_request *req = luaL_checkrequest(L,-3); http_response(req,httpcode,data,size); lua_pop(L,3); return 0; } /* http_method_text(request::userdata)::string */ int lhttp_method_text(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); const char *method = http_method_text(req->method); lua_pushstring(L,method); return 1; } /* http_request_get_path(request::userdata)::string */ int lhttp_request_get_path(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); const char *path = req->path; lua_pushstring(L,path); return 1; } /* http_request_get_host(request::userdata)::string */ int lhttp_request_get_host(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); const char *host = req->host; lua_pushstring(L,host); return 1; } /* http_request_populate_post(request::userdata) */ int lhttp_request_populate_post(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); http_populate_post(req); return 0; } /* http_request_populate_qs(request::userdata) */ int lhttp_request_populate_qs(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); http_populate_qs(req); return 0; } /* http_response_header(request::userdata, header::string, value::string) */ int lhttp_response_header(lua_State *L){ const char *value = luaL_checkstring(L,-1); const char *header = luaL_checkstring(L,-2); struct http_request *req = luaL_checkrequest(L,-3); lua_pop(L,3); http_response_header(req, header, value); return 0; } /* http_response_cookie(req::userdata, name::string, value::string, path::string, expires::number, maxage::number) */ int lhttp_response_cookie(lua_State *L){ //int flags = luaL_checkint(L,-1);//TODO: flags int maxage = luaL_checkint(L,-1); int expires = luaL_checkint(L,-2); const char *path = luaL_checkstring(L,-3); const char *value = luaL_checkstring(L,-4); const char *name = luaL_checkstring(L,-5); struct http_request *req = luaL_checkrequest(L,-6); lua_pop(L,6); http_response_cookie(req,name,value,path,expires,maxage,NULL); return 0; } /* http_request_cookie(req::userdata, name::string)::string | nil */ int lhttp_request_cookie(lua_State *L){ char *value; const char *name = luaL_checkstring(L,-1); struct http_request *req = luaL_checkrequest(L,-2); lua_pop(L,2); if(http_request_cookie(req,name,&value)){ lua_pushstring(L,value); }else{ lua_pushnil(L); } return 1; } /* This method may fail, if it does, it will return false plus an error message http_argument_get_string(request::userdata, name::string)::(string || false, string) */ int lhttp_argument_get_string(lua_State *L){ const char *name = luaL_checkstring(L,-1); struct http_request *req = luaL_checkrequest(L,-2); lua_pop(L,2); const char *value; int err = http_argument_get_string(req,name,&value); if(err == KORE_RESULT_OK){ lua_pushstring(L,value); return 1; }else{ lua_pushboolean(L,0); lua_pushstring(L,"Failed to find argument: "); lua_pushstring(L,name); lua_concat(L,2); return 2; } } /* Get the ip of this connection, ipv6 supported http_request_get_ip(request::userdata)::string */ int lhttp_request_get_ip(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); char addr[INET6_ADDRSTRLEN]; switch(req->owner->family){ case AF_INET: inet_ntop( req->owner->family, &(req->owner->addr.ipv4.sin_addr), addr, sizeof(addr) ); break; case AF_INET6: inet_ntop( req->owner->family, &(req->owner->addr.ipv6.sin6_addr), addr, sizeof(addr) ); break; case AF_UNIX: default: lua_pushstring(L,"Tried to get IP from unknown socket family:"); lua_getglobal(L,"tostring"); lua_pushnumber(L,req->owner->family); lua_call(L,1,1); lua_concat(L,2); lua_error(L); break; } lua_pushstring(L,addr); return 1; } /* http_populate_cookies(request::userdata) */ int lhttp_populate_cookies(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); http_populate_cookies(req); return 0; } /* http_populate_multipart_form(request::userdata) */ int lhttp_populate_multipart_form(lua_State *L){ struct http_request *req = luaL_checkrequest(L,-1); lua_pop(L,1); http_populate_multipart_form(req); return 0; } /* http_file_get(request::userdata, name::string)::string */ int lhttp_file_get(lua_State *L){ const char *name = luaL_checkstring(L,-1); struct http_request *req = luaL_checkrequest(L,-2); lua_pop(L,2); struct http_file *f = http_file_lookup(req, name); if(f == NULL){ lua_pushstring(L,"No such file:"); lua_pushstring(L,name); lua_concat(L,2); lua_error(L); } char s[f->length + 1]; size_t read = http_file_read(f,s,f->length); if(read < f->length){ lua_pushstring(L,"Failed to read contents of:"); lua_pushstring(L,name); lua_concat(L,2); lua_error(L); } s[f->length] = '\0'; lua_pushstring(L,s); return 1; } /* log(priority,string) //formating must be done before calling */ int lkore_log(lua_State *L){ const char *str = luaL_checkstring(L,-1); int prio = luaL_checkint(L,-2); lua_pop(L,2); kore_log(prio,"%s",str); return 0; } static const luaL_Reg kore_funcs[] = { {"http_response", lhttp_response}, {"http_response_header", lhttp_response_header}, {"http_method_text",lhttp_method_text}, {"http_request_get_path",lhttp_request_get_path}, {"http_request_get_host",lhttp_request_get_host}, {"http_request_populate_post",lhttp_request_populate_post}, {"http_request_populate_qs",lhttp_request_populate_qs}, {"http_request_cookie",lhttp_request_cookie}, {"http_response_cookie",lhttp_response_cookie}, {"http_argument_get_string",lhttp_argument_get_string}, {"http_request_get_ip",lhttp_request_get_ip}, {"http_populate_cookies",lhttp_populate_cookies}, {"http_populate_multipart_form",lhttp_populate_multipart_form}, {"http_file_get",lhttp_file_get}, {"log",lkore_log}, {NULL,NULL} }; static const luaL_Reg http_request_meta[] = { {NULL,NULL} }; void load_kore_libs(lua_State *L){ luaL_newmetatable(L,"http_request");//{m_http_request} lua_newtable(L);//{m_http_request},{} luaL_register(L,NULL,http_request_meta);//{m_http_request},{meta} lua_setfield(L,-2,"__index");//{m_http_request} lua_pop(L,1); lua_getglobal(L,"_G"); luaL_register(L,NULL,kore_funcs); //Push priority constants for use with log() LUA_PUSH_CONST(L,LOG_EMERG); LUA_PUSH_CONST(L,LOG_ALERT); LUA_PUSH_CONST(L,LOG_CRIT); LUA_PUSH_CONST(L,LOG_ERR); LUA_PUSH_CONST(L,LOG_WARNING); LUA_PUSH_CONST(L,LOG_NOTICE); LUA_PUSH_CONST(L,LOG_INFO); LUA_PUSH_CONST(L,LOG_DEBUG); #ifdef BUILD_PROD lua_pushboolean(1); #else lua_pushboolean(0); #endif lua_setfield(L,-2,"PRODUCTION"); lua_pop(L,1); }