fix memory leak

This commit is contained in:
Xuan Sang LE 2018-03-02 19:04:00 +01:00
parent 3029555f59
commit 6bc76386f6
13 changed files with 231 additions and 58 deletions

View File

@ -130,7 +130,24 @@ void accept_request(void* client)
}
end:
if(oldurl) free(oldurl);
if(rq) free(rq);
if(rq)
{
dictionary subdict;
subdict = (dictionary)dvalue(rq, "__xheader__");
if(subdict)
{
freedict(subdict);
dput(rq, "__xheader__", NULL);
}
subdict = (dictionary)dvalue(rq, "cookie");
if(subdict)
{
freedict(subdict);
dput(rq, "cookie", NULL);
}
freedict(rq);
}
antd_close(client);
}
@ -155,7 +172,12 @@ int rule_check(const char*k, const char* v, const char* host, const char* _url,
else
target = host;
if(!ret) return 0;
if(!ret)
{
free(url);
free(query);
return 0;
}
tmp = (char*) v;
char * search = "<([a-zA-Z0-9]+)>";
//printf("match again %s\n",tmp);
@ -519,9 +541,10 @@ dictionary decode_request(void* client,const char* method, char* url)
}
//if(line) free(line);
query = apply_rules(host, url);
if(host) free(host);
if(strcmp(method,"GET") == 0)
{
if(host) free(host);
{
if(ctype) free(ctype);
if(query)
{
LOG("Query: %s\n", query);
@ -536,15 +559,21 @@ dictionary decode_request(void* client,const char* method, char* url)
// plugin should handle this ugraded connection
// not the server
if(!request) request = dict();
dput(request,"__web_socket__","1");
dput(request,"__web_socket__",strdup("1"));
}
}
else
{
if(query)
free(query);
if(ws_key)
free(ws_key);
if(ctype == NULL || clen == -1)
{
LOG("Bad request\n");
if(ctype) free(ctype);
if(cookie) freedict(cookie);
free(xheader);
return NULL;
}
LOG("ContentType %s\n", ctype);
@ -575,8 +604,8 @@ dictionary decode_request(void* client,const char* method, char* url)
//if(cookie->key == NULL) {free(cookie);cookie= NULL;}
if(!request)
request = dict();
dput(request,"cookie",cookie);
if(cookie)
dput(request,"cookie",cookie);
dput(request,"__xheader__",xheader);
return request;
}
@ -635,10 +664,11 @@ dictionary decode_cookie(const char* line)
{
char *token,*token1;
char *cpstr = strdup(line);
char *orgcpy = cpstr;
trim(cpstr,' ');
trim(cpstr,'\n');
trim(cpstr,'\r');
//printf("FUCKIT %s\n",cpstr );
dictionary dic = NULL;
while((token = strsep(&cpstr,";")))
{
@ -648,13 +678,12 @@ dictionary decode_cookie(const char* line)
{
if(dic == NULL)
dic = dict();
//LOG("Found cookie : %s = %s\n",token1,token);
dput(dic,token1,strdup(token));
}
}
//}
free(orgcpy);
return dic;
//free(cpstr);
}
/**
* Decode the multi-part form data from the POST request
@ -670,7 +699,9 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
char * boundary;
char * boundend;
char * line;
char * orgline;
char * str_copy = strdup(ctype);
char* orgcpy = str_copy;
char* token;
char* keytoken ;
char* valtoken ;
@ -689,13 +720,29 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
trim(boundary,' ');
boundend = __s("%s--",boundary);
//find first boundary
while((line = read_line(client))&&strstr(line,boundary) <= 0);
while((line = read_line(client))&&strstr(line,boundary) <= 0)
{
if(line) free(line);
}
// loop through each part separated by the boundary
while(line && strstr(line,boundary) > 0){
free(line);
// search for content disposition:
while((line = read_line(client)) &&
strstr(line,"Content-Disposition:") <= 0);
if(strstr(line,"Content-Disposition:") <= 0) return NULL;
strstr(line,"Content-Disposition:") <= 0)
{
free(line);
line = NULL;
}
if(!line || strstr(line,"Content-Disposition:") <= 0)
{
if(line)
free(line);
free(orgcpy);
free(boundend);
return NULL;
}
orgline = line;
// extract parameters from header
part_name = NULL;
part_file = NULL;
@ -714,19 +761,24 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
trim(valtoken,'\"');
if(strcmp(keytoken,"name") == 0)
{
part_name = valtoken;
part_name = strdup(valtoken);
} else if(strcmp(keytoken,"filename") == 0)
{
part_file = valtoken;
part_file = strdup(valtoken);
}
}
}
}
free(orgline);
// 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);
while((line = read_line(client)) && strcmp(line,"\r\n") != 0)
{
free(line);
}
if(line) free(line);
if(part_file == NULL)
{
/**
@ -740,7 +792,10 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
trim(line,' ');
dput(dic,part_name,line);
// find the next boundary
while((line = read_line(client)) && strstr(line,boundary) <= 0);
while((line = read_line(client)) && strstr(line,boundary) <= 0)
{
free(line);
}
}
else
{
@ -762,11 +817,14 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
line = buf;
field = __s("%s.file",part_name);
dput(dic,field,part_file);
dput(dic,field, strdup(part_file));
free(field);
field = __s("%s.tmp",part_name);
dput(dic,field,strdup(file_path));
free(field);
field = __s("%s.size",part_name);
dput(dic,field,__s("%d",totalsize));
free(field);
field = __s("%s.ext",part_name);
dput(dic,field,ext(part_file));
free(field);
@ -777,7 +835,9 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
LOG("Cannot wirte file to :%s\n", file_path );
}
free(file_path);
free(part_file);
}
free(part_name);
}
//printf("[Lines]:%s\n",line);
// check if end of request
@ -786,9 +846,10 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
LOG("End request %s\n", boundend);
break;
}
}
}
free(boundend);
}
free(str_copy);
free(orgcpy);
return dic;
}
/**
@ -800,10 +861,11 @@ dictionary decode_multi_part_request(void* client,const char* ctype)
dictionary decode_url_request(const char* query)
{
if(query == NULL) return NULL;
char* str_copy = strdup(query);
//str_copy = ;
char* token;
if(strlen(query) == 0) return NULL;
char* str_copy = strdup(query);
char* org_copy = str_copy;
dictionary dic = dict();
while ((token = strsep(&str_copy, "&")))
{
@ -819,7 +881,7 @@ dictionary decode_url_request(const char* query)
}
}
}
free(str_copy);
free(org_copy);
return dic;
}
/**
@ -859,6 +921,7 @@ int execute_plugin(void* client, const char *path, const char *method, dictionar
struct plugin_entry *plugin ;
int plen = strlen(path);
char * rpath = (char*) malloc((plen+1)*sizeof(char));
char* orgs = rpath;
char *error;
memcpy(rpath,path+1,plen);
rpath[plen] = '\0';
@ -900,7 +963,7 @@ int execute_plugin(void* client, const char *path, const char *method, dictionar
//dictionary dic = decode_request(client,method,query_string);
(*fn)(client,method,pfunc,dic);
//free(dic);
free(rpath);
free(orgs);
return 1;
}

24
httpd.c
View File

@ -4,9 +4,10 @@
#include "libs/ini.h"
#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
int server_sock = -1;
#ifdef USE_OPENSSL
static int ssl_session_ctx_id = 1;
SSL_CTX *ctx;
void init_openssl()
{
SSL_load_error_strings();
@ -98,12 +99,12 @@ static int config_handler(void* conf, const char* section, const char* name,
#endif
else if (strcmp(section, "RULES") == 0)
{
list_put_s(&pconfig->rules, strdup(name));
list_put_s(&pconfig->rules, strdup(value));
list_put_s(&pconfig->rules, name);
list_put_s(&pconfig->rules, value);
}
else if (strcmp(section, "FILEHANDLER") == 0)
{
dput( pconfig->handlers, strdup(name),strdup(value));
dput( pconfig->handlers, name ,strdup(value));
}
else if(strcmp(section,"AUTOSTART")==0){
// The server section must be added before the autostart section
@ -162,9 +163,13 @@ void load_config(const char* file)
init_file_system();
}
void stop_serve(int dummy) {
list_free(&server_config.rules);
free(server_config.handlers);
list_free(&(server_config.rules));
freedict(server_config.handlers);
unload_all_plugin();
#ifdef USE_OPENSSL
SSL_CTX_free(ctx);
#endif
close(server_sock);
}
int main(int argc, char* argv[])
{
@ -173,8 +178,6 @@ int main(int argc, char* argv[])
load_config(CONFIG);
else
load_config(argv[1]);
int server_sock = -1;
unsigned port = server_config.port;
int client_sock = -1;
struct sockaddr_in client_name;
@ -188,7 +191,6 @@ int main(int argc, char* argv[])
signal(SIGINT, stop_serve);
#ifdef USE_OPENSSL
SSL_CTX *ctx;
if( server_config.usessl == 1 )
{
init_openssl();
@ -236,9 +238,7 @@ int main(int argc, char* argv[])
}
//accept_request(&client);
}
#ifdef USE_OPENSSL
SSL_CTX_free(ctx);
#endif
close(server_sock);
return(0);

View File

@ -81,7 +81,10 @@ void add_record(dbrecord* r,dbfield f)
new_r->idx = 1;
new_r->next = NULL;
if((*r)->idx == 0)
{
freerecord(&(*r));
*r = new_r;
}
else
{
dbrecord* temp;
@ -157,8 +160,8 @@ dbrecord dbselect(sqlite3* db, const char* table,const char* fstring,...)
dbfield fields = __field();
for(int col = 0; col < cols; col++)
{
char *value = (char*)sqlite3_column_text(statement, col);
char *name = (char*)sqlite3_column_name(statement, col);
const char *value = sqlite3_column_text(statement, col);
const char *name = sqlite3_column_name(statement, col);
add_field(&fields,name,(value!=0)?value:"");
}
add_record(&records,fields);
@ -180,8 +183,12 @@ int hastable(sqlite3* db,const char* table)
dbrecord rc = dbselect(db,"sqlite_master","type='table' and name='%s'", table);
//free(prefix);
if(!rc) return 0;
if(!rc->fields) return 0;
free(rc);
if(!rc->fields)
{
freerecord(&rc);
return 0;
}
freerecord(&rc);
return 1;
}
int dbupdate(sqlite3* db,const char* table,const dbfield field,const char* fstring,...)
@ -228,4 +235,26 @@ int dbdelete(sqlite3* db,const char* table,const char* fstring,...)
free(cond);
free(sql);
return ret;
}
}
void freerecord(dbrecord * r)
{
dbrecord curr;
while ((curr = (*r)) != NULL) {
(*r) = (*r)->next;
if(curr->fields)
freefield(&(curr->fields));
free (curr);
}
}
void freefield(dbfield *f)
{
dbfield curr;
while( (curr = (*f)) != NULL )
{
(*f) = (*f)->next;
if(curr->name) free(curr->name);
if(curr->value) free(curr->value);
free(curr);
}
}

View File

@ -34,4 +34,6 @@ char* value_of(const dbfield,const char*);
void add_field(dbfield*,const char*, const char*);
void add_record(dbrecord*,dbfield);
void dbclose(sqlite3*);
void freerecord(dbrecord *);
void freefield(dbfield *);
#endif

View File

@ -93,5 +93,29 @@ void* dvalue(dictionary dic, const char* key)
return as->value;
}
void freedict(dictionary dic){free(dic);}
void free_association(association * asoc)
{
while( (*asoc) != NULL )
{
association a = *asoc;
(* asoc) = (*asoc) ->next;
if(a->key)
{
free(a->key);
if(a->value) free(a->value);
}
free(a);
}
}
void freedict(dictionary dic){
for(int i = 0; i < HASHSIZE; i++)
free_association(&(dic[i]));
free(dic);
}

View File

@ -9,8 +9,12 @@ int usessl()
void set_status(void* client,int code,const char* msg)
{
response(client, __s("HTTP/1.1 %d %s", code, msg));
response(client, __s("Server: %s ", SERVER_NAME));
char *s = __s("HTTP/1.1 %d %s", code, msg);
response(client, s);
free(s);
s = __s("Server: %s ", SERVER_NAME);
response(client, s);
free(s);
}
void redirect(void* client,const char*path)
{
@ -67,7 +71,7 @@ int response(void* client, const char* data)
}
int antd_send(const void *src, const void* data, int len)
{
if(!src) return -1;
if(!src || !data) return -1;
antd_client_t * source = (antd_client_t *) src;
#ifdef USE_OPENSSL
if(usessl())
@ -146,7 +150,11 @@ int __t(void* client, const char* fstring,...)
va_end(arguments);
if(dlen < BUFFLEN)
return response(client,data);
{
int ret = response(client,data);
free(data);
return ret;
}
else
{
while(sent < dlen - 1)
@ -163,7 +171,12 @@ int __t(void* client, const char* fstring,...)
sent += buflen;
nbytes = antd_send(client, chunk, buflen);
free(chunk);
if(nbytes == -1) return 0;
if(nbytes == -1)
{
//free(data);
//return 0;
break;
}
}
chunk = "\r\n";
antd_send(client, chunk, strlen(chunk));

View File

@ -34,6 +34,7 @@ void list_put(list* l, item it)
{
if(*l == NULL || (*l)->type == RPC_TYPE_NIL)
{
free(*l);
*l = it;
return ;
}
@ -167,6 +168,7 @@ list split(const char* str, const char* delim)
{
if(str == NULL || delim == NULL) return NULL;
char* str_cpy = strdup(str);
char* org_str = str_cpy;
char* token;
list l = list_init();
while((token = strsep(&str_cpy,delim)))
@ -176,7 +178,7 @@ list split(const char* str, const char* delim)
list_put_special(&l,token);
}
}
free(str_cpy);
free(org_str);
if(l->type== RPC_TYPE_NIL)
return NULL;
return l;
@ -227,9 +229,15 @@ void list_free(list *l)
{
item curr;
while ((curr = (*l)) != NULL) {
(*l) = (*l)->next;
(*l) = (*l)->next;
if(curr->type == RPC_TYPE_ARRAY)
list_free(&curr->value.array);
else if(curr->type == RPC_TYPE_STRING)
free(curr->value.s);
else if(curr->type == RPC_TYPE_DATE)
free(curr->value.date);
else if(curr->type == RPC_TYPE_BASE64)
free(curr->value.b64);
free (curr);
}
}

View File

@ -73,4 +73,13 @@ char* config_dir()
if (stat(path, &st) == -1)
mkdir(path, 0755);
return path;
}
void __release()
{
printf("Releasing plugin\n");
if(__plugin__.name) free(__plugin__.name);
if(__plugin__.dbpath) free(__plugin__.dbpath);
if(__plugin__.htdocs) free(__plugin__.htdocs);
if(__plugin__.pdir) free(__plugin__.pdir);
}

View File

@ -37,5 +37,5 @@ char* htdocs(const char*);
char* config_dir();
/*Default function for plugin*/
void handler(void*, const char*,const char*,dictionary);
void __release();
#endif

View File

@ -143,13 +143,15 @@ char* ext(const char* file)
char* token,*ltoken = "";
if(file == NULL) return NULL;
char* str_cpy = strdup(file);
char* str_org = str_cpy;
if(strstr(str_cpy,".")<= 0) return "";
if(*file == '.')
trim(str_cpy,'.');
while((token = strsep(&str_cpy,".")) && strlen(token)>0) {ltoken = token;}
free(str_cpy);
return ltoken;
char* ext = strdup(ltoken);
free(str_org);
return ext;
}
/*get mime file info from extension*/
@ -182,6 +184,7 @@ char* mime(const char* file)
{
char * ex = ext(file);
mime_t m = mime_from_ext(ex);
free(ex);
return m.type;
}
@ -189,6 +192,7 @@ int is_bin(const char* file)
{
char * ex = ext(file);
mime_t m = mime_from_ext(ex);
free(ex);
return m.bin;
}

