fixed memory leaks, added cleanup code, added valgrind scripts to test binaries
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
fini.h
|
||||
loop.h
|
||||
loop_http.h
|
||||
cleanup.h
|
||||
u_login.h
|
||||
u_rooms.h
|
||||
aqhomehttp.h
|
||||
@@ -57,6 +58,7 @@
|
||||
fini.c
|
||||
loop.c
|
||||
loop_http.c
|
||||
cleanup.c
|
||||
u_login.c
|
||||
u_rooms.c
|
||||
main.c
|
||||
|
||||
@@ -48,7 +48,7 @@ void AqHomeHttpService_Extend(AQH_SERVICE *sv)
|
||||
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQHOME_HTTP, sv, xsv, _freeData);
|
||||
|
||||
xsv->contentTree=AQH_HttpContent_new("root");
|
||||
|
||||
xsv->storageMutex=GWEN_Mutex_new();
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ void _freeData(void *bp, void *p)
|
||||
xsv->storage=NULL;
|
||||
AQH_HttpContent_free(xsv->contentTree);
|
||||
xsv->contentTree=NULL;
|
||||
GWEN_Mutex_free(xsv->storageMutex);
|
||||
|
||||
GWEN_FREE_OBJECT(xsv);
|
||||
}
|
||||
@@ -124,6 +125,65 @@ void AqHomeHttpService_SetContentTree(AQH_SERVICE *sv, AQH_HTTP_CONTENT *c)
|
||||
|
||||
|
||||
|
||||
void AqHomeHttpService_MarkStorageChanged(AQH_SERVICE *sv)
|
||||
{
|
||||
if (sv) {
|
||||
AQHOME_HTTP *xsv;
|
||||
|
||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||
if (xsv) {
|
||||
AQH_Storage_AddRuntimeFlags(xsv->storage, AQH_STORAGE_RTFLAGS_MODIFIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AqHomeHttpService_LockStorage(AQH_SERVICE *sv)
|
||||
{
|
||||
if (sv) {
|
||||
AQHOME_HTTP *xsv;
|
||||
|
||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||
if (xsv) {
|
||||
int rv;
|
||||
|
||||
rv=GWEN_Mutex_Lock(xsv->storageMutex);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error obtaining lock on storage mutex");
|
||||
return rv;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return GWEN_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AqHomeHttpService_UnlockStorage(AQH_SERVICE *sv)
|
||||
{
|
||||
if (sv) {
|
||||
AQHOME_HTTP *xsv;
|
||||
|
||||
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||
if (xsv) {
|
||||
int rv;
|
||||
|
||||
rv=GWEN_Mutex_Unlock(xsv->storageMutex);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error releasing lock on storage mutex");
|
||||
return rv;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return GWEN_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,9 @@ AQH_HTTP_CONTENT *AqHomeHttpService_GetContentTree(const AQH_SERVICE *sv);
|
||||
void AqHomeHttpService_SetContentTree(AQH_SERVICE *sv, AQH_HTTP_CONTENT *c);
|
||||
|
||||
|
||||
|
||||
int AqHomeHttpService_LockStorage(AQH_SERVICE *sv);
|
||||
int AqHomeHttpService_UnlockStorage(AQH_SERVICE *sv);
|
||||
void AqHomeHttpService_MarkStorageChanged(AQH_SERVICE *sv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
|
||||
#include "./aqhomehttp.h"
|
||||
|
||||
#include <gwenhywfar/mutex.h>
|
||||
|
||||
|
||||
|
||||
typedef struct AQHOME_HTTP AQHOME_HTTP;
|
||||
struct AQHOME_HTTP {
|
||||
AQH_STORAGE *storage; /* do not release */
|
||||
AQH_STORAGE *storage; /* do not release */
|
||||
GWEN_MUTEX *storageMutex;
|
||||
|
||||
AQH_HTTP_CONTENT *contentTree;
|
||||
};
|
||||
|
||||
@@ -36,16 +36,16 @@ AQHOME_STORAGE *AqHomeStorage_new()
|
||||
void AqHomeStorage_free(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
if (aqh) {
|
||||
AQH_Service_free(aqh->httpService);
|
||||
aqh->httpService=NULL;
|
||||
AQH_Storage_free(aqh->storage);
|
||||
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
|
||||
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
|
||||
GWEN_DB_Group_free(aqh->dbArgs);
|
||||
|
||||
aqh->storage=NULL;
|
||||
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
|
||||
aqh->rootEndpoint=NULL;
|
||||
aqh->ipcdEndpoint=NULL;
|
||||
aqh->mqttEndpoint=NULL;
|
||||
aqh->httpdEndpoint=NULL;
|
||||
GWEN_DB_Group_free(aqh->dbArgs);
|
||||
aqh->dbArgs=NULL;
|
||||
free(aqh->pidFile);
|
||||
|
||||
@@ -114,6 +114,13 @@ void AqHomeStorage_SetPidFile(AQHOME_STORAGE *aqh, const char *s)
|
||||
|
||||
|
||||
|
||||
int AqHomeStorage_GetTimeout(const AQHOME_STORAGE *aqh)
|
||||
{
|
||||
return aqh?aqh->timeout:0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ AQH_STORAGE *AqHomeStorage_GetStorage(const AQHOME_STORAGE *aqh);
|
||||
const char *AqHomeStorage_GetPidFile(const AQHOME_STORAGE *aqh);
|
||||
void AqHomeStorage_SetPidFile(AQHOME_STORAGE *aqh, const char *s);
|
||||
|
||||
int AqHomeStorage_GetTimeout(const AQHOME_STORAGE *aqh);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#define AQHOME_STORAGE_DEFAULT_STATEFILE "/var/lib/aqhomestorage/config/statefile"
|
||||
|
||||
#define AQHOME_STORAGE_DEFAULT_MAXSESSIONAGE (30*60)
|
||||
|
||||
#define AQHOME_STORAGE_SITEHEADER "site-header.html"
|
||||
#define AQHOME_STORAGE_SITEFOOTER "site-footer.html"
|
||||
|
||||
@@ -35,9 +37,9 @@
|
||||
struct AQHOME_STORAGE {
|
||||
GWEN_MSG_ENDPOINT *rootEndpoint;
|
||||
|
||||
GWEN_MSG_ENDPOINT *ipcdEndpoint;
|
||||
GWEN_MSG_ENDPOINT *mqttEndpoint;
|
||||
GWEN_MSG_ENDPOINT *httpdEndpoint;
|
||||
GWEN_MSG_ENDPOINT *ipcdEndpoint; /* don't release, will be released by freeing rootEndpoint! */
|
||||
GWEN_MSG_ENDPOINT *mqttEndpoint; /* don't release, will be released by freeing rootEndpoint! */
|
||||
GWEN_MSG_ENDPOINT *httpdEndpoint; /* don't release, will be released by freeing rootEndpoint! */
|
||||
|
||||
GWEN_DB_NODE *dbArgs;
|
||||
|
||||
@@ -45,6 +47,10 @@ struct AQHOME_STORAGE {
|
||||
AQH_STORAGE *storage;
|
||||
|
||||
char *pidFile;
|
||||
|
||||
int maxSessionAgeInSeconds;
|
||||
|
||||
int timeout; /* timeout for run e.g. inside valgrind */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
61
apps/aqhome-storage/cleanup.c
Normal file
61
apps/aqhome-storage/cleanup.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
* This file is part of the project AqHome.
|
||||
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||
*
|
||||
* The license for this file can be found in the file COPYING which you
|
||||
* should have received along with this file.
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "./cleanup.h"
|
||||
#include "./aqhomehttp.h"
|
||||
#include "./aqhomestorage_p.h"
|
||||
#include "aqhome/http/httpservice_conf.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/args.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/endpoint.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defines
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* implementations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void AqHomeStorage_Cleanup(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
|
||||
int rv;
|
||||
|
||||
rv=AQH_HttpService_CleanupSessions(aqh->httpService, aqh->maxSessionAgeInSeconds);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
25
apps/aqhome-storage/cleanup.h
Normal file
25
apps/aqhome-storage/cleanup.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/****************************************************************************
|
||||
* This file is part of the project AqHome.
|
||||
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||
*
|
||||
* The license for this file can be found in the file COPYING which you
|
||||
* should have received along with this file.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_STORAGE_CLEANUP_H
|
||||
#define AQHOME_STORAGE_CLEANUP_H
|
||||
|
||||
|
||||
#include "./aqhomestorage.h"
|
||||
|
||||
|
||||
void AqHomeStorage_Cleanup(AQHOME_STORAGE *aqh);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -96,6 +96,9 @@ int AqHomeStorage_Init(AQHOME_STORAGE *aqh, int argc, char **argv)
|
||||
}
|
||||
aqh->dbArgs=dbArgs;
|
||||
|
||||
aqh->maxSessionAgeInSeconds=GWEN_DB_GetIntValue(dbArgs, "maxSessionAge", 0, AQHOME_STORAGE_DEFAULT_MAXSESSIONAGE);
|
||||
aqh->timeout=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 0);
|
||||
|
||||
s=GWEN_DB_GetCharValue(dbArgs, "pidfile", 0, AQHOME_STORAGE_DEFAULT_PIDFILE);
|
||||
if (s && *s) {
|
||||
AqHomeStorage_SetPidFile(aqh, s);
|
||||
@@ -415,6 +418,17 @@ int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs)
|
||||
I18S("Specify the port to listen on for HTTP connections"),
|
||||
I18S("Specify the port to listen on for HTTP connections")
|
||||
},
|
||||
{
|
||||
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
|
||||
GWEN_ArgsType_Int, /* type */
|
||||
"maxSessionAge", /* name */
|
||||
0, /* minnum */
|
||||
1, /* maxnum */
|
||||
NULL, /* short option */
|
||||
"maxsessionage", /* long option */
|
||||
I18S("Specify maximum session age in seconds (default: 30mins)"),
|
||||
I18S("Specify maximum session age in seconds (default: 30mins)")
|
||||
},
|
||||
{
|
||||
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
|
||||
GWEN_ArgsType_Char, /* type */
|
||||
|
||||
@@ -151,7 +151,7 @@ int _setupHttpService(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
|
||||
DBG_ERROR(NULL, "Error loading config for HTTP service (%d)", rv);
|
||||
return GWEN_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
AQH_HttpService_LoadAllSessions(aqh->httpService);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
#include "./loop.h"
|
||||
#include "./loop_http.h"
|
||||
#include "./aqhomehttp.h"
|
||||
#include "./aqhomestorage_p.h"
|
||||
#include "aqhome/http/httpservice_conf.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/args.h>
|
||||
@@ -34,6 +36,7 @@
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int _writeModifiedSessions(AQHOME_STORAGE *aqh);
|
||||
|
||||
|
||||
|
||||
@@ -48,9 +51,97 @@ void AqHomeStorage_Loop(AQHOME_STORAGE *aqh, int timeoutInMsecs)
|
||||
GWEN_MsgEndpoint_ChildrenIoLoop(aqh->rootEndpoint, timeoutInMsecs);
|
||||
AqHomeStorage_ReadAndHandleHttpMessages(aqh);
|
||||
// AqHomeStorage_ReadAndHandleIpcMessages(aqh);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AqHomeStorage_WriteStorageIfChanged(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
if (AQH_Storage_GetRuntimeFlags(aqh->storage) & AQH_STORAGE_RTFLAGS_MODIFIED) {
|
||||
int rv;
|
||||
|
||||
DBG_INFO(NULL, "Storage modified, writing statefile");
|
||||
rv=AqHomeHttpService_LockStorage(aqh->httpService);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "Error locking storage (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
rv=AQH_Storage_WriteState(aqh->storage);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "Error writing state file (%d)", rv);
|
||||
AqHomeHttpService_UnlockStorage(aqh->httpService);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv=AqHomeHttpService_UnlockStorage(aqh->httpService);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "Error unlocking storage (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int AqHomeStorage_WriteServiceIfChanged(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv=_writeModifiedSessions(aqh);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _writeModifiedSessions(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
AQH_SESSION_LIST *sessionList;
|
||||
int rv;
|
||||
|
||||
rv=AQH_HttpService_LockSessions(aqh->httpService);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "Error locking sessions (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
sessionList=AQH_Service_GetSessionList(aqh->httpService);
|
||||
if (sessionList) {
|
||||
AQH_SESSION *session;
|
||||
|
||||
session=AQH_Session_List_First(sessionList);
|
||||
while(session) {
|
||||
if (AQH_Session_GetRuntimeFlags(session) & AQH_SESSION_RTFLAGS_MODIFIED) {
|
||||
DBG_INFO(NULL, "Session \"%s\" modified, writing", AQH_Session_GetUid(session));
|
||||
rv=AQH_HttpService_SaveSession(aqh->httpService, session);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "Error writing session \"%s\" (%d)", AQH_Session_GetUid(session), rv);
|
||||
}
|
||||
else {
|
||||
DBG_DEBUG(NULL, "Session \"%s\" written", AQH_Session_GetUid(session));
|
||||
AQH_Session_SubRuntimeFlags(session, AQH_SESSION_RTFLAGS_MODIFIED);
|
||||
}
|
||||
}
|
||||
session=AQH_Session_List_Next(session);
|
||||
}
|
||||
}
|
||||
|
||||
rv=AQH_HttpService_UnlockSessions(aqh->httpService);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "Error unlocking sessions (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
|
||||
void AqHomeStorage_Loop(AQHOME_STORAGE *aqh, int timeoutInMsecs);
|
||||
|
||||
int AqHomeStorage_WriteStorageIfChanged(AQHOME_STORAGE *aqh);
|
||||
|
||||
int AqHomeStorage_WriteServiceIfChanged(AQHOME_STORAGE *aqh);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "./init.h"
|
||||
#include "./fini.h"
|
||||
#include "./loop.h"
|
||||
#include "./cleanup.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/logger.h>
|
||||
@@ -29,6 +30,14 @@
|
||||
|
||||
|
||||
|
||||
//#define CLEANUP_INTERVAL_IN_SECS (5*60)
|
||||
//#define WRITE_INTERVAL_IN_SECS (5*60)
|
||||
|
||||
#define CLEANUP_INTERVAL_IN_SECS (60)
|
||||
#define WRITE_INTERVAL_IN_SECS (60)
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defines
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
@@ -48,6 +57,9 @@ static int _setupSigAction(struct sigaction *sa, int sig);
|
||||
static void _signalHandler(int s);
|
||||
#endif
|
||||
|
||||
static void _runService(AQHOME_STORAGE *aqh);
|
||||
static void _writeCurrentState(AQHOME_STORAGE *aqh);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
@@ -106,10 +118,7 @@ int main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
|
||||
while(!stopService) {
|
||||
DBG_DEBUG(NULL, "Next loop");
|
||||
AqHomeStorage_Loop(aqh, 2000);
|
||||
}
|
||||
_runService(aqh);
|
||||
|
||||
AqHomeStorage_Fini(aqh);
|
||||
AqHomeStorage_free(aqh);
|
||||
@@ -122,6 +131,67 @@ int main(int argc, char **argv)
|
||||
|
||||
|
||||
|
||||
void _runService(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
time_t timeStart;
|
||||
time_t timeLastCleanup;
|
||||
time_t timeLastWrite;
|
||||
int timeout;
|
||||
|
||||
timeout=AqHomeStorage_GetTimeout(aqh);
|
||||
timeStart=time(NULL);
|
||||
timeLastCleanup=time(NULL);
|
||||
timeLastWrite=time(NULL);
|
||||
|
||||
while(!stopService) {
|
||||
time_t now;
|
||||
|
||||
DBG_DEBUG(NULL, "Next loop");
|
||||
AqHomeStorage_Loop(aqh, 2000);
|
||||
|
||||
now=time(NULL);
|
||||
|
||||
if (((int)difftime(now, timeLastCleanup))>CLEANUP_INTERVAL_IN_SECS) {
|
||||
DBG_INFO(NULL, "Cleanup time");
|
||||
AqHomeStorage_Cleanup(aqh);
|
||||
timeLastCleanup=now;
|
||||
}
|
||||
|
||||
if (((int)difftime(now, timeLastWrite))>WRITE_INTERVAL_IN_SECS) {
|
||||
DBG_INFO(NULL, "Write time");
|
||||
_writeCurrentState(aqh);
|
||||
timeLastWrite=now;
|
||||
}
|
||||
|
||||
|
||||
if (timeout && ((int)difftime(now, timeStart))>timeout) {
|
||||
DBG_INFO(NULL, "Timeout");
|
||||
_writeCurrentState(aqh);
|
||||
break;
|
||||
}
|
||||
} /* while */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _writeCurrentState(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv=AqHomeStorage_WriteStorageIfChanged(aqh);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "ATTENTION: Could not write storage statefile (%d)", rv);
|
||||
}
|
||||
|
||||
rv=AqHomeStorage_WriteServiceIfChanged(aqh);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "ATTENTION: Could not write current config (%d)", rv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int _setSignalHandlers(void)
|
||||
{
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
|
||||
@@ -308,8 +308,9 @@ AQH_SESSION *_generateSessionForUser(AQH_SERVICE *sv, AQH_USER *u)
|
||||
session=AQH_Session_new();
|
||||
AQH_Session_SetUid(session, GWEN_Buffer_GetStart(buf));
|
||||
|
||||
ts=GWEN_Timestamp_NowInGmTime();
|
||||
ts=GWEN_Timestamp_NowInLocalTime();
|
||||
AQH_Session_SetTimestampCreation(session, ts);
|
||||
AQH_Session_SetTimestampLastAccess(session, ts);
|
||||
GWEN_Timestamp_free(ts);
|
||||
|
||||
AQH_Session_SetUserAlias(session, AQH_User_GetAlias(u));
|
||||
|
||||
@@ -36,14 +36,15 @@
|
||||
*/
|
||||
|
||||
static int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
static int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
static int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
static GWEN_MSG *_handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
static GWEN_MSG *_handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
|
||||
static void _handleGetList(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
||||
|
||||
static void _handleGetAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
||||
static int _handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
static GWEN_MSG *_handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
static int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf);
|
||||
static GWEN_MSG *_addRoomCreateResponse(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||
|
||||
|
||||
|
||||
@@ -68,7 +69,7 @@ int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
{
|
||||
const char *protocol;
|
||||
const char *cmd;
|
||||
GWEN_MSG *msgOut=NULL;
|
||||
GWEN_MSG *msgOut;
|
||||
|
||||
AQH_HttpService_SetupModuleAndPerms(AQH_HttpUrlHandler_GetHttpService(uh), rq, "aqhome");
|
||||
AQH_HttpRequest_SetupUrlPathMembers(rq);
|
||||
@@ -76,26 +77,14 @@ int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
protocol=AQH_HttpRequest_GetProtocol(rq);
|
||||
cmd=AQH_HttpRequest_GetCommand(rq);
|
||||
if (cmd && *cmd) {
|
||||
int rv;
|
||||
|
||||
if (strcasecmp(cmd, "GET")==0) {
|
||||
rv=_handleGet(uh, rq);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(cmd, "POST")==0) {
|
||||
rv=_handlePost(uh, rq);
|
||||
if (rv<0) {
|
||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (strcasecmp(cmd, "GET")==0)
|
||||
msgOut=_handleGet(uh, rq);
|
||||
else if (strcasecmp(cmd, "POST")==0)
|
||||
msgOut=_handlePost(uh, rq);
|
||||
else {
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 405, "Method not allowed", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
}
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
@@ -106,7 +95,7 @@ int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
|
||||
|
||||
|
||||
int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
GWEN_MSG *_handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
{
|
||||
GWEN_BUFFER *pageBuf;
|
||||
int rv;
|
||||
@@ -120,9 +109,7 @@ int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
if (rv<0) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
|
||||
GWEN_Buffer_free(pageBuf);
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||
}
|
||||
|
||||
/* handle middle part (header - middle - footer) */
|
||||
@@ -140,38 +127,35 @@ int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
_handleGetAdd(uh, rq, pageBuf);
|
||||
else {
|
||||
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
GWEN_Buffer_free(pageBuf);
|
||||
return 0;
|
||||
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "No list of url members");
|
||||
GWEN_Buffer_free(pageBuf);
|
||||
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||
}
|
||||
|
||||
rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
GWEN_Buffer_free(pageBuf);
|
||||
return rv;
|
||||
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||
}
|
||||
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
|
||||
GWEN_Buffer_free(pageBuf);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
|
||||
return 0;
|
||||
return msgOut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
GWEN_MSG *_handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
{
|
||||
GWEN_DB_NODE *db;
|
||||
const GWEN_STRINGLIST *sl;
|
||||
const char *protocol;
|
||||
GWEN_MSG *msgOut=NULL;
|
||||
int rv;
|
||||
|
||||
DBG_ERROR(NULL, "POST:");
|
||||
db=AQH_HttpRequest_GetDbPostBody(rq);
|
||||
@@ -185,24 +169,21 @@ int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
s=GWEN_StringList_StringAt(sl, 1);
|
||||
if (s && *s) {
|
||||
if (strcasecmp(s, "add")==0)
|
||||
rv=_handlePostAdd(uh, rq);
|
||||
return _handlePostAdd(uh, rq);
|
||||
else {
|
||||
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "Invalid url (2nd member missing)");
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
else {
|
||||
DBG_ERROR(NULL, "No list of url members");
|
||||
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -316,65 +297,89 @@ int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *d
|
||||
|
||||
|
||||
|
||||
int _handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
GWEN_MSG *_handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
{
|
||||
const char *protocol;
|
||||
AQH_SERVICE *sv;
|
||||
uint32_t perms;
|
||||
GWEN_MSG *msgOut=NULL;
|
||||
|
||||
protocol=AQH_HttpRequest_GetProtocol(rq);
|
||||
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||
perms=AQH_HttpRequest_GetModulePerms(rq);
|
||||
if (perms & AQHOME_HTTP_PERMS_ADD_ROOM) {
|
||||
GWEN_DB_NODE *db;
|
||||
const char *roomName;
|
||||
const char *roomDescr;
|
||||
AQH_STORAGE *sto;
|
||||
|
||||
db=AQH_HttpRequest_GetDbPostBody(rq);
|
||||
|
||||
roomName=GWEN_DB_GetCharValue(db, "name", 0, NULL);
|
||||
roomDescr=GWEN_DB_GetCharValue(db, "description", 0, NULL);
|
||||
|
||||
if (!(roomName && *roomName)) {
|
||||
msgOut=AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Missing room name"), 1, db, _writeAddPage);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sto=AqHomeHttpService_GetStorage(sv);
|
||||
if (sto) {
|
||||
AQH_ROOM *r;
|
||||
|
||||
r=AQH_Room_new();
|
||||
AQH_Room_SetName(r, roomName);
|
||||
if (roomDescr && *roomDescr)
|
||||
AQH_Room_SetDescription(r, roomDescr);
|
||||
if (AQH_Storage_GetRoomByName(sto, roomName)!=NULL) {
|
||||
msgOut=AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Room already exists"), 1, db, _writeAddPage);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
}
|
||||
AQH_Storage_AddRoom(sto, r);
|
||||
msgOut=AQH_HttpService_CreateRedirectingResponseMsg(sv, protocol, "/rooms/list");
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
return _addRoomCreateResponse(uh, rq);
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "No storage");
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
msgOut=AQH_HttpService_CreateResponseMsg(sv, 403, "Forbidden", protocol, NULL);
|
||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||
return 0;
|
||||
return AQH_HttpService_CreateResponseMsg(sv, 403, "Forbidden", protocol, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GWEN_MSG *_addRoomCreateResponse(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
const char *protocol;
|
||||
GWEN_DB_NODE *db;
|
||||
const char *roomName;
|
||||
const char *roomDescr;
|
||||
AQH_STORAGE *sto;
|
||||
|
||||
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||
protocol=AQH_HttpRequest_GetProtocol(rq);
|
||||
db=AQH_HttpRequest_GetDbPostBody(rq);
|
||||
|
||||
roomName=GWEN_DB_GetCharValue(db, "name", 0, NULL);
|
||||
roomDescr=GWEN_DB_GetCharValue(db, "description", 0, NULL);
|
||||
|
||||
if (!(roomName && *roomName)) {
|
||||
DBG_INFO(NULL, "Missing room name");
|
||||
return AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Missing room name"), 1, db, _writeAddPage);
|
||||
}
|
||||
|
||||
sto=AqHomeHttpService_GetStorage(sv);
|
||||
if (sto) {
|
||||
AQH_ROOM *r;
|
||||
int rv;
|
||||
|
||||
r=AQH_Room_new();
|
||||
AQH_Room_SetName(r, roomName);
|
||||
if (roomDescr && *roomDescr)
|
||||
AQH_Room_SetDescription(r, roomDescr);
|
||||
|
||||
rv=AqHomeHttpService_LockStorage(sv);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error locking storage");
|
||||
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||
}
|
||||
if (AQH_Storage_GetRoomByName(sto, roomName)!=NULL) {
|
||||
DBG_INFO(NULL, "Room \"%s\" already exists", roomName);
|
||||
AqHomeHttpService_UnlockStorage(sv);
|
||||
return AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Room already exists"), 1, db, _writeAddPage);
|
||||
}
|
||||
AQH_Storage_AddRoom(sto, r);
|
||||
AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED);
|
||||
|
||||
rv=AqHomeHttpService_UnlockStorage(sv);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error unlocking storage");
|
||||
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||
}
|
||||
return AQH_HttpService_CreateRedirectingResponseMsg(sv, protocol, "/rooms/list");
|
||||
}
|
||||
else
|
||||
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user