fixed memory leaks, added cleanup code, added valgrind scripts to test binaries
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include <gwenhywfar/buffer.h>
|
||||
#include <gwenhywfar/text.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/directory.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
@@ -54,11 +55,15 @@ static GWEN_BUFFER *_getConfigFilePath(const AQH_SERVICE *sv, const char *fileNa
|
||||
static GWEN_BUFFER *_getModuleFilePath(const AQH_SERVICE *sv, const char *modName);
|
||||
static GWEN_BUFFER *_getUserFilePath(const AQH_SERVICE *sv, const char *userAlias);
|
||||
static GWEN_BUFFER *_getSessionFilePath(const AQH_SERVICE *sv, const char *sessionUid);
|
||||
static GWEN_BUFFER *_getSessionFolder(const AQH_SERVICE *sv);
|
||||
static int _checkUser(const AQH_USER *user, int ignoreMissingId);
|
||||
static int _checkSession(const AQH_SESSION *session);
|
||||
static int _checkModule(const AQH_MODULE *m, int ignoreMissingId);
|
||||
static int _checkRoleList(const AQH_ROLE_LIST *roleList, int ignoreMissingId);
|
||||
static int _writeDbFile(const char *fname, GWEN_DB_NODE *db);
|
||||
static GWEN_STRINGLIST *_getConfFileList(const char *folder, const char *mask);
|
||||
static AQH_SESSION_LIST *_readAllSessionsIntoList(const AQH_SERVICE *sv);
|
||||
static AQH_SESSION *_readSessionFromFile(const char *filename);
|
||||
|
||||
|
||||
|
||||
@@ -278,6 +283,141 @@ AQH_SESSION *AQH_HttpService_GetSession(AQH_SERVICE *sv, const char *sessionUid)
|
||||
|
||||
|
||||
|
||||
int AQH_HttpService_LockSessions(AQH_SERVICE *sv)
|
||||
{
|
||||
AQH_HTTP_SERVICE *xsv;
|
||||
int rv;
|
||||
|
||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
||||
if (xsv==NULL) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Not a AQH_HttpService object");
|
||||
return GWEN_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
rv=GWEN_Mutex_Lock(xsv->sessionMutex);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error obtaining lock on session mutex");
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AQH_HttpService_UnlockSessions(AQH_SERVICE *sv)
|
||||
{
|
||||
AQH_HTTP_SERVICE *xsv;
|
||||
int rv;
|
||||
|
||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
||||
if (xsv==NULL) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Not a AQH_HttpService object");
|
||||
return GWEN_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
rv=GWEN_Mutex_Unlock(xsv->sessionMutex);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error releasing lock on session mutex");
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AQH_HttpService_CleanupSessions(AQH_SERVICE *sv, int maxAgeInSecs)
|
||||
{
|
||||
time_t tNow;
|
||||
AQH_SESSION_LIST *sessionList;
|
||||
int rv;
|
||||
|
||||
rv=AQH_HttpService_LockSessions(sv);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "Error locking sessions (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
tNow=time(NULL);
|
||||
|
||||
sessionList=AQH_Service_GetSessionList(sv);
|
||||
if (sessionList) {
|
||||
AQH_SESSION *session;
|
||||
|
||||
session=AQH_Session_List_First(sessionList);
|
||||
while(session) {
|
||||
AQH_SESSION *next;
|
||||
const GWEN_TIMESTAMP *ts;
|
||||
|
||||
next=AQH_Session_List_Next(session);
|
||||
|
||||
ts=AQH_Session_GetTimestampLastAccess(session);
|
||||
if (ts==NULL)
|
||||
ts=AQH_Session_GetTimestampCreation(session);
|
||||
if (ts) {
|
||||
time_t diff;
|
||||
|
||||
diff=tNow-GWEN_Timestamp_toTimeT(ts);
|
||||
if (((int)diff)>maxAgeInSecs) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "Session \"%s\" expired (%d secs)", AQH_Session_GetUid(session), (int) diff);
|
||||
rv=AQH_HttpService_DelSession(sv, session); /* frees session!! */
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
session=next;
|
||||
}
|
||||
}
|
||||
|
||||
rv=AQH_HttpService_UnlockSessions(sv);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "Error unlocking sessions (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void AQH_HttpService_LoadAllSessions(AQH_SERVICE *sv)
|
||||
{
|
||||
AQH_SESSION_LIST *sessionList;
|
||||
|
||||
sessionList=_readAllSessionsIntoList(sv);
|
||||
if (sessionList) {
|
||||
AQH_SESSION *session;
|
||||
|
||||
while( (session=AQH_Session_List_First(sessionList)) ) {
|
||||
const char *sessionUid;
|
||||
const char *userAlias;
|
||||
|
||||
AQH_Session_List_Del(session);
|
||||
sessionUid=AQH_Session_GetUid(session);
|
||||
userAlias=AQH_Session_GetUserAlias(session);
|
||||
if (userAlias && *userAlias) {
|
||||
AQH_USER *user;
|
||||
|
||||
user=AQH_HttpService_GetUser(sv, userAlias);
|
||||
if (user==NULL) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "User \"%s\" for session \"%s\" not available", userAlias, sessionUid);
|
||||
AQH_Session_free(session);
|
||||
}
|
||||
else {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "Adding session \"%s\" (user=%s)", sessionUid, userAlias);
|
||||
AQH_Session_SetUser(session, user);
|
||||
AQH_Service_AddSession(sv, session);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Session has no user, not adding");
|
||||
AQH_Session_free(session);
|
||||
}
|
||||
} /* while */
|
||||
AQH_Session_List_free(sessionList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -518,29 +658,21 @@ AQH_SESSION *AQH_HttpService_LoadSession(const AQH_SERVICE *sv, const char *sess
|
||||
{
|
||||
GWEN_BUFFER *nameBuf;
|
||||
int rv;
|
||||
GWEN_DB_NODE *db;
|
||||
AQH_SESSION *session;
|
||||
|
||||
db=GWEN_DB_Group_new("user");
|
||||
|
||||
nameBuf=_getSessionFilePath(sv, sessionUid);
|
||||
rv=GWEN_DB_ReadFile(db, GWEN_Buffer_GetStart(nameBuf), GWEN_DB_FLAGS_DEFAULT);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||
if (nameBuf==NULL) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here");
|
||||
return NULL;
|
||||
}
|
||||
session=_readSessionFromFile(GWEN_Buffer_GetStart(nameBuf));
|
||||
if (session==NULL) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error loading session \"%s\" from config group", sessionUid);
|
||||
GWEN_Buffer_free(nameBuf);
|
||||
GWEN_DB_Group_free(db);
|
||||
return NULL;
|
||||
}
|
||||
GWEN_Buffer_free(nameBuf);
|
||||
|
||||
session=AQH_Session_fromDb(db);
|
||||
if (session==NULL) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error loading session \"%s\" from config group", sessionUid);
|
||||
GWEN_DB_Group_free(db);
|
||||
return NULL;
|
||||
}
|
||||
GWEN_DB_Group_free(db);
|
||||
|
||||
rv=_checkSession(session);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "Invalid data for session \"%s\"", sessionUid);
|
||||
@@ -686,7 +818,6 @@ AQH_SESSION *_ensureSession(AQH_SERVICE *sv, const char *sessionUid)
|
||||
AQH_Session_free(session);
|
||||
return NULL;
|
||||
}
|
||||
AQH_User_Attach(user);
|
||||
AQH_Session_SetUser(session, user);
|
||||
AQH_Service_AddSession(sv, session);
|
||||
}
|
||||
@@ -773,23 +904,16 @@ GWEN_BUFFER *_getUserFilePath(const AQH_SERVICE *sv, const char *userAlias)
|
||||
|
||||
GWEN_BUFFER *_getSessionFilePath(const AQH_SERVICE *sv, const char *sessionUid)
|
||||
{
|
||||
const char *configFolder;
|
||||
GWEN_BUFFER *nameBuf;
|
||||
|
||||
configFolder=AQH_HttpService_GetConfigFolder(sv);
|
||||
if (!(configFolder && *configFolder)) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "No config folder given");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
GWEN_BUFFER *nameBuf;
|
||||
|
||||
nameBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
GWEN_Buffer_AppendString(nameBuf, configFolder);
|
||||
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S AQH_HTTP_SERVICE_DIR_SESSIONS GWEN_DIR_SEPARATOR_S);
|
||||
nameBuf=_getSessionFolder(sv);
|
||||
if (nameBuf) {
|
||||
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S);
|
||||
GWEN_Text_EscapeToBuffer(sessionUid, nameBuf);
|
||||
GWEN_Buffer_AppendString(nameBuf, ".conf");
|
||||
return nameBuf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1012,6 +1136,132 @@ int _writeDbFile(const char *fname, GWEN_DB_NODE *db)
|
||||
|
||||
|
||||
|
||||
GWEN_BUFFER *_getSessionFolder(const AQH_SERVICE *sv)
|
||||
{
|
||||
const char *configFolder;
|
||||
|
||||
configFolder=AQH_HttpService_GetConfigFolder(sv);
|
||||
if (!(configFolder && *configFolder)) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "No config folder given");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
GWEN_BUFFER *nameBuf;
|
||||
|
||||
nameBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
GWEN_Buffer_AppendString(nameBuf, configFolder);
|
||||
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S AQH_HTTP_SERVICE_DIR_SESSIONS);
|
||||
return nameBuf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GWEN_STRINGLIST *_getConfFileList(const char *folder, const char *mask)
|
||||
{
|
||||
GWEN_STRINGLIST *sl;
|
||||
int rv;
|
||||
|
||||
sl=GWEN_StringList_new();
|
||||
rv=GWEN_Directory_GetFileEntries(folder, sl, mask);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||
GWEN_StringList_free(sl);
|
||||
return NULL;
|
||||
}
|
||||
if (GWEN_StringList_Count(sl)<1) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "Empty string list");
|
||||
GWEN_StringList_free(sl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AQH_SESSION_LIST *_readAllSessionsIntoList(const AQH_SERVICE *sv)
|
||||
{
|
||||
GWEN_BUFFER *folderBuf;
|
||||
|
||||
folderBuf=_getSessionFolder(sv);
|
||||
if (folderBuf) {
|
||||
GWEN_STRINGLIST *fileList;
|
||||
|
||||
fileList=_getConfFileList(GWEN_Buffer_GetStart(folderBuf), "*.conf");
|
||||
if (fileList) {
|
||||
AQH_SESSION_LIST *sessionList;
|
||||
uint32_t pos;
|
||||
GWEN_STRINGLISTENTRY *se;
|
||||
|
||||
sessionList=AQH_Session_List_new();
|
||||
GWEN_Buffer_AppendString(folderBuf, GWEN_DIR_SEPARATOR_S);
|
||||
pos=GWEN_Buffer_GetPos(folderBuf);
|
||||
se=GWEN_StringList_FirstEntry(fileList);
|
||||
while(se) {
|
||||
const char *s;
|
||||
|
||||
s=GWEN_StringListEntry_Data(se);
|
||||
if (s && *s) {
|
||||
AQH_SESSION *session;
|
||||
|
||||
GWEN_Buffer_AppendString(folderBuf, s);
|
||||
session=_readSessionFromFile(GWEN_Buffer_GetStart(folderBuf));
|
||||
if (session==NULL) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here");
|
||||
}
|
||||
else {
|
||||
AQH_Session_List_Add(session, sessionList);
|
||||
}
|
||||
GWEN_Buffer_Crop(folderBuf, 0, pos);
|
||||
}
|
||||
se=GWEN_StringListEntry_Next(se);
|
||||
}
|
||||
if (AQH_Session_List_GetCount(sessionList)<1) {
|
||||
DBG_INFO(NULL, "Empty session list");
|
||||
AQH_Session_List_free(sessionList);
|
||||
GWEN_StringList_free(fileList);
|
||||
GWEN_Buffer_free(folderBuf);
|
||||
return NULL;
|
||||
}
|
||||
GWEN_StringList_free(fileList);
|
||||
GWEN_Buffer_free(folderBuf);
|
||||
return sessionList;
|
||||
}
|
||||
GWEN_Buffer_free(folderBuf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AQH_SESSION *_readSessionFromFile(const char *filename)
|
||||
{
|
||||
int rv;
|
||||
GWEN_DB_NODE *db;
|
||||
AQH_SESSION *session;
|
||||
|
||||
db=GWEN_DB_Group_new("session");
|
||||
|
||||
rv=GWEN_DB_ReadFile(db, filename, GWEN_DB_FLAGS_DEFAULT);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||
GWEN_DB_Group_free(db);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
session=AQH_Session_fromDb(db);
|
||||
if (session==NULL) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error loading session from file \"%s\"", filename);
|
||||
GWEN_DB_Group_free(db);
|
||||
return NULL;
|
||||
}
|
||||
GWEN_DB_Group_free(db);
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user