From 9943dbdcc8b698edb8e6d5913cf1cb5f948d53b8 Mon Sep 17 00:00:00 2001 From: Xuan Sang LE Date: Sat, 29 Jul 2017 22:00:34 +0200 Subject: [PATCH] using shared library for common api --- .gitignore | 1 + Makefile | 73 ++++-- antd | 9 +- http_server.c | 505 ++++++++++++++++++++++++++++++++++++++ http_server.h | 23 +- httpd.c | 2 +- plugin_manager.c | 503 ------------------------------------- plugin_manager.h | 23 +- plugins/cookiex/cookiex.c | 2 +- plugins/dbhelper.h | 5 +- plugins/handle.c | 217 ++++++++++++++++ plugins/handle.h | 48 ++++ plugins/plugin.c | 214 +--------------- plugins/plugin.h | 52 +--- 14 files changed, 874 insertions(+), 803 deletions(-) create mode 100644 plugins/handle.c create mode 100644 plugins/handle.h diff --git a/.gitignore b/.gitignore index a82bca8..b9c4eb4 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ modules.order Module.symvers Mkfile.old dkms.con +.DS_Store diff --git a/Makefile b/Makefile index 1229bec..8c2f309 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,7 @@ +USE_DB=TRUE CC=gcc EXT=dylib -SERVER=plugin_manager.o \ - plugins/ini.o \ - http_server.o \ - plugins/dictionary.o \ - plugins/base64.o \ - plugins/sha1.o \ - plugins/utils.o -SERVERLIB=-lpthread -ldl + UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Linux) BUILDIRD=/opt/www @@ -17,46 +11,75 @@ ifeq ($(UNAME_S),Darwin) BUILDIRD=../ant-build PF_FLAG= -DMACOS endif -CFLAGS=-W -Wall -g -std=c99 -D DEBUG -D USE_DB $(PF_FLAG) + +ifeq ($(USE_DB),TRUE) + DB_OBJ=plugins/dbhelper.o + DB_LIB=-lsqlite3 + DB_FLAG=-D USE_DB +endif + +ifeq ($(USE_DB),FALSE) + DB_OBJ= + DB_LIB= + DB_FLAG= +endif + + +CFLAGS= -W -Wall -g -std=c99 -D DEBUG $(DB_FLAG) $(PF_FLAG) + +LIB_PATH=$(BUILDIRD)/plugins +LIB_NAME=libantd +LIB_FLAG= $(LIB_PATH$)/$(LIB_NAME).$(EXT) +SERVERLIB=-lpthread -ldl $(LIB_FLAG) + +SERVER_O=plugin_manager.o \ + http_server.o \ + httpd.o #-lsocket PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT) wterm.$(EXT) nodedaemon.$(EXT) cookiex.$(EXT) wsimg.$(EXT) -PLUGINSDEP = plugins/ini.o \ - plugins/plugin.o \ - plugins/dbhelper.o \ - plugins/dictionary.o \ - plugins/base64.o \ - plugins/utils.o \ - plugins/ws.o \ - plugins/sha1.o \ - plugins/list.o -PLUGINLIBS = -lsqlite3 +LIBOBJS = plugins/ini.o \ + plugins/handle.o \ + $(DB_OBJ) \ + plugins/dictionary.o \ + plugins/base64.o \ + plugins/utils.o \ + plugins/ws.o \ + plugins/sha1.o \ + plugins/list.o + +PLUGINSDEP = plugins/plugin.o + main: httpd plugins -httpd:$(SERVER) - $(CC) $(CFLAGS) $(SERVERLIB) $(SERVER) -o $(BUILDIRD)/httpd httpd.c +httpd: lib $(SERVER_O) + $(CC) $(CFLAGS) $(SERVER_O) $(SERVERLIB) -o $(BUILDIRD)/httpd cp antd $(BUILDIRD) +lib: $(LIBOBJS) + $(CC) $(CFLAGS) $(DB_LIB) -shared -o $(LIB_PATH$)/$(LIB_NAME).$(EXT) $(LIBOBJS) %.o: %.c $(CC) -fPIC $(CFLAGS) -c $< -o $@ + plugins: $(PLUGINS) %.$(EXT): $(PLUGINSDEP) for file in $(wildcard plugins/$(basename $@)/*.c) ; do\ $(CC) -fPIC $(CFLAGS) -c $$file -o $$file.o; \ done - $(CC) $(CFLAGS) $(PLUGINLIBS) -shared -o $(BUILDIRD)/plugins/$(basename $@).$(EXT) \ - $(PLUGINSDEP) plugins/$(basename $@)/*.c.o + $(CC) $(CFLAGS) $(PLUGINLIBS) $(LIB_FLAG) -shared -o $(BUILDIRD)/plugins/$(basename $@).$(EXT) \ + $(PLUGINSDEP) plugins/$(basename $@)/*.c.o clean: sclean pclean sclean: - rm -f *.o $(BUILDIRD)/httpd + -rm -f *.o $(BUILDIRD)/httpd + -rm *.$(EXT) pclean: - rm -rf $(BUILDIRD)/plugins/* plugins/*.o + -rm -rf $(BUILDIRD)/plugins/* plugins/*.o -for file in plugins/* ;do \ if [ -d "$$file" ]; then \ rm "$$file"/*.o; \ diff --git a/antd b/antd index edccb44..eb341e1 100755 --- a/antd +++ b/antd @@ -1 +1,8 @@ -LD_LIBRARY_PATH=$(dirname "$0")/plugins $(dirname "$0")/httpd $(dirname "$0")/config.ini +#!/bin/sh +UNAME=`uname -s` + +if [ "$UNAME" == "Darwin" ]; then + DYLD_LIBRARY_PATH=$(dirname "$0")/plugins/ $(dirname "$0")/httpd $(dirname "$0")/config.ini +else + LD_LIBRARY_PATH=$(dirname "$0")/plugins/ $(dirname "$0")/httpd $(dirname "$0")/config.ini +fi diff --git a/http_server.c b/http_server.c index eff3bbf..71a84a6 100644 --- a/http_server.c +++ b/http_server.c @@ -381,3 +381,508 @@ void unimplemented(int client) } + +/** + * Decode the HTTP POST request with URL encode + * @param client socket client + * @param len content length + * @return query string + */ +char* post_url_decode(int client,int len) +{ + char *query = (char*) malloc((len+1)*sizeof(char)); + for (int i = 0; i < len; i++) { + recv(client, (query+i), 1, 0); + } + query[len]='\0'; + //query = url_decode(query); + LOG("POST Query %s\n", query); + return query; +} +/** + * Decode the HTTP request + * Get the cookie values + * if it is the GET request, decode the query string into a dictionary + * if it is a POST, check the content type of the request + * - if it is a POST request with URL encoded : decode the url encode + * - if it is a POST request with multipart form data: de code the multipart + * - if other - UNIMPLEMENTED + * @param client socket client + * @param method HTTP method + * @param query query string in case of GET + * @return a dictionary of key- value + */ +dictionary decode_request(int client,const char* method,const char* query) +{ + dictionary request = NULL; + dictionary cookie = NULL; + dictionary xheader = dict(); + char* line; + char * token; + if(strcmp(method,"GET") == 0) + { + // this for check if web socket is enabled + int ws= 0; + char* ws_key = NULL; + while((line = read_line(client)) && strcmp("\r\n",line)) + { + trim(line, '\n'); + trim(line, '\r'); + token = strsep(&line,":"); + trim(token,' '); + trim(line,' '); + dput(xheader,token,line); + if(token != NULL &&strcasecmp(token,"Cookie") == 0) + { + if(!cookie) cookie = decode_cookie(line); + } + else if(token != NULL && strcasecmp(token,"Upgrade") == 0) + { + // verify that the connection is upgrade to websocket + trim(line, ' '); + if(line != NULL && strcasecmp(line,"websocket") == 0) + ws = 1; + } else if(token != NULL && strcasecmp(token,"Sec-WebSocket-Key") == 0) + { + // get the key from the client + trim(line, ' '); + ws_key = strdup(line); + } + } + request = decode_url_request(query); + if(ws && ws_key != NULL) + { + ws_confirm_request(client, ws_key); + free(ws_key); + // insert wsocket flag to request + // plugin should handle this ugraded connection + // not the server + if(!request) request = dict(); + dput(request,"__web_socket__","1"); + } + } + else + { + char* ctype = NULL; + int clen = -1; + line = read_line(client); + while (line && strcmp("\r\n",line)) + { + //printf("%s\n",line); + trim(line, '\n'); + trim(line, '\r'); + token = strsep(&line,":"); + trim(token,' '); + trim(line, ' '); + dput(xheader,token,line); + if(token != NULL &&strcasecmp(token,"Content-Type") == 0) + { + ctype = strsep(&line,":"); + trim(ctype,' '); + } else if(token != NULL &&strcasecmp(token,"Content-Length") == 0) + { + token = strsep(&line,":"); + trim(token,' '); + clen = atoi(token); + } + else if(token != NULL &&strcasecmp(token,"Cookie") == 0) + { + if(!cookie) cookie = decode_cookie(line); + } + + line = read_line(client); + } + free(line); + if(ctype == NULL || clen == -1) + { + LOG("Bad request\n"); + return NULL; + } + // decide what to do with the data + if(strstr(ctype,FORM_URL_ENCODE) > 0) + { + request = decode_url_request(post_url_decode(client,clen)); + } else if(strstr(ctype,FORM_MULTI_PART)> 0) + { + //printf("Multi part form : %s\n", ctype); + request = decode_multi_part_request(client,ctype); + } + else if(strstr(ctype,APP_JSON) > 0) + { + char* query = json_data_decode(client,clen); + request = dict(); + dput(request,"json", strdup(query)); + free(query); + } + else + { + LOG("Un supported yet %s\n",ctype); + return NULL; + } + } + //if(cookie->key == NULL) {free(cookie);cookie= NULL;} + if(!request) + request = dict(); + + dput(request,"cookie",cookie); + dput(request,"__xheader__",xheader); + return request; +} +void __px(const char* data,int size) +{ + for (int i = 0; i < size; ++i) + printf(" %02x", data[i]); + + printf("\n"); +} +/** +* Send header to the client to confirm +* that the websocket is accepted by +* our server +*/ +void ws_confirm_request(int client, const char* key) +{ + char buf[256]; + char rkey[128]; + char sha_d[20]; + char base64[64]; + strcpy(rkey,key); + strcat(rkey,WS_MAGIC_STRING); + //printf("RESPONDKEY '%s'\n", rkey); + SHA1_CTX context; + SHA1_Init(&context); + SHA1_Update(&context, rkey, strlen(rkey)); + SHA1_Final(&context, sha_d); + Base64encode(base64, sha_d, 20); + //printf("Base 64 '%s'\n", base64); + // send accept to client + sprintf(buf, "HTTP/1.1 101 Switching Protocols\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Upgrade: websocket\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Connection: Upgrade\r\n"); + send(client, buf, strlen(buf), 0); + sprintf(buf, "Sec-WebSocket-Accept: %s\r\n",base64); + send(client, buf, strlen(buf), 0); + sprintf(buf, "\r\n"); + send(client, buf, strlen(buf), 0); + + LOG("%s\n", "Websocket is now enabled for plugin"); +} +/** + * Decode the cookie header to a dictionary + * @param client The client socket + * @return The Dictionary socket or NULL + */ +dictionary decode_cookie(const char* line) +{ + char *token,*token1; + char *cpstr = strdup(line); + trim(cpstr,' '); + trim(cpstr,'\n'); + trim(cpstr,'\r'); + //printf("FUCKIT %s\n",cpstr ); + dictionary dic = NULL; + while((token = strsep(&cpstr,";"))) + { + trim(token,' '); + token1 = strsep(&token,"="); + if(token1) + { + if(dic == NULL) + dic = dict(); + //LOG("Found cookie : %s = %s\n",token1,token); + dput(dic,token1,strdup(token)); + } + } + //} + return dic; + //free(cpstr); +} +/** + * Decode the multi-part form data from the POST request + * If it is a file upload, copy the file to tmp dir + * and generate the metadata for the server-side + * @param client the socket client + * @param ctype Content-Type of the request + * @param clen Content length, but not used here + * @return a dictionary of key - value + */ +dictionary decode_multi_part_request(int client,const char* ctype) +{ + char * boundary; + char * boundend; + char * line; + char * str_copy = strdup(ctype); + char* token; + char* keytoken ; + char* valtoken ; + char* part_name; + char* part_file; + char* file_path; + char buf[BUFFLEN]; + char* field; + dictionary dic = NULL; + FILE *fp = NULL; + boundary = strsep(&str_copy,"="); //discard first part + boundary = strsep(&str_copy,"="); + if(boundary && strlen(boundary)>0) + { + dic = dict(); + trim(boundary,' '); + boundend = __s("%s--",boundary); + //find first boundary + while((line = read_line(client))&&strstr(line,boundary) <= 0); + // loop through each part separated by the boundary + while(line && strstr(line,boundary) > 0){ + // search for content disposition: + while((line = read_line(client)) && + strstr(line,"Content-Disposition:") <= 0); + if(strstr(line,"Content-Disposition:") <= 0) return NULL; + // extract parameters from header + part_name = NULL; + part_file = NULL; + while((token = strsep(&line,";"))) + { + keytoken = strsep(&token,"="); + if(keytoken && strlen(keytoken)>0) + { + trim(keytoken,' '); + valtoken = strsep(&token,"="); + if(valtoken) + { + trim(valtoken,' '); + trim(valtoken,'\n'); + trim(valtoken,'\r'); + trim(valtoken,'\"'); + if(strcmp(keytoken,"name") == 0) + { + part_name = valtoken; + } else if(strcmp(keytoken,"filename") == 0) + { + part_file = valtoken; + } + } + } + } + // get the binary data + if(part_name != NULL) + { + // go to the beginer of data bock + while((line = read_line(client)) && strcmp(line,"\r\n") != 0); + if(part_file == NULL) + { + /** + * This allow only 1024 bytes of data (max), + * out of this range, the data is cut out. + * Need an efficient way to handle this + */ + line = read_line(client); + trim(line,'\n'); + trim(line,'\r'); + trim(line,' '); + dput(dic,part_name,line); + // find the next boundary + while((line = read_line(client)) && strstr(line,boundary) <= 0); + } + else + { + file_path = __s("%s%s.%u",server_config.tmpdir,part_file,(unsigned)time(NULL)); + fp=fopen(file_path, "wb"); + if(fp) + { + int totalsize=0,len=0; + //read until the next boundary + while((len = read_buf(client,buf,sizeof(buf))) > 0 && strstr(buf,boundary) <= 0) + { + fwrite(buf, len, 1, fp); + totalsize += len; + } + //remove \r\n at the end + fseek(fp,-2, SEEK_CUR); + totalsize -= 2; + fclose(fp); + line = buf; + + field = __s("%s.file",part_name); + dput(dic,field,part_file); + field = __s("%s.tmp",part_name); + dput(dic,field,strdup(file_path)); + field = __s("%s.size",part_name); + dput(dic,field,__s("%d",totalsize)); + field = __s("%s.ext",part_name); + dput(dic,field,ext(part_file)); + free(field); + + } + else + { + LOG("Cannot wirte file to :%s\n", file_path ); + } + free(file_path); + } + } + //printf("[Lines]:%s\n",line); + // check if end of request + if(line&&strstr(line,boundend)>0) + { + LOG("End request %s\n", boundend); + break; + } + } + } + free(str_copy); + return dic; +} +/** + * Decode a query string (GET request or POST URL encoded) to + * a dictionary of key-value + * @param query : the query string + * @return a dictionary of key-value + */ +dictionary decode_url_request(const char* query) +{ + char* str_copy = strdup(query); + //str_copy = ; + char* token; + if(query == NULL) return NULL; + if(strlen(query) == 0) return NULL; + dictionary dic = dict(); + while ((token = strsep(&str_copy, "&"))) + { + char* key; + char* val; + if(strlen(token)>0) + { + key = strsep(&token,"="); + if(key && strlen(key)>0) + { + val = strsep(&token,"="); + dput(dic,key,url_decode(val)); + } + } + } + free(str_copy); + return dic; +} +/** +* Decode JSON query string to string +*/ +char* json_data_decode(int client,int len) +{ + char *query = (char*) malloc((len+1)*sizeof(char)); + for (int i = 0; i < len; i++) { + recv(client, (query+i), 1, 0); + } + query[len]='\0'; + //query = url_decode(query); + LOG("JSON Query %s\n", query); + return query; +} + +/** + * read the request as a string line format + * @param sock socket + * @return a request string + */ +char* read_line(int sock) +{ + char buf[BUFFLEN]; + read_buf(sock,buf,sizeof(buf)); + return strdup(buf); +} +/** + * Read the socket request in to a buffer or size + * The data is read until the buffer is full or + * there are a carrier return character + * @param sock socket + * @param buf buffer + * @param size size of buffer + * @return number of bytes read + */ +int read_buf(int sock, char*buf,int size) +{ + int i = 0; + char c = '\0'; + int n; + while ((i < size - 1) && (c != '\n')) + { + n = recv(sock, &c, 1, 0); + if (n > 0) + { + buf[i] = c; + i++; + } + else + c = '\n'; + } + buf[i] = '\0'; + return i; +} + +/** + * Execute a plugin based on the http requeset + * First decode the http request header to find the correct plugin + * and the correct function on the plugin + * Second, decode all parameters necessary of the request and pass it + * to the callback function. + * Execute the callback function if sucess + * @param client soket client + * @param path request path + * @param method request method + * @param query_string GET query string + * @return -1 if failure + * 1 if sucess + */ +int execute_plugin(int client, const char *path, const char *method, const char *query_string) +{ + char pname[255]; + char pfunc[255]; + void (*fn)(int, const char*,const char*, dictionary); + struct plugin_entry *plugin ; + int plen = strlen(path); + char * rpath = (char*) malloc((plen+1)*sizeof(char)); + char *error; + memcpy(rpath,path+1,plen); + rpath[plen] = '\0'; + trim(rpath,'/'); + char * delim = strchr(rpath,'/'); + if(delim == NULL) + { + strcpy(pname,rpath); + strcpy(pfunc,"default"); + } + else + { + int npos,fpos; + npos = delim - rpath; + fpos = strlen(rpath) - npos ; + memcpy(pname,rpath,npos); + pname[npos] = '\0'; + memcpy(pfunc,rpath+npos+1,fpos); + pfunc[fpos-1]='\0'; + } + LOG("Client %d\n",client ); + LOG("Path : '%s'\n", rpath); + LOG("Method:%s\n", method); + LOG("Plugin name '%s'\n",pname); + LOG("Query path. '%s'\n", pfunc); + LOG("query :%s\n", query_string); + + //load the plugin + if((plugin = plugin_lookup(pname)) == NULL) + if((plugin= plugin_load(pname)) == NULL) + return -1; + // load the function + fn = (void (*)(int, const char *, const char*, dictionary))dlsym(plugin->handle, PLUGIN_HANDLER); + if ((error = dlerror()) != NULL) + { + LOG("Problem when finding %s method from %s : %s \n", PLUGIN_HANDLER, pname,error); + return -1; + } + dictionary dic = decode_request(client,method,query_string); + (*fn)(client,method,pfunc,dic); + free(dic); + free(rpath); + return 1; +} diff --git a/http_server.h b/http_server.h index e3faa9d..f1990ac 100644 --- a/http_server.h +++ b/http_server.h @@ -4,8 +4,16 @@ #include #include #include +#include +#include "plugins/dictionary.h" #include "plugin_manager.h" +#define FORM_URL_ENCODE "application/x-www-form-urlencoded" +#define FORM_MULTI_PART "multipart/form-data" +#define APP_JSON "application/json" +#define PLUGIN_HANDLER "handler" +#define WS_MAGIC_STRING "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + #define ISspace(x) isspace((int)(x)) @@ -21,4 +29,17 @@ void headers(int, const char *); void not_found(int); void serve_file(int, const char *); int startup(unsigned *); -void unimplemented(int); \ No newline at end of file +void unimplemented(int); + +void ws_confirm_request(int, const char*); +char* post_url_decode(int client,int len); +dictionary decode_url_request(const char* query); +dictionary decode_request(int client,const char* method,const char* query); +dictionary decode_multi_part_request(int,const char*); +dictionary decode_cookie(const char*); +char* json_data_decode(int,int); +char* read_line(int sock); +int read_buf(int sock,char* buf,int i); + +int execute_plugin(int client, const char *path, + const char *method, const char *query_string); \ No newline at end of file diff --git a/httpd.c b/httpd.c index a67e63d..34ead3f 100644 --- a/httpd.c +++ b/httpd.c @@ -9,7 +9,7 @@ static int config_handler(void* conf, const char* section, const char* name, const char* value) { config_t* pconfig = (config_t*)conf; - char * ppath = NULL; + //char * ppath = NULL; if (MATCH("SERVER", "port")) { pconfig->port = atoi(value); } else if (MATCH("SERVER", "plugins")) { diff --git a/plugin_manager.c b/plugin_manager.c index 0ec0873..20fd410 100644 --- a/plugin_manager.c +++ b/plugin_manager.c @@ -4,443 +4,6 @@ */ static struct plugin_entry *plugin_table[HASHSIZE]; config_t server_config; -/** - * Decode the HTTP POST request with URL encode - * @param client socket client - * @param len content length - * @return query string - */ -char* post_url_decode(int client,int len) -{ - char *query = (char*) malloc((len+1)*sizeof(char)); - for (int i = 0; i < len; i++) { - recv(client, (query+i), 1, 0); - } - query[len]='\0'; - //query = url_decode(query); - LOG("POST Query %s\n", query); - return query; -} -/** - * Decode the HTTP request - * Get the cookie values - * if it is the GET request, decode the query string into a dictionary - * if it is a POST, check the content type of the request - * - if it is a POST request with URL encoded : decode the url encode - * - if it is a POST request with multipart form data: de code the multipart - * - if other - UNIMPLEMENTED - * @param client socket client - * @param method HTTP method - * @param query query string in case of GET - * @return a dictionary of key- value - */ -dictionary decode_request(int client,const char* method,const char* query) -{ - dictionary request = NULL; - dictionary cookie = NULL; - dictionary xheader = dict(); - char* line; - char * token; - if(strcmp(method,"GET") == 0) - { - // this for check if web socket is enabled - int ws= 0; - char* ws_key = NULL; - while((line = read_line(client)) && strcmp("\r\n",line)) - { - trim(line, '\n'); - trim(line, '\r'); - token = strsep(&line,":"); - trim(token,' '); - trim(line,' '); - dput(xheader,token,line); - if(token != NULL &&strcasecmp(token,"Cookie") == 0) - { - if(!cookie) cookie = decode_cookie(line); - } - else if(token != NULL && strcasecmp(token,"Upgrade") == 0) - { - // verify that the connection is upgrade to websocket - trim(line, ' '); - if(line != NULL && strcasecmp(line,"websocket") == 0) - ws = 1; - } else if(token != NULL && strcasecmp(token,"Sec-WebSocket-Key") == 0) - { - // get the key from the client - trim(line, ' '); - ws_key = strdup(line); - } - } - request = decode_url_request(query); - if(ws && ws_key != NULL) - { - ws_confirm_request(client, ws_key); - free(ws_key); - // insert wsocket flag to request - // plugin should handle this ugraded connection - // not the server - if(!request) request = dict(); - dput(request,"__web_socket__","1"); - } - } - else - { - char* ctype = NULL; - int clen = -1; - line = read_line(client); - while (line && strcmp("\r\n",line)) - { - //printf("%s\n",line); - trim(line, '\n'); - trim(line, '\r'); - token = strsep(&line,":"); - trim(token,' '); - trim(line, ' '); - dput(xheader,token,line); - if(token != NULL &&strcasecmp(token,"Content-Type") == 0) - { - ctype = strsep(&line,":"); - trim(ctype,' '); - } else if(token != NULL &&strcasecmp(token,"Content-Length") == 0) - { - token = strsep(&line,":"); - trim(token,' '); - clen = atoi(token); - } - else if(token != NULL &&strcasecmp(token,"Cookie") == 0) - { - if(!cookie) cookie = decode_cookie(line); - } - - line = read_line(client); - } - free(line); - if(ctype == NULL || clen == -1) - { - LOG("Bad request\n"); - return NULL; - } - // decide what to do with the data - if(strstr(ctype,FORM_URL_ENCODE) > 0) - { - request = decode_url_request(post_url_decode(client,clen)); - } else if(strstr(ctype,FORM_MULTI_PART)> 0) - { - //printf("Multi part form : %s\n", ctype); - request = decode_multi_part_request(client,ctype); - } - else if(strstr(ctype,APP_JSON) > 0) - { - char* query = json_data_decode(client,clen); - request = dict(); - dput(request,"json", strdup(query)); - free(query); - } - else - { - LOG("Un supported yet %s\n",ctype); - return NULL; - } - } - //if(cookie->key == NULL) {free(cookie);cookie= NULL;} - if(!request) - request = dict(); - - dput(request,"cookie",cookie); - dput(request,"__xheader__",xheader); - return request; -} -void __px(const char* data,int size) -{ - for (int i = 0; i < size; ++i) - printf(" %02x", data[i]); - - printf("\n"); -} -/** -* Send header to the client to confirm -* that the websocket is accepted by -* our server -*/ -void ws_confirm_request(int client, const char* key) -{ - char buf[256]; - char rkey[128]; - char sha_d[20]; - char base64[64]; - strcpy(rkey,key); - strcat(rkey,WS_MAGIC_STRING); - //printf("RESPONDKEY '%s'\n", rkey); - SHA1_CTX context; - SHA1_Init(&context); - SHA1_Update(&context, rkey, strlen(rkey)); - SHA1_Final(&context, sha_d); - Base64encode(base64, sha_d, 20); - //printf("Base 64 '%s'\n", base64); - // send accept to client - sprintf(buf, "HTTP/1.1 101 Switching Protocols\r\n"); - send(client, buf, strlen(buf), 0); - sprintf(buf, "Upgrade: websocket\r\n"); - send(client, buf, strlen(buf), 0); - sprintf(buf, "Connection: Upgrade\r\n"); - send(client, buf, strlen(buf), 0); - sprintf(buf, "Sec-WebSocket-Accept: %s\r\n",base64); - send(client, buf, strlen(buf), 0); - sprintf(buf, "\r\n"); - send(client, buf, strlen(buf), 0); - - LOG("%s\n", "Websocket is now enabled for plugin"); -} -/** - * Decode the cookie header to a dictionary - * @param client The client socket - * @return The Dictionary socket or NULL - */ -dictionary decode_cookie(const char* line) -{ - char *token,*token1; - char *cpstr = strdup(line); - trim(cpstr,' '); - trim(cpstr,'\n'); - trim(cpstr,'\r'); - //printf("FUCKIT %s\n",cpstr ); - dictionary dic = NULL; - while((token = strsep(&cpstr,";"))) - { - trim(token,' '); - token1 = strsep(&token,"="); - if(token1) - { - if(dic == NULL) - dic = dict(); - //LOG("Found cookie : %s = %s\n",token1,token); - dput(dic,token1,strdup(token)); - } - } - //} - return dic; - //free(cpstr); -} -/** - * Decode the multi-part form data from the POST request - * If it is a file upload, copy the file to tmp dir - * and generate the metadata for the server-side - * @param client the socket client - * @param ctype Content-Type of the request - * @param clen Content length, but not used here - * @return a dictionary of key - value - */ -dictionary decode_multi_part_request(int client,const char* ctype) -{ - char * boundary; - char * boundend; - char * line; - char * str_copy = strdup(ctype); - char* token; - char* keytoken ; - char* valtoken ; - char* part_name; - char* part_file; - char* file_path; - char buf[BUFFLEN]; - char* field; - dictionary dic = NULL; - FILE *fp = NULL; - boundary = strsep(&str_copy,"="); //discard first part - boundary = strsep(&str_copy,"="); - if(boundary && strlen(boundary)>0) - { - dic = dict(); - trim(boundary,' '); - boundend = __s("%s--",boundary); - //find first boundary - while((line = read_line(client))&&strstr(line,boundary) <= 0); - // loop through each part separated by the boundary - while(line && strstr(line,boundary) > 0){ - // search for content disposition: - while((line = read_line(client)) && - strstr(line,"Content-Disposition:") <= 0); - if(strstr(line,"Content-Disposition:") <= 0) return NULL; - // extract parameters from header - part_name = NULL; - part_file = NULL; - while((token = strsep(&line,";"))) - { - keytoken = strsep(&token,"="); - if(keytoken && strlen(keytoken)>0) - { - trim(keytoken,' '); - valtoken = strsep(&token,"="); - if(valtoken) - { - trim(valtoken,' '); - trim(valtoken,'\n'); - trim(valtoken,'\r'); - trim(valtoken,'\"'); - if(strcmp(keytoken,"name") == 0) - { - part_name = valtoken; - } else if(strcmp(keytoken,"filename") == 0) - { - part_file = valtoken; - } - } - } - } - // get the binary data - if(part_name != NULL) - { - // go to the beginer of data bock - while((line = read_line(client)) && strcmp(line,"\r\n") != 0); - if(part_file == NULL) - { - /** - * This allow only 1024 bytes of data (max), - * out of this range, the data is cut out. - * Need an efficient way to handle this - */ - line = read_line(client); - trim(line,'\n'); - trim(line,'\r'); - trim(line,' '); - dput(dic,part_name,line); - // find the next boundary - while((line = read_line(client)) && strstr(line,boundary) <= 0); - } - else - { - file_path = __s("%s%s.%u",server_config.tmpdir,part_file,(unsigned)time(NULL)); - fp=fopen(file_path, "wb"); - if(fp) - { - int totalsize=0,len=0; - //read until the next boundary - while((len = read_buf(client,buf,sizeof(buf))) > 0 && strstr(buf,boundary) <= 0) - { - fwrite(buf, len, 1, fp); - totalsize += len; - } - //remove \r\n at the end - fseek(fp,-2, SEEK_CUR); - totalsize -= 2; - fclose(fp); - line = buf; - - field = __s("%s.file",part_name); - dput(dic,field,part_file); - field = __s("%s.tmp",part_name); - dput(dic,field,strdup(file_path)); - field = __s("%s.size",part_name); - dput(dic,field,__s("%d",totalsize)); - field = __s("%s.ext",part_name); - dput(dic,field,ext(part_file)); - free(field); - - } - else - { - LOG("Cannot wirte file to :%s\n", file_path ); - } - free(file_path); - } - } - //printf("[Lines]:%s\n",line); - // check if end of request - if(line&&strstr(line,boundend)>0) - { - LOG("End request %s\n", boundend); - break; - } - } - } - free(str_copy); - return dic; -} -/** - * Decode a query string (GET request or POST URL encoded) to - * a dictionary of key-value - * @param query : the query string - * @return a dictionary of key-value - */ -dictionary decode_url_request(const char* query) -{ - char* str_copy = strdup(query); - //str_copy = ; - char* token; - if(query == NULL) return NULL; - if(strlen(query) == 0) return NULL; - dictionary dic = dict(); - while ((token = strsep(&str_copy, "&"))) - { - char* key; - char* val; - if(strlen(token)>0) - { - key = strsep(&token,"="); - if(key && strlen(key)>0) - { - val = strsep(&token,"="); - dput(dic,key,url_decode(val)); - } - } - } - free(str_copy); - return dic; -} -/** -* Decode JSON query string to string -*/ -char* json_data_decode(int client,int len) -{ - char *query = (char*) malloc((len+1)*sizeof(char)); - for (int i = 0; i < len; i++) { - recv(client, (query+i), 1, 0); - } - query[len]='\0'; - //query = url_decode(query); - LOG("JSON Query %s\n", query); - return query; -} - -/** - * read the request as a string line format - * @param sock socket - * @return a request string - */ -char* read_line(int sock) -{ - char buf[BUFFLEN]; - read_buf(sock,buf,sizeof(buf)); - return strdup(buf); -} -/** - * Read the socket request in to a buffer or size - * The data is read until the buffer is full or - * there are a carrier return character - * @param sock socket - * @param buf buffer - * @param size size of buffer - * @return number of bytes read - */ -int read_buf(int sock, char*buf,int size) -{ - int i = 0; - char c = '\0'; - int n; - while ((i < size - 1) && (c != '\n')) - { - n = recv(sock, &c, 1, 0); - if (n > 0) - { - buf[i] = c; - i++; - } - else - c = '\n'; - } - buf[i] = '\0'; - return i; -} /** * Locate a plugin in the plugin table @@ -570,69 +133,3 @@ void unload_all_plugin() exit(0); } -/** - * Execute a plugin based on the http requeset - * First decode the http request header to find the correct plugin - * and the correct function on the plugin - * Second, decode all parameters necessary of the request and pass it - * to the callback function. - * Execute the callback function if sucess - * @param client soket client - * @param path request path - * @param method request method - * @param query_string GET query string - * @return -1 if failure - * 1 if sucess - */ -int execute_plugin(int client, const char *path, const char *method, const char *query_string) -{ - char pname[255]; - char pfunc[255]; - void (*fn)(int, const char*,const char*, dictionary); - struct plugin_entry *plugin ; - int plen = strlen(path); - char * rpath = (char*) malloc((plen+1)*sizeof(char)); - char *error; - memcpy(rpath,path+1,plen); - rpath[plen] = '\0'; - trim(rpath,'/'); - char * delim = strchr(rpath,'/'); - if(delim == NULL) - { - strcpy(pname,rpath); - strcpy(pfunc,"default"); - } - else - { - int npos,fpos; - npos = delim - rpath; - fpos = strlen(rpath) - npos ; - memcpy(pname,rpath,npos); - pname[npos] = '\0'; - memcpy(pfunc,rpath+npos+1,fpos); - pfunc[fpos-1]='\0'; - } - LOG("Client %d\n",client ); - LOG("Path : '%s'\n", rpath); - LOG("Method:%s\n", method); - LOG("Plugin name '%s'\n",pname); - LOG("Query path. '%s'\n", pfunc); - LOG("query :%s\n", query_string); - - //load the plugin - if((plugin = plugin_lookup(pname)) == NULL) - if((plugin= plugin_load(pname)) == NULL) - return -1; - // load the function - fn = (void (*)(int, const char *, const char*, dictionary))dlsym(plugin->handle, PLUGIN_HANDLER); - if ((error = dlerror()) != NULL) - { - LOG("Problem when finding %s method from %s : %s \n", PLUGIN_HANDLER, pname,error); - return -1; - } - dictionary dic = decode_request(client,method,query_string); - (*fn)(client,method,pfunc,dic); - free(dic); - free(rpath); - return 1; -} diff --git a/plugin_manager.h b/plugin_manager.h index 76d50bd..a8e92f6 100644 --- a/plugin_manager.h +++ b/plugin_manager.h @@ -1,13 +1,9 @@ +#ifndef PLUGIN_MANAGER_H +#define PLUGIN_MANAGER_H #include -#include -#include "plugins/dictionary.h" +#include "plugins/utils.h" #include "config.h" -#define FORM_URL_ENCODE "application/x-www-form-urlencoded" -#define FORM_MULTI_PART "multipart/form-data" -#define APP_JSON "application/json" -#define PLUGIN_HANDLER "handler" -#define WS_MAGIC_STRING "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" struct plugin_entry { struct plugin_entry *next; char *pname; @@ -22,14 +18,5 @@ void unload_all_plugin(); void unload_plugin(struct plugin_entry*); void unload_plugin_by_name(const char*); void * plugin_from_file(char* name); -void ws_confirm_request(int, const char*); -char* post_url_decode(int client,int len); -dictionary decode_url_request(const char* query); -dictionary decode_request(int client,const char* method,const char* query); -dictionary decode_multi_part_request(int,const char*); -dictionary decode_cookie(const char*); -char* json_data_decode(int,int); -char* read_line(int sock); -int read_buf(int sock,char* buf,int i); -int execute_plugin(int client, const char *path, - const char *method, const char *query_string); \ No newline at end of file + +#endif \ No newline at end of file diff --git a/plugins/cookiex/cookiex.c b/plugins/cookiex/cookiex.c index d1d260f..59f3c19 100644 --- a/plugins/cookiex/cookiex.c +++ b/plugins/cookiex/cookiex.c @@ -18,7 +18,7 @@ void execute(int client,const char* method,dictionary rq) dictionary d = dict(); dput(d,"test",c); dput(d,"test1","This is another cookie"); - set_cookie(client,"text/html; charset=utf-8",d); + set_cookie(client,"text/html; charset=utf-8",d,__plugin__.name); LOG("%s",c); __t(client,"

