mirror of
https://gitee.com/jiuyilian/embedded-framework.git
synced 2025-01-06 10:16:51 -05:00
230 lines
7.3 KiB
C++
230 lines
7.3 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;
|
|
constexpr int UNKNOWN_LENGTH = -1;
|
|
static void sigHandler(int signo)
|
|
{
|
|
LogInfo("Stop goahead web server.\n");
|
|
finished = 1;
|
|
}
|
|
static void CheckUploadDir(void)
|
|
{
|
|
const char *directory = GOAHEAD_UPLOAD_TMP_PATH;
|
|
if (access(directory, F_OK) != 0) {
|
|
int result = mkdir(directory, 0777);
|
|
|
|
if (result == 0) {
|
|
LogInfo("mkdir upload tmp path successfuly.\n");
|
|
}
|
|
else {
|
|
LogError("mkdir upload tmp path failed.\n");
|
|
}
|
|
}
|
|
|
|
const char *directory2 = GOAHEAD_UPLOAD_PATH;
|
|
if (access(directory2, F_OK) != 0) {
|
|
int result = mkdir(directory2, 0777);
|
|
|
|
if (result == 0) {
|
|
LogInfo("mkdir upload path successfuly.\n");
|
|
}
|
|
else {
|
|
LogError("mkdir upload path failed.\n");
|
|
}
|
|
}
|
|
}
|
|
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 void get_thumbnail_handle(const char *thumbnailUrl, void *context)
|
|
{
|
|
struct Webs *wp = (struct Webs *)context;
|
|
if (nullptr == thumbnailUrl) {
|
|
LogError("thumbnailUrl is nullptr.\n");
|
|
return;
|
|
}
|
|
FILE *file = nullptr;
|
|
unsigned char *buffer = nullptr;
|
|
size_t bytesRead = 0;
|
|
long int fsize = 0;
|
|
file = fopen(thumbnailUrl, "rb");
|
|
if (file == nullptr) {
|
|
LogError("Open picture failed[%s].\n", thumbnailUrl);
|
|
goto END;
|
|
}
|
|
fseek(file, 0, SEEK_END);
|
|
fsize = ftell(file);
|
|
rewind(file);
|
|
buffer = (unsigned char *)malloc(fsize);
|
|
if (!buffer) {
|
|
LogError("malloc failed.\n");
|
|
goto END;
|
|
}
|
|
|
|
while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0) {
|
|
websWriteBlock(wp, (cchar *)buffer, bytesRead);
|
|
}
|
|
|
|
END:
|
|
if (buffer) {
|
|
free(buffer);
|
|
}
|
|
if (file) {
|
|
fclose(file);
|
|
}
|
|
}
|
|
static bool AppRequestHandle(Webs *wp)
|
|
{
|
|
websSetStatus(wp, 200);
|
|
websWriteHeaders(wp, UNKNOWN_LENGTH, 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 = nullptr;
|
|
|
|
websSetStatus(wp, 200);
|
|
websWriteHeaders(wp, UNKNOWN_LENGTH, 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(GOAHEAD_UPLOAD_PATH "/%s", up->clientFilename);
|
|
if (rename(up->filename, upfile) < 0) {
|
|
error("Cannot rename uploaded file: %s to %s, errno %d", up->filename, upfile, errno);
|
|
}
|
|
LogInfo("Upload file:%s\n", upfile);
|
|
wfree(upfile);
|
|
upfile = nullptr;
|
|
}
|
|
gHttpHandle(wp->url, 0, response_handle, wp);
|
|
}
|
|
websDone(wp);
|
|
return 1;
|
|
}
|
|
static bool AppGetThumbnail(Webs *wp)
|
|
{
|
|
LogInfo("AppGetThumbnail url = %s\n", wp->url);
|
|
websSetStatus(wp, 200);
|
|
websWriteHeaders(wp, UNKNOWN_LENGTH, 0);
|
|
websWriteHeader(wp, "Content-Type", "image/jpeg");
|
|
websWriteEndHeaders(wp);
|
|
gHttpHandle(wp->url, 0, get_thumbnail_handle, wp);
|
|
websDone(wp);
|
|
return 1;
|
|
}
|
|
StatusCode WebServerInit(const WebServerParam webParam)
|
|
{
|
|
CheckUploadDir();
|
|
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);
|
|
LogInfo("GOAHEAD_CONFIG_FILE_PATH = %s\n", GOAHEAD_CONFIG_FILE_PATH);
|
|
LogInfo("listen = %s\n", listen);
|
|
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);
|
|
websDefineHandler("AppUploadHandle", 0, AppUploadHandle, 0, 0);
|
|
websAddRoute("/upload", "AppUploadHandle", 0);
|
|
websDefineHandler("AppGetThumbnail", 0, AppGetThumbnail, 0, 0);
|
|
websAddRoute("/app/getthumbnail", "AppGetThumbnail", 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);
|
|
} |