Files
aqhomecontrol/aqhome/http/urlhandler.c

262 lines
6.2 KiB
C

/****************************************************************************
* 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
//#define DISABLE_DEBUGLOG
#include "./urlhandler_p.h"
#include "aqhome/http/httpservice_http.h"
#include <gwenhywfar/debug.h>
#include <gwenhywfar/misc.h>
#include <gwenhywfar/text.h>
GWEN_INHERIT_FUNCTIONS(AQH_HTTP_URLHANDLER)
GWEN_LIST_FUNCTIONS(AQH_HTTP_URLHANDLER, AQH_HttpUrlHandler)
static int _addContentHeaders(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf);
static int _addContentFooters(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf);
AQH_HTTP_URLHANDLER *AQH_HttpUrlHandler_new(AQH_SERVICE *sv)
{
AQH_HTTP_URLHANDLER *uh;
GWEN_NEW_OBJECT(AQH_HTTP_URLHANDLER, uh);
GWEN_INHERIT_INIT(AQH_HTTP_URLHANDLER, uh);
GWEN_LIST_INIT(AQH_HTTP_URLHANDLER, uh);
uh->urlPatternList=GWEN_StringList_new();
uh->httpService=sv;
return uh;
}
void AQH_HttpUrlHandler_free(AQH_HTTP_URLHANDLER *uh)
{
if (uh) {
GWEN_LIST_FINI(AQH_HTTP_URLHANDLER, uh);
GWEN_INHERIT_FINI(AQH_HTTP_URLHANDLER, uh);
free(uh->folder);
GWEN_StringList_free(uh->urlPatternList);
GWEN_FREE_OBJECT(uh);
}
}
AQH_SERVICE *AQH_HttpUrlHandler_GetHttpService(const AQH_HTTP_URLHANDLER *uh)
{
return uh?uh->httpService:NULL;
}
AQH_HTTP_CONTENT *AQH_HttpUrlHandler_GetContentProvider(const AQH_HTTP_URLHANDLER *uh)
{
return uh?uh->httpContentProvider:NULL;
}
void AQH_HttpUrlHandler_SetContentProvider(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_CONTENT *cp)
{
if (uh)
uh->httpContentProvider=cp;
}
void AQH_HttpUrlHandler_AddUrlPattern(AQH_HTTP_URLHANDLER *uh, const char *s)
{
if (uh && s && *s)
GWEN_StringList_AppendString(uh->urlPatternList, s, 0, 1);
}
const char *AQH_HttpUrlHandler_GetFolder(const AQH_HTTP_URLHANDLER *uh)
{
return uh?uh->folder:NULL;
}
void AQH_HttpUrlHandler_SetFolder(AQH_HTTP_URLHANDLER *uh, const char *s)
{
if (uh) {
free(uh->folder);
uh->folder=s?strdup(s):NULL;
}
}
int AQH_HttpUrlHandler_UrlMatches(const AQH_HTTP_URLHANDLER *uh, const char *s)
{
if (uh && s && *s) {
GWEN_STRINGLISTENTRY *se;
se=GWEN_StringList_FirstEntry(uh->urlPatternList);
while(se) {
const char *pattern;
pattern=GWEN_StringListEntry_Data(se);
if (GWEN_Text_ComparePattern(s, pattern, 0)!=-1)
return 1;
se=GWEN_StringListEntry_Next(se);
}
}
return 0;
}
void AQH_HttpUrlHandler_SetHandleFn(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_URLHANDLER_HANDLE_FN fn)
{
if (uh)
uh->handleFn=fn;
}
int AQH_HttpUrlHandler_HandleMessage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
{
if (uh && uh->handleFn)
return uh->handleFn(uh, rq);
return 0;
}
int AQH_HttpUrlHandler_AddContentHeaders(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf)
{
return _addContentHeaders(uh->httpContentProvider, m, dbuf);
}
int AQH_HttpUrlHandler_AddContentFooters(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf)
{
return _addContentFooters(uh->httpContentProvider, m, dbuf);
}
GWEN_MSG *AQH_HttpUrlHandler_CreatePageMessage(AQH_HTTP_URLHANDLER *uh,
AQH_HTTP_REQUEST *rq,
const char *statusTextColor, const char *statusMsg,
int withHeadersAndFooters,
GWEN_DB_NODE *dbValues,
AQH_HTTP_URLHANDLER_WRITEPAGE_CB cb)
{
GWEN_BUFFER *pageBuf;
int rv;
GWEN_MSG *msgOut=NULL;
const char *protocol;
protocol=AQH_HttpRequest_GetProtocol(rq);
pageBuf=GWEN_Buffer_new(0, 256, 0, 1);
if (withHeadersAndFooters) {
rv=AQH_HttpUrlHandler_AddContentHeaders(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
GWEN_Buffer_free(pageBuf);
return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
}
}
if (statusMsg)
GWEN_Buffer_AppendArgs(pageBuf, "<p><font color=\"%s\">%s</font></p>", statusTextColor?statusTextColor:"black", statusMsg);
if (cb) {
rv=cb(uh, rq, dbValues, pageBuf);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
GWEN_Buffer_free(pageBuf);
return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
}
}
if (withHeadersAndFooters) {
rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
if (rv<0) {
DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
GWEN_Buffer_free(pageBuf);
return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
}
}
msgOut=AQH_HttpService_CreateResponseMsg(uh->httpService, 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
GWEN_Buffer_free(pageBuf);
return msgOut;
}
int _addContentHeaders(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf)
{
AQH_HTTP_CONTENT *parent;
int rv;
parent=AQH_HttpContent_Tree2_GetParent(c);
if (parent) {
rv=_addContentHeaders(parent, m, dbuf);
if (rv<0) {
DBG_INFO(AQH_LOGDOMAIN, "Error adding content headers for \"%s\"", AQH_HttpContent_GetName(parent));
return rv;
}
}
rv=AQH_HttpContent_AddOpeningContent(c, m, dbuf);
if (rv<0) {
DBG_INFO(AQH_LOGDOMAIN, "Error adding content headers for \"%s\"", AQH_HttpContent_GetName(c));
return rv;
}
return 0;
}
int _addContentFooters(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf)
{
AQH_HTTP_CONTENT *parent;
int rv;
rv=AQH_HttpContent_AddClosingContent(c, m, dbuf);
if (rv<0) {
DBG_INFO(AQH_LOGDOMAIN, "Error adding content footers for \"%s\"", AQH_HttpContent_GetName(c));
return rv;
}
parent=AQH_HttpContent_Tree2_GetParent(c);
if (parent) {
rv=_addContentFooters(parent, m, dbuf);
if (rv<0) {
DBG_INFO(AQH_LOGDOMAIN, "Error adding content footers for \"%s\"", AQH_HttpContent_GetName(parent));
return rv;
}
}
return 0;
}