Set the cookie

"); diff --git a/plugins/dbhelper.h b/plugins/dbhelper.h index c1a80b2..9b13cd8 100644 --- a/plugins/dbhelper.h +++ b/plugins/dbhelper.h @@ -1,3 +1,5 @@ +#ifndef DB_HELPER +#define DB_HELPER #include #include "utils.h" @@ -31,4 +33,5 @@ char* __name_value_list(const dbfield); char* value_of(const dbfield,const char*); void add_field(dbfield*,const char*, const char*); void add_record(dbrecord*,dbfield); -void dbclose(sqlite3*); \ No newline at end of file +void dbclose(sqlite3*); +#endif \ No newline at end of file diff --git a/plugins/handle.c b/plugins/handle.c new file mode 100644 index 0000000..0be636b --- /dev/null +++ b/plugins/handle.c @@ -0,0 +1,217 @@ +#include "handle.h" + + +void set_status(int client,int code,const char* msg) +{ + response(client, __s("HTTP/1.0 %d %s", code, msg)); + response(client, __s("Server: %s ", SERVER_NAME)); +} +void redirect(int client,const char*path) +{ + __t(client,"",path); +} + +void html(int client) +{ + ctype(client,"text/html; charset=utf-8"); +} +void text(int client) +{ + ctype(client,"text/plain; charset=utf-8"); +} +void json(int client) +{ + ctype(client,"application/json"); +} +void textstream(int client) +{ + ctype(client, "text/event-stream"); +} +void octstream(int client, char* name) +{ + set_status(client,200,"OK"); + __t(client,"Content-Type: application/octet-stream"); + __t(client,"Content-Disposition: attachment; filename=\"%s\"", name); + response(client,""); + //Content-Disposition: attachment; filename="fname.ext" +} +void jpeg(int client) +{ + ctype(client,"image/jpeg"); +} +void ctype(int client, const char* type) +{ + set_status(client,200,"OK"); + __t(client,"Content-Type: %s",type); + response(client,""); +} + +int response(int client, const char* data) +{ + char buf[BUFFLEN+3]; + strcpy(buf, data); + int nbytes; + int size = strlen(data); + buf[size] = '\r'; + buf[size+1] = '\n'; + buf[size+2] = '\0'; + nbytes = send(client, buf, strlen(buf), 0); + return (nbytes ==-1?0:1); +} +int __ti(int client,int data) +{ + char str[15]; + sprintf(str, "%d", data); + return response(client,str); +} + +int __t(int client, const char* fstring,...) +{ + int nbytes; + int dlen; + int sent = 0; + int buflen = 0; + va_list arguments; + char * data; + char* chunk; + va_start( arguments, fstring); + dlen = vsnprintf(0,0,fstring,arguments) + 1; + va_end(arguments); + if ((data = (char*)malloc(dlen*sizeof(char))) != 0) + { + va_start(arguments, fstring); + vsnprintf(data, dlen, fstring, arguments); + va_end(arguments); + + if(dlen < BUFFLEN) + return response(client,data); + else + { + while(sent < dlen - 1) + { + if(dlen - sent > BUFFLEN) + buflen = BUFFLEN; + else + buflen = dlen - sent - 1; + //LOG("BUFFLEN %d\n",buflen); + chunk = (char*) malloc((buflen)*sizeof(char)); + memcpy(chunk,data+sent,buflen); + //chunk[buflen-1] = '\0'; + //response(client,chunk); + sent += buflen; + nbytes = send(client, chunk, buflen, 0); + free(chunk); + if(nbytes == -1) return 0; + } + chunk = "\r\n"; + send(client, chunk, strlen(chunk), 0); + } + free(data); + } + return 1; + // +} +int __b(int client, const unsigned char* data, int size) +{ + char buf[BUFFLEN]; + int sent = 0; + int buflen = 0; + int nbytes; + if(size <= BUFFLEN) + { + nbytes = send(client,data,size,0); + return (nbytes==-1?0:1); + } + else + { + while(sent < size) + { + if(size - sent > BUFFLEN) + buflen = BUFFLEN; + else + buflen = size - sent; + memcpy(buf,data+sent,buflen); + nbytes = send(client,buf,buflen,0); + sent += buflen; + if(nbytes == -1) return 0; + } + } + return 1; +} +int __fb(int client, const char* file) +{ + printf("Open file %s\n",file ); + unsigned char buffer[BUFFLEN]; + FILE *ptr; + ptr = fopen(file,"rb"); + if(!ptr) + { + LOG("Cannot read : %s\n", file); + return 0; + } + size_t size; + while(!feof(ptr)) + { + size = fread(buffer,1,BUFFLEN,ptr); + if(!__b(client,buffer,size)) return 0; + } + fclose(ptr); + return 1; +} +int __f(int client, const char* file) +{ + unsigned char buf[BUFFLEN]; + FILE *ptr; + int nbytes; + ptr = fopen(file,"r"); + if(!ptr) + { + LOG("Cannot read : %s\n", file); + return 0; + } + ; + while(fgets(buf, sizeof(buf), ptr) != NULL) + { + nbytes = send(client, buf, strlen(buf), 0); + if(nbytes == -1) return 0; + //LOG("READ : %s\n", buf); + //fgets(buf, sizeof(buf), ptr); + } + fclose(ptr); + return 1; +} + +int upload(const char* tmp, const char* path) +{ + return !rename(tmp, path); +} +// __plugin__.name +void set_cookie(int client,const char* type, dictionary dic, const char* name) +{ + set_status(client,200,"OK"); + __t(client,"Content-Type: %s",type); + association assoc; + for_each_assoc(assoc,dic){ + __t(client,"Set-Cookie: %s=%s; Path=/%s",assoc->key, (char*)assoc->value, name); + } + response(client,""); +} +void clear_cookie(int client, dictionary dic) +{ + set_status(client,200,"OK"); + __t(client,"Content-Type: text/html; charset=utf-8"); + association assoc; + for_each_assoc(assoc,dic){ + __t(client,"Set-Cookie: %s=%s;expires=",assoc->key, (char*)assoc->value, server_time()); + } + response(client,""); +} +void unknow(int client) +{ + html(client); + __t(client,"404 API not found"); +} +int ws_enable(dictionary dic) +{ + return (dic != NULL && R_INT(dic,"__web_socket__") == 1); +} \ No newline at end of file diff --git a/plugins/handle.h b/plugins/handle.h new file mode 100644 index 0000000..4134b42 --- /dev/null +++ b/plugins/handle.h @@ -0,0 +1,48 @@ +#ifndef HANDLE_H +#define HANDLE_H +#include +#include +#include +#ifdef USE_DB +#include "dbhelper.h" +#endif +#include "dictionary.h" +#include "list.h" +#include "ini.h" +#include "ws.h" + +#define SERVER_NAME "antd" +#define IS_POST(method) (strcmp(method,"POST")== 0) +#define IS_GET(method) (strcmp(method,"GET")== 0) +#define R_STR(d,k) ((char*)dvalue(d,k)) +#define R_INT(d,k) (atoi(dvalue(d,k))) +#define R_FLOAT(d,k) ((double)atof(dvalue(d,k))) +#define R_PTR(d,k) (dvalue(d,k)) +#define __RESULT__ "{\"result\":%d,\"msg\":\"%s\"}" + + + + +int response(int, const char*); +void ctype(int,const char*); +void redirect(int,const char*); +void html(int); +void text(int); +void json(int); +void jpeg(int); +void octstream(int, char*); +void textstream(int); +int __ti(int,int); +int __t(int, const char*,...); +int __b(int, const unsigned char*, int); +int __f(int, const char*); +int __fb(int, const char*); +int upload(const char*, const char*); + +void set_cookie(int, const char*,dictionary,const char*); +void set_status(int,int,const char*); +void clear_cookie(int, dictionary); +/*Default function for plugin*/ +void unknow(int); +int ws_enable(dictionary); +#endif diff --git a/plugins/plugin.c b/plugins/plugin.c index 54c96c2..01cc402 100644 --- a/plugins/plugin.c +++ b/plugins/plugin.c @@ -30,185 +30,6 @@ sqldb getdb() return getdb(__plugin__.name); } #endif -void set_status(int client,int code,const char* msg) -{ - response(client, __s("HTTP/1.0 %d %s", code, msg)); - response(client, __s("Server: %s ", SERVER_NAME)); -} -void redirect(int client,const char*path) -{ - __t(client,"",path); -} - -void html(int client) -{ - header(client,"text/html; charset=utf-8"); -} -void text(int client) -{ - header(client,"text/plain; charset=utf-8"); -} -void json(int client) -{ - header(client,"application/json"); -} -void textstream(int client) -{ - header(client, "text/event-stream"); -} -void octstream(int client, char* name) -{ - set_status(client,200,"OK"); - __t(client,"Content-Type: application/octet-stream"); - __t(client,"Content-Disposition: attachment; filename=\"%s\"", name); - response(client,""); - //Content-Disposition: attachment; filename="fname.ext" -} -void jpeg(int client) -{ - header(client,"image/jpeg"); -} -void header(int client, const char* type) -{ - set_status(client,200,"OK"); - __t(client,"Content-Type: %s",type); - response(client,""); -} - -int response(int client, const char* data) -{ - char buf[BUFFLEN+3]; - strcpy(buf, data); - int nbytes; - int size = strlen(data); - buf[size] = '\r'; - buf[size+1] = '\n'; - buf[size+2] = '\0'; - nbytes = send(client, buf, strlen(buf), 0); - return (nbytes ==-1?0:1); -} -int __ti(int client,int data) -{ - char str[15]; - sprintf(str, "%d", data); - return response(client,str); -} - -int __t(int client, const char* fstring,...) -{ - int nbytes; - int dlen; - int sent = 0; - int buflen = 0; - va_list arguments; - char * data; - char* chunk; - va_start( arguments, fstring); - dlen = vsnprintf(0,0,fstring,arguments) + 1; - va_end(arguments); - if ((data = (char*)malloc(dlen*sizeof(char))) != 0) - { - va_start(arguments, fstring); - vsnprintf(data, dlen, fstring, arguments); - va_end(arguments); - - if(dlen < BUFFLEN) - return response(client,data); - else - { - while(sent < dlen - 1) - { - if(dlen - sent > BUFFLEN) - buflen = BUFFLEN; - else - buflen = dlen - sent - 1; - //LOG("BUFFLEN %d\n",buflen); - chunk = (char*) malloc((buflen)*sizeof(char)); - memcpy(chunk,data+sent,buflen); - //chunk[buflen-1] = '\0'; - //response(client,chunk); - sent += buflen; - nbytes = send(client, chunk, buflen, 0); - free(chunk); - if(nbytes == -1) return 0; - } - chunk = "\r\n"; - send(client, chunk, strlen(chunk), 0); - } - free(data); - } - return 1; - // -} -int __b(int client, const unsigned char* data, int size) -{ - char buf[BUFFLEN]; - int sent = 0; - int buflen = 0; - int nbytes; - if(size <= BUFFLEN) - { - nbytes = send(client,data,size,0); - return (nbytes==-1?0:1); - } - else - { - while(sent < size) - { - if(size - sent > BUFFLEN) - buflen = BUFFLEN; - else - buflen = size - sent; - memcpy(buf,data+sent,buflen); - nbytes = send(client,buf,buflen,0); - sent += buflen; - if(nbytes == -1) return 0; - } - } - return 1; -} -int __fb(int client, const char* file) -{ - printf("Open file %s\n",file ); - unsigned char buffer[BUFFLEN]; - FILE *ptr; - ptr = fopen(file,"rb"); - if(!ptr) - { - LOG("Cannot read : %s\n", file); - return 0; - } - size_t size; - while(!feof(ptr)) - { - size = fread(buffer,1,BUFFLEN,ptr); - if(!__b(client,buffer,size)) return 0; - } - fclose(ptr); - return 1; -} -int __f(int client, const char* file) -{ - unsigned char buf[BUFFLEN]; - FILE *ptr; - int nbytes; - ptr = fopen(file,"r"); - if(!ptr) - { - LOG("Cannot read : %s\n", file); - return 0; - } - ; - while(fgets(buf, sizeof(buf), ptr) != NULL) - { - nbytes = send(client, buf, strlen(buf), 0); - if(nbytes == -1) return 0; - //LOG("READ : %s\n", buf); - //fgets(buf, sizeof(buf), ptr); - } - fclose(ptr); - return 1; -} char* route(const char* repath) { @@ -225,6 +46,7 @@ char* route(const char* repath) } return path; } + char* htdocs(const char* repath) { if(repath != NULL) @@ -232,30 +54,7 @@ char* htdocs(const char* repath) else return __s("%s",__plugin__.htdocs); } -int upload(const char* tmp, const char* path) -{ - return !rename(tmp, path); -} -void set_cookie(int client,const char* type, dictionary dic) -{ - set_status(client,200,"OK"); - __t(client,"Content-Type: %s",type); - association assoc; - for_each_assoc(assoc,dic){ - __t(client,"Set-Cookie: %s=%s; Path=/%s",assoc->key, (char*)assoc->value, __plugin__.name); - } - response(client,""); -} -void clear_cookie(int client, dictionary dic) -{ - set_status(client,200,"OK"); - __t(client,"Content-Type: text/html; charset=utf-8"); - association assoc; - for_each_assoc(assoc,dic){ - __t(client,"Set-Cookie: %s=%s;expires=",assoc->key, (char*)assoc->value, server_time()); - } - response(client,""); -} + char* config_dir() { struct stat st; @@ -263,13 +62,4 @@ char* config_dir() if (stat(path, &st) == -1) mkdir(path, 0755); return path; -} -void unknow(int client) -{ - html(client); - __t(client,"404 API not found"); -} -int ws_enable(dictionary dic) -{ - return (dic != NULL && R_INT(dic,"__web_socket__") == 1); } \ No newline at end of file diff --git a/plugins/plugin.h b/plugins/plugin.h index cf59d87..28aedeb 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -1,29 +1,17 @@ -#include -#include -#include +#ifndef PLUGIN_H +#define PLUGIN_H + #ifdef USE_DB #include "dbhelper.h" #endif -#include "dictionary.h" -#include "list.h" -#include "ini.h" -#include "ws.h" - -#define SERVER_NAME "antd" -#define IS_POST(method) (strcmp(method,"POST")== 0) -#define IS_GET(method) (strcmp(method,"GET")== 0) -#define R_STR(d,k) ((char*)dvalue(d,k)) -#define R_INT(d,k) (atoi(dvalue(d,k))) -#define R_FLOAT(d,k) ((double)atof(dvalue(d,k))) -#define R_PTR(d,k) (dvalue(d,k)) -#define __RESULT__ "{\"result\":%d,\"msg\":\"%s\"}" +#include "handle.h" typedef struct { char *name; char *dbpath; char * htdocs; char*pdir; - int *sport; + int sport; } plugin_header; @@ -35,32 +23,16 @@ typedef sqlite3* sqldb; extern plugin_header __plugin__; extern call __init__; -int response(int, const char*); -void header(int,const char*); -void redirect(int,const char*); -void html(int); -void text(int); -void json(int); -void jpeg(int); -void octstream(int, char*); -void textstream(int); -int __ti(int,int); -int __t(int, const char*,...); -int __b(int, const unsigned char*, int); -int __f(int, const char*); -int __fb(int, const char*); -int upload(const char*, const char*); -char* config_dir(); -char* route(const char*); -char* htdocs(const char*); + #ifdef USE_DB sqldb getdb(); sqldb __getdb(char *name); #endif -void set_cookie(int, const char*,dictionary); -void set_status(int,int,const char*); -void clear_cookie(int, dictionary); + +char* route(const char*); +char* htdocs(const char*); +char* config_dir(); /*Default function for plugin*/ void handler(int, const char*,const char*,dictionary); -void unknow(int); -int ws_enable(dictionary); + +#endif