hunting/utils/WebServer/src/WebServer.cpp
2024-03-02 21:53:28 -08:00

150 lines
5.0 KiB
C++

/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "WebServer.h"
#include "ILog.h"
#include "goahead.h"
#include "js.h"
#include <signal.h>
static int finished = 0;
static HttpHandleCallback gHttpHandle = NULL;
static void sigHandler(int signo)
{
LogInfo("Stop goahead web server.\n");
finished = 1;
}
static void logHeader(void)
{
char home[ME_GOAHEAD_LIMIT_STRING];
char *result = getcwd(home, sizeof(home));
if (nullptr == result) {
LogWarning("Can't get path.\n");
}
logmsg(2, "Configuration for %s", ME_TITLE);
logmsg(2, "---------------------------------------------");
logmsg(2, "Version: %s", ME_VERSION);
logmsg(2, "BuildType: %s", ME_DEBUG ? "Debug" : "Release");
logmsg(2, "CPU: %s", ME_CPU);
logmsg(2, "OS: %s", ME_OS);
logmsg(2, "Host: %s", websGetServer());
logmsg(2, "Directory: %s", home);
logmsg(2, "Documents: %s", websGetDocuments());
logmsg(2, "Configure: %s", ME_CONFIG_CMD);
logmsg(2, "---------------------------------------------");
}
void initPlatform(void)
{
signal(SIGINT, sigHandler);
signal(SIGTERM, sigHandler);
signal(SIGKILL, sigHandler);
signal(SIGPIPE, SIG_IGN);
}
static void response_handle(const char *responseStr, void *context)
{
struct Webs *wp = (struct Webs *)context;
if (NULL != responseStr) {
websWrite(wp, "%s", responseStr);
}
}
static bool AppRequestHandle(Webs *wp)
{
websSetStatus(wp, 200);
websWriteHeaders(wp, -1, 0);
websWriteHeader(wp, "Content-Type", "text/plain");
websWriteEndHeaders(wp);
gHttpHandle(wp->url, 0, response_handle, wp);
websDone(wp);
return 1;
}
static bool AppUploadHandle(Webs *wp)
{
WebsKey *s;
WebsUpload *up;
char *upfile;
websSetStatus(wp, 200);
websWriteHeaders(wp, -1, 0);
websWriteHeader(wp, "Content-Type", "text/plain");
websWriteEndHeaders(wp);
if (scaselessmatch(wp->method, "POST")) {
for (s = hashFirst(wp->files); s; s = hashNext(wp->files, s)) {
up = (WebsUpload *)s->content.value.symbol;
LogInfo("FILE: %s\r\n", s->name.value.string);
LogInfo("FILENAME=%s\r\n", up->filename);
LogInfo("CLIENT=%s\r\n", up->clientFilename);
LogInfo("TYPE=%s\r\n", up->contentType);
LogInfo("SIZE=%d\r\n", up->size);
upfile = sfmt("%s/tmp/%s", websGetDocuments(), up->clientFilename);
if (rename(up->filename, upfile) < 0) {
error("Cannot rename uploaded file: %s to %s, errno %d", up->filename, upfile, errno);
}
wfree(upfile);
}
gHttpHandle(wp->url, 0, response_handle, wp);
}
websDone(wp);
return 1;
}
StatusCode WebServerInit(const WebServerParam webParam)
{
websSetDebug(1);
logSetPath("stdout:2");
const char *documents = GOAHEAD_DOCUMENTS_PATH;
constexpr int BUF_LENGTH = 128;
char routePath[BUF_LENGTH] = {0};
char authPath[BUF_LENGTH] = {0};
char listen[BUF_LENGTH] = {0};
snprintf(routePath, BUF_LENGTH, "%s/route.txt", GOAHEAD_CONFIG_FILE_PATH);
snprintf(authPath, BUF_LENGTH, "%s/auth.txt", GOAHEAD_CONFIG_FILE_PATH);
snprintf(listen, BUF_LENGTH, "%s:%d", webParam.mIp, webParam.mPort);
initPlatform();
if (websOpen(documents, routePath) < 0) {
LogError("Cannot initialize server. Exiting.\n");
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
logHeader();
if (websLoad(authPath) < 0) {
LogError("Cannot load %s", authPath);
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
if (websListen(listen) < 0) {
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
if (nullptr != webParam.mHttpRequestHandle) {
gHttpHandle = webParam.mHttpRequestHandle;
websDefineHandler("appRequestHandle", 0, AppRequestHandle, 0, 0);
websAddRoute("/app", "appRequestHandle", 0);
}
if (nullptr != webParam.mHttpRequestHandle) {
websDefineHandler("AppUploadHandle", 0, AppUploadHandle, 0, 0);
websAddRoute("/upload", "AppUploadHandle", 0);
}
websServiceEvents(&finished);
logmsg(1, "Instructed to exit\n");
websClose();
return CreateStatusCode(STATUS_CODE_OK);
}
StatusCode WebServerExit(void)
{
LogInfo("Stop goahead web server.\n");
finished = 1;
return CreateStatusCode(STATUS_CODE_OK);
}
StatusCode WebServerUnInit(void)
{
LogInfo("WebServerUnInit.\n");
return CreateStatusCode(STATUS_CODE_OK);
}