150 lines
5.0 KiB
C++
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);
|
|
} |