aqhome-storage: started adding class AqHomeHttpService
This will be the class handling HTTP requests for AqHome.
This commit is contained in:
@@ -39,6 +39,8 @@
|
|||||||
aqhomestorage.h
|
aqhomestorage.h
|
||||||
init.h
|
init.h
|
||||||
http.h
|
http.h
|
||||||
|
aqhomehttp.h
|
||||||
|
aqhomehttp_p.h
|
||||||
</headers>
|
</headers>
|
||||||
|
|
||||||
<sources>
|
<sources>
|
||||||
@@ -48,6 +50,7 @@
|
|||||||
init.c
|
init.c
|
||||||
http.c
|
http.c
|
||||||
main.c
|
main.c
|
||||||
|
aqhomehttp.c
|
||||||
</sources>
|
</sources>
|
||||||
|
|
||||||
<useTargets>
|
<useTargets>
|
||||||
|
|||||||
306
apps/aqhome-storage/aqhomehttp.c
Normal file
306
apps/aqhome-storage/aqhomehttp.c
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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 "./aqhomehttp_p.h"
|
||||||
|
#include "aqhome/http/httpservice.h"
|
||||||
|
#include "aqhome/http/httpservice_http.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/db.h>
|
||||||
|
#include <gwenhywfar/buffer.h>
|
||||||
|
#include <gwenhywfar/text.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_INHERIT(AQH_SERVICE, AQHOME_HTTP)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
||||||
|
static int _handleUrl(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq);
|
||||||
|
static int _handleUrl_login(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq);
|
||||||
|
static GWEN_MSG *_createResponseMsg(AQH_SERVICE *sv, int code, const char *text, const char *protocol, const char *page);
|
||||||
|
static void _writeDefaultResponseHeaderToBuffer(AQH_SERVICE *sv, int contentLength, GWEN_BUFFER *buf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* implementations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void AqHomeHttpService_Extend(AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
GWEN_NEW_OBJECT(AQHOME_HTTP, xsv);
|
||||||
|
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQHOME_HTTP, sv, xsv, _freeData);
|
||||||
|
|
||||||
|
AQH_HttpService_SetHandleRequestFn(sv, _handleUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _freeData(void *bp, void *p)
|
||||||
|
{
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=(AQHOME_HTTP*) p;
|
||||||
|
|
||||||
|
AQH_Storage_free(xsv->storage);
|
||||||
|
xsv->storage=NULL;
|
||||||
|
GWEN_MsgEndpoint_free(xsv->rootEndpoint);
|
||||||
|
xsv->rootEndpoint=NULL;
|
||||||
|
xsv->ipcdEndpoint=NULL;
|
||||||
|
xsv->mqttEndpoint=NULL;
|
||||||
|
xsv->httpdEndpoint=NULL;
|
||||||
|
GWEN_DB_Group_free(xsv->dbArgs);
|
||||||
|
xsv->dbArgs=NULL;
|
||||||
|
free(xsv->pidFile);
|
||||||
|
|
||||||
|
GWEN_FREE_OBJECT(xsv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_DB_NODE *AqHomeHttpService_GetDbArgs(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv)
|
||||||
|
return xsv->dbArgs;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char *AqHomeHttpService_GetPidFile(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv)
|
||||||
|
return xsv->pidFile;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AqHomeHttpService_SetPidFile(AQH_SERVICE *sv, const char *s)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv) {
|
||||||
|
free(xsv->pidFile);
|
||||||
|
xsv->pidFile=s?strdup(s):NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetRootEndpoint(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv)
|
||||||
|
return xsv->rootEndpoint;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetIpcdEndpoint(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv)
|
||||||
|
return xsv->ipcdEndpoint;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetMqttEndpoint(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv)
|
||||||
|
return xsv->mqttEndpoint;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetHttpdEndpoint(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv)
|
||||||
|
return xsv->httpdEndpoint;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_STORAGE *AqHomeHttpService_GetStorage(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv)
|
||||||
|
return xsv->storage;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _handleUrl(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq)
|
||||||
|
{
|
||||||
|
|
||||||
|
const GWEN_URL *url;
|
||||||
|
const char *sPath;
|
||||||
|
|
||||||
|
url=AQH_HttpRequest_GetUrl(rq);
|
||||||
|
|
||||||
|
sPath=GWEN_Url_GetPath(url);
|
||||||
|
if (strcasecmp(sPath, "/login")==0)
|
||||||
|
return _handleUrl_login(sv, rq);
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "Invalid URL [%s]", sPath);
|
||||||
|
return GWEN_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _handleUrl_login(AQH_SERVICE *sv, AQH_HTTP_REQUEST *rq)
|
||||||
|
{
|
||||||
|
const char *protocol;
|
||||||
|
const char *cmd;
|
||||||
|
AQH_SESSION *session;
|
||||||
|
GWEN_MSG *msgOut=NULL;
|
||||||
|
|
||||||
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
||||||
|
session=AQH_HttpRequest_GetSession(rq);
|
||||||
|
cmd=AQH_HttpRequest_GetCommand(rq);
|
||||||
|
if (cmd && strcasecmp(cmd, "GET")==0) {
|
||||||
|
GWEN_BUFFER *pageBuf;
|
||||||
|
const char *s;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
pageBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
s=AQH_HttpService_GetSiteHeader(sv);
|
||||||
|
if (s)
|
||||||
|
GWEN_Buffer_AppendString(pageBuf, s);
|
||||||
|
|
||||||
|
rv=AQH_HttpService_AddFile(sv, session, "login.html", pageBuf);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error reading file \"login.html\"");
|
||||||
|
GWEN_Buffer_free(pageBuf);
|
||||||
|
msgOut=_createResponseMsg(sv, 500, "Internal Error", protocol, NULL);
|
||||||
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s=AQH_HttpService_GetSiteFooter(sv);
|
||||||
|
if (s)
|
||||||
|
GWEN_Buffer_AppendString(pageBuf, s);
|
||||||
|
|
||||||
|
msgOut=_createResponseMsg(sv, 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
|
||||||
|
GWEN_Buffer_free(pageBuf);
|
||||||
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msgOut=_createResponseMsg(sv, 501, "Not (yet) implemented", protocol, NULL);
|
||||||
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG *_createResponseMsg(AQH_SERVICE *sv, int code, const char *text, const char *protocol, const char *page)
|
||||||
|
{
|
||||||
|
GWEN_BUFFER *buf;
|
||||||
|
GWEN_MSG *msg;
|
||||||
|
|
||||||
|
buf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
AQH_HttpService_AddStatusLine(sv, code, text, protocol, buf);
|
||||||
|
_writeDefaultResponseHeaderToBuffer(sv, (page && *page)?strlen(page):0, buf);
|
||||||
|
if (page && *page)
|
||||||
|
GWEN_Buffer_AppendString(buf, page);
|
||||||
|
|
||||||
|
msg=GWEN_Msg_fromBytes((const uint8_t*)GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetUsedBytes(buf));
|
||||||
|
GWEN_Buffer_free(buf);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _writeDefaultResponseHeaderToBuffer(AQH_SERVICE *sv, int contentLength, GWEN_BUFFER *buf)
|
||||||
|
{
|
||||||
|
GWEN_DB_NODE *db;
|
||||||
|
|
||||||
|
db=GWEN_DB_Group_new("header");
|
||||||
|
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "Keep-Alive");
|
||||||
|
GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Type", "text/html; charset=utf-8");
|
||||||
|
GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-Length", contentLength);
|
||||||
|
|
||||||
|
AQH_HttpService_AddHeader(sv, db, buf);
|
||||||
|
GWEN_DB_Group_free(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
41
apps/aqhome-storage/aqhomehttp.h
Normal file
41
apps/aqhome-storage/aqhomehttp.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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_HTTP_H
|
||||||
|
#define AQHOME_HTTP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "aqhome/service/service.h"
|
||||||
|
#include "aqhome/data/storage.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/endpoint.h>
|
||||||
|
|
||||||
|
|
||||||
|
void AqHomeHttpService_Extend(AQH_SERVICE *sv);
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetRootEndpoint(const AQH_SERVICE *sv);
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetIpcdEndpoint(const AQH_SERVICE *sv);
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetMqttEndpoint(const AQH_SERVICE *sv);
|
||||||
|
GWEN_MSG_ENDPOINT *AqHomeHttpService_GetHttpdEndpoint(const AQH_SERVICE *sv);
|
||||||
|
|
||||||
|
AQH_STORAGE *AqHomeHttpService_GetStorage(const AQH_SERVICE *sv);
|
||||||
|
|
||||||
|
GWEN_DB_NODE *AqHomeHttpService_GetDbArgs(const AQH_SERVICE *sv);
|
||||||
|
const char *AqHomeHttpService_GetPidFile(const AQH_SERVICE *sv);
|
||||||
|
void AqHomeHttpService_SetPidFile(AQH_SERVICE *sv, const char *s);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
35
apps/aqhome-storage/aqhomehttp_p.h
Normal file
35
apps/aqhome-storage/aqhomehttp_p.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* 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_HTTP_P_H
|
||||||
|
#define AQHOME_HTTP_P_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "./aqhomehttp.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AQHOME_HTTP AQHOME_HTTP;
|
||||||
|
struct AQHOME_HTTP {
|
||||||
|
GWEN_MSG_ENDPOINT *rootEndpoint;
|
||||||
|
|
||||||
|
GWEN_MSG_ENDPOINT *ipcdEndpoint;
|
||||||
|
GWEN_MSG_ENDPOINT *mqttEndpoint;
|
||||||
|
GWEN_MSG_ENDPOINT *httpdEndpoint;
|
||||||
|
|
||||||
|
AQH_STORAGE *storage;
|
||||||
|
|
||||||
|
GWEN_DB_NODE *dbArgs;
|
||||||
|
|
||||||
|
char *pidFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user