View File

@ -15,7 +15,7 @@ static void ws_gen_mask_key(ws_msg_header_t * header)
ws_msg_header_t * ws_read_header(void* client)
{
uint8_t byte;
uint8_t byte = 0;
uint8_t bytes[8];
ws_msg_header_t* header = (ws_msg_header_t*) malloc(sizeof(*header));

View File

@ -89,12 +89,14 @@ void handler(void* cl, const char* m, const char* rqp, dictionary rq)
{
LOG("%s\n","Data is not mask");
write(fdm, "exit\n", 5);
free(h);
return;
}
if(h->opcode == WS_CLOSE)
{
LOG("%s\n","Websocket: connection closed");
write(fdm, "exit\n", 5);
free(h);
return;
}
else if(h->opcode == WS_TEXT)
@ -102,6 +104,7 @@ void handler(void* cl, const char* m, const char* rqp, dictionary rq)
int l;
char * tok = NULL;
char* tok1 = NULL;
char* orgs = NULL;
while((l = ws_read_data(cl,h,sizeof(buff),buff)) > 0)
{
char c = buff[0];
@ -114,6 +117,7 @@ void handler(void* cl, const char* m, const char* rqp, dictionary rq)
case 's': // terminal resize event
buff[l] = '\0';
tok = strdup(buff+1);
orgs = tok;
tok1 = strsep(&tok,":");
if(tok != NULL && tok1 != NULL)
{
@ -136,6 +140,8 @@ void handler(void* cl, const char* m, const char* rqp, dictionary rq)
if (ioctl(fdm, TIOCSWINSZ, (char *) &win) != 0)
printf("Cannot set winsize\n");
free(orgs);
}
break;

View File

@ -60,6 +60,8 @@ void * plugin_from_file(char* name)
if (!lib_handle)
{
LOG("Cannot load plugin '%s' : '%s'\n",name,dlerror());
if(path)
free(path);
return NULL;
}
// set database path
@ -87,7 +89,16 @@ void unload_plugin(struct plugin_entry* np)
{
// execute it
(*fn)();
}
}
fn = (void(*)()) dlsym(np->handle, "__release");
if ((error = dlerror()) != NULL)
{
LOG("Cant not release plugin %s : %s \n", np->pname,error);
}
if(fn)
{
(*fn)();
}
dlclose(np->handle);
//free((void *) np->handle);
free((void *) np->pname);
@ -124,11 +135,15 @@ void unload_all_plugin()
LOG("Unload all plugins\n");
for(int i=0;i<HASHSIZE;i++)
{
struct plugin_entry *np;
for (np = plugin_table[i]; np != NULL; np = np->next)
{
unload_plugin(np);
}
struct plugin_entry **np, *curr;
np = &plugin_table[i];
while((curr = *np) != NULL)
{
(*np) = (*np)->next;
unload_plugin(curr);
free(curr);
}
plugin_table[i] = NULL;
}
exit(0);