smr/src/libkore.c

320 lines
7.4 KiB
C
Raw Normal View History

2020-05-16 01:10:11 +02:00
/*Export kore's functions to lua*/
#include <kore/kore.h>
#include <kore/http.h>
#ifdef BUILD_PROD
#include <luajit.h>
#endif
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
//#include <inet/in.h>//linux only I guess
#include "libkore.h"
#include <syslog.h>
#define LUA_PUSH_CONST(L,a) lua_pushnumber(L,a); lua_setfield(L,-2,#a);
2020-05-16 01:10:11 +02:00
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;
}
2020-05-16 01:10:11 +02:00
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},
2020-05-16 01:10:11 +02:00
{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");
2020-05-16 01:10:11 +02:00
lua_pop(L,1);
}