aqhome: more work on http server.
This commit is contained in:
244
apps/aqhome-storage/init_http.c
Normal file
244
apps/aqhome-storage/init_http.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/****************************************************************************
|
||||
* 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 "./init_http.h"
|
||||
#include "./aqhomestorage_p.h"
|
||||
#include "./aqhomehttp.h"
|
||||
#include "./u_login.h"
|
||||
#include "./u_rooms.h"
|
||||
|
||||
#include "aqhome/msg/endpoint_tty.h"
|
||||
#include "aqhome/ipc/endpoint_ipc.h"
|
||||
#include "aqhome/mqtt/endpoint_mqttc.h"
|
||||
#include "aqhome/http/endpoint_http.h"
|
||||
#include "aqhome/http/httpservice_conf.h"
|
||||
#include "aqhome/http/httpservice_http.h"
|
||||
#include "aqhome/http/httpservice.h"
|
||||
#include "aqhome/http/content_files.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/args.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/endpoint_tcpd.h>
|
||||
#include <gwenhywfar/endpoint_msgio.h>
|
||||
#include <gwenhywfar/directory.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* defines
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
//#define I18N(msg) msg
|
||||
#define I18S(msg) msg
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* forward declarations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void _setupEndpoint(AQHOME_STORAGE *aqh, const char *tcpAddress, int tcpPort);
|
||||
static int _setupHttpService(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs);
|
||||
static int _createContentRoot(AQHOME_STORAGE *aqh);
|
||||
static GWEN_MSG_ENDPOINT *_acceptHttpFn(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKET *sk, const GWEN_INETADDRESS *addr, void *data);
|
||||
|
||||
static int _createUrlHandler_login(AQHOME_STORAGE *aqh);
|
||||
static int _createUrlHandler_rooms(AQHOME_STORAGE *aqh);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* implementations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int AqHomeStorage_SetupHttp(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
|
||||
{
|
||||
const char *tcpAddress;
|
||||
int tcpPort;
|
||||
|
||||
tcpAddress=GWEN_DB_GetCharValue(dbArgs, "httpAddress", 0, NULL);
|
||||
tcpPort=GWEN_DB_GetIntValue(dbArgs, "httpPort", 0, AQHOME_STORAGE_DEFAULT_HTTP_PORT);
|
||||
|
||||
if (tcpAddress && *tcpAddress && tcpPort) {
|
||||
int rv;
|
||||
|
||||
_setupEndpoint(aqh, tcpAddress, tcpPort);
|
||||
rv=_setupHttpService(aqh, dbArgs);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv=_createContentRoot(aqh);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv=_createUrlHandler_login(aqh);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv=_createUrlHandler_rooms(aqh);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _setupEndpoint(AQHOME_STORAGE *aqh, const char *tcpAddress, int tcpPort)
|
||||
{
|
||||
GWEN_MSG_ENDPOINT *ep;
|
||||
|
||||
ep=GWEN_TcpdEndpoint_new(tcpAddress, tcpPort, NULL, 0);
|
||||
GWEN_TcpdEndpoint_SetAcceptFn(ep, _acceptHttpFn, aqh);
|
||||
|
||||
GWEN_MsgEndpoint_Tree2_AddChild(aqh->rootEndpoint, ep);
|
||||
aqh->httpdEndpoint=ep;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _setupHttpService(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
|
||||
{
|
||||
const char *configFolder;
|
||||
const char *sourceFolder;
|
||||
int rv;
|
||||
|
||||
configFolder=GWEN_DB_GetCharValue(dbArgs, "cfgdir", 0, AQHOME_STORAGE_DEFAULT_CONFIGDIR);
|
||||
sourceFolder=GWEN_DB_GetCharValue(dbArgs, "sourceFolder", 0, AQHOME_STORAGE_DEFAULT_HTTP_SOURCEDIR);
|
||||
aqh->httpService=AQH_HttpService_new(configFolder, sourceFolder);
|
||||
AqHomeHttpService_Extend(aqh->httpService);
|
||||
AqHomeHttpService_SetStorage(aqh->httpService, aqh->storage);
|
||||
rv=AQH_HttpService_LoadConfig(aqh->httpService);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error loading config for HTTP service (%d)", rv);
|
||||
return GWEN_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GWEN_MSG_ENDPOINT *_acceptHttpFn(GWEN_MSG_ENDPOINT *ep,
|
||||
GWEN_SOCKET *sk,
|
||||
const GWEN_INETADDRESS *addr,
|
||||
GWEN_UNUSED void *data)
|
||||
{
|
||||
GWEN_MSG_ENDPOINT *epIncoming;
|
||||
|
||||
/* AQHOME_STORAGE *aqh;
|
||||
*
|
||||
* aqh=(AQHOME_STORAGE*) data;
|
||||
*/
|
||||
|
||||
DBG_INFO(NULL, "Incoming HTTP connection");
|
||||
epIncoming=GWEN_MsgEndpoint_new("http", 0);
|
||||
GWEN_MsgEndpoint_SetSocket(epIncoming, sk);
|
||||
GWEN_MsgIoEndpoint_Extend(epIncoming);
|
||||
AQH_HttpEndpoint_Extend(epIncoming, AQH_ENDPOINT_HTTP_FLAGS_PASSIVE);
|
||||
return epIncoming;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _createContentRoot(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
const char *sourceFolder;
|
||||
GWEN_BUFFER *nbuf1;
|
||||
GWEN_BUFFER *nbuf2;
|
||||
AQH_HTTP_CONTENT *c;
|
||||
|
||||
sourceFolder=AQH_HttpService_GetSourceFolder(aqh->httpService);
|
||||
|
||||
nbuf1=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
nbuf2=GWEN_Buffer_new(0, 256, 0, 1);
|
||||
|
||||
GWEN_Buffer_AppendString(nbuf1, sourceFolder);
|
||||
GWEN_Buffer_AppendString(nbuf1, GWEN_DIR_SEPARATOR_S AQHOME_STORAGE_SITEHEADER);
|
||||
|
||||
GWEN_Buffer_AppendString(nbuf2, sourceFolder);
|
||||
GWEN_Buffer_AppendString(nbuf2, GWEN_DIR_SEPARATOR_S AQHOME_STORAGE_SITEFOOTER);
|
||||
|
||||
c=AQH_HttpContentFiles_new("root", GWEN_Buffer_GetStart(nbuf1), GWEN_Buffer_GetStart(nbuf2));
|
||||
if (c==NULL) {
|
||||
DBG_INFO(NULL,
|
||||
"Unable to create content for root (header=[%s], footer=[%s])",
|
||||
GWEN_Buffer_GetStart(nbuf1), GWEN_Buffer_GetStart(nbuf2));
|
||||
GWEN_Buffer_free(nbuf2);
|
||||
GWEN_Buffer_free(nbuf1);
|
||||
return GWEN_ERROR_GENERIC;
|
||||
}
|
||||
AqHomeHttpService_SetContentTree(aqh->httpService, c);
|
||||
|
||||
GWEN_Buffer_free(nbuf2);
|
||||
GWEN_Buffer_free(nbuf1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _createUrlHandler_login(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
AQH_HTTP_URLHANDLER *uh;
|
||||
|
||||
uh=AQH_LoginHttpUrlHandler_new(aqh->httpService);
|
||||
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
|
||||
AQH_HttpUrlHandler_AddUrlPattern(uh, "/login");
|
||||
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _createUrlHandler_rooms(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
AQH_HTTP_URLHANDLER *uh;
|
||||
|
||||
uh=AQH_RoomsHttpUrlHandler_new(aqh->httpService);
|
||||
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
|
||||
AQH_HttpUrlHandler_AddUrlPattern(uh, "/rooms/*");
|
||||
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user