add a .clang-format file (#9154)

This commit is contained in:
Jorropo
2026-01-03 21:19:24 +01:00
committed by GitHub
parent abab6ce815
commit 0d11331d18
771 changed files with 77752 additions and 83184 deletions

View File

@@ -90,130 +90,126 @@ PiWebServerThread *piwebServerThread;
/**
* Return the filename extension
*/
const char *get_filename_ext(const char *path)
{
const char *dot = strrchr(path, '.');
if (!dot || dot == path)
return "*";
if (strchr(dot, '?') != NULL) {
//*strchr(dot, '?') = '\0';
const char *empty = "\0";
return empty;
}
return dot;
const char *get_filename_ext(const char *path) {
const char *dot = strrchr(path, '.');
if (!dot || dot == path)
return "*";
if (strchr(dot, '?') != NULL) {
//*strchr(dot, '?') = '\0';
const char *empty = "\0";
return empty;
}
return dot;
}
/**
* Streaming callback function to ease sending large files
*/
static ssize_t callback_static_file_stream(void *cls, uint64_t pos, char *buf, size_t max)
{
(void)(pos);
if (cls != NULL) {
return fread(buf, 1, max, (FILE *)cls);
} else {
return U_STREAM_END;
}
static ssize_t callback_static_file_stream(void *cls, uint64_t pos, char *buf, size_t max) {
(void)(pos);
if (cls != NULL) {
return fread(buf, 1, max, (FILE *)cls);
} else {
return U_STREAM_END;
}
}
/**
* Cleanup FILE* structure when streaming is complete
*/
static void callback_static_file_stream_free(void *cls)
{
if (cls != NULL) {
fclose((FILE *)cls);
}
static void callback_static_file_stream_free(void *cls) {
if (cls != NULL) {
fclose((FILE *)cls);
}
}
/**
* static file callback endpoint that delivers the content for WebServer calls
*/
int callback_static_file(const struct _u_request *request, struct _u_response *response, void *user_data)
{
size_t length;
FILE *f;
char *file_requested, *file_path, *url_dup_save, *real_path = NULL;
const char *content_type;
int callback_static_file(const struct _u_request *request, struct _u_response *response, void *user_data) {
size_t length;
FILE *f;
char *file_requested, *file_path, *url_dup_save, *real_path = NULL;
const char *content_type;
/*
* Comment this if statement if you don't access static files url from root dir, like /app
*/
if (request->callback_position > 0) {
return U_CALLBACK_CONTINUE;
} else if (user_data != NULL && (configWeb.files_path != NULL)) {
file_requested = o_strdup(request->http_url);
url_dup_save = file_requested;
/*
* Comment this if statement if you don't access static files url from root dir, like /app
*/
if (request->callback_position > 0) {
return U_CALLBACK_CONTINUE;
} else if (user_data != NULL && (configWeb.files_path != NULL)) {
file_requested = o_strdup(request->http_url);
url_dup_save = file_requested;
while (file_requested[0] == '/') {
file_requested++;
}
file_requested += o_strlen(configWeb.url_prefix);
while (file_requested[0] == '/') {
file_requested++;
}
if (strchr(file_requested, '#') != NULL) {
*strchr(file_requested, '#') = '\0';
}
if (strchr(file_requested, '?') != NULL) {
*strchr(file_requested, '?') = '\0';
}
if (file_requested == NULL || o_strlen(file_requested) == 0 || 0 == o_strcmp("/", file_requested)) {
o_free(url_dup_save);
url_dup_save = file_requested = o_strdup("index.html");
}
file_path = msprintf("%s/%s", configWeb.files_path, file_requested);
real_path = realpath(file_path, NULL);
if (0 == o_strncmp(configWeb.files_path, real_path, o_strlen(configWeb.files_path))) {
if (access(file_path, F_OK) != -1) {
f = fopen(file_path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
content_type = u_map_get_case(&configWeb.mime_types, get_filename_ext(file_requested));
if (content_type == NULL) {
content_type = u_map_get(&configWeb.mime_types, "*");
LOG_DEBUG("Static File Server - Unknown mime type for extension %s ", get_filename_ext(file_requested));
}
u_map_put(response->map_header, "Content-Type", content_type);
u_map_copy_into(response->map_header, &configWeb.map_header);
if (ulfius_set_stream_response(response, 200, callback_static_file_stream, callback_static_file_stream_free,
length, STATIC_FILE_CHUNK, f) != U_OK) {
LOG_DEBUG("callback_static_file - Error ulfius_set_stream_response");
}
}
} else {
if (configWeb.redirect_on_404 == NULL) {
ulfius_set_string_body_response(response, 404, "File not found");
} else {
ulfius_add_header_to_response(response, "Location", configWeb.redirect_on_404);
response->status = 302;
}
}
} else {
if (configWeb.redirect_on_404 == NULL) {
ulfius_set_string_body_response(response, 404, "File not found");
} else {
ulfius_add_header_to_response(response, "Location", configWeb.redirect_on_404);
response->status = 302;
}
}
o_free(file_path);
o_free(url_dup_save);
free(real_path); // realpath uses malloc
return U_CALLBACK_CONTINUE;
} else {
LOG_DEBUG("Static File Server - Error, user_data is NULL or inconsistent");
return U_CALLBACK_ERROR;
while (file_requested[0] == '/') {
file_requested++;
}
file_requested += o_strlen(configWeb.url_prefix);
while (file_requested[0] == '/') {
file_requested++;
}
if (strchr(file_requested, '#') != NULL) {
*strchr(file_requested, '#') = '\0';
}
if (strchr(file_requested, '?') != NULL) {
*strchr(file_requested, '?') = '\0';
}
if (file_requested == NULL || o_strlen(file_requested) == 0 || 0 == o_strcmp("/", file_requested)) {
o_free(url_dup_save);
url_dup_save = file_requested = o_strdup("index.html");
}
file_path = msprintf("%s/%s", configWeb.files_path, file_requested);
real_path = realpath(file_path, NULL);
if (0 == o_strncmp(configWeb.files_path, real_path, o_strlen(configWeb.files_path))) {
if (access(file_path, F_OK) != -1) {
f = fopen(file_path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
content_type = u_map_get_case(&configWeb.mime_types, get_filename_ext(file_requested));
if (content_type == NULL) {
content_type = u_map_get(&configWeb.mime_types, "*");
LOG_DEBUG("Static File Server - Unknown mime type for extension %s ", get_filename_ext(file_requested));
}
u_map_put(response->map_header, "Content-Type", content_type);
u_map_copy_into(response->map_header, &configWeb.map_header);
if (ulfius_set_stream_response(response, 200, callback_static_file_stream, callback_static_file_stream_free, length, STATIC_FILE_CHUNK,
f) != U_OK) {
LOG_DEBUG("callback_static_file - Error ulfius_set_stream_response");
}
}
} else {
if (configWeb.redirect_on_404 == NULL) {
ulfius_set_string_body_response(response, 404, "File not found");
} else {
ulfius_add_header_to_response(response, "Location", configWeb.redirect_on_404);
response->status = 302;
}
}
} else {
if (configWeb.redirect_on_404 == NULL) {
ulfius_set_string_body_response(response, 404, "File not found");
} else {
ulfius_add_header_to_response(response, "Location", configWeb.redirect_on_404);
response->status = 302;
}
}
o_free(file_path);
o_free(url_dup_save);
free(real_path); // realpath uses malloc
return U_CALLBACK_CONTINUE;
} else {
LOG_DEBUG("Static File Server - Error, user_data is NULL or inconsistent");
return U_CALLBACK_ERROR;
}
}
static void handleWebResponse() {}
@@ -222,316 +218,305 @@ static void handleWebResponse() {}
* Adapt the radioapi to the Webservice handleAPIv1ToRadio
* Trigger : WebGui(SAVE)->WebServcice->phoneApi
*/
int handleAPIv1ToRadio(const struct _u_request *req, struct _u_response *res, void *user_data)
{
LOG_DEBUG("handleAPIv1ToRadio web -> radio ");
int handleAPIv1ToRadio(const struct _u_request *req, struct _u_response *res, void *user_data) {
LOG_DEBUG("handleAPIv1ToRadio web -> radio ");
ulfius_add_header_to_response(res, "Content-Type", "application/x-protobuf");
ulfius_add_header_to_response(res, "Access-Control-Allow-Headers", "Content-Type");
ulfius_add_header_to_response(res, "Access-Control-Allow-Origin", "*");
ulfius_add_header_to_response(res, "Access-Control-Allow-Methods", "PUT, OPTIONS");
ulfius_add_header_to_response(res, "X-Protobuf-Schema",
"https://raw.githubusercontent.com/meshtastic/protobufs/master/meshtastic/mesh.proto");
ulfius_add_header_to_response(res, "Content-Type", "application/x-protobuf");
ulfius_add_header_to_response(res, "Access-Control-Allow-Headers", "Content-Type");
ulfius_add_header_to_response(res, "Access-Control-Allow-Origin", "*");
ulfius_add_header_to_response(res, "Access-Control-Allow-Methods", "PUT, OPTIONS");
ulfius_add_header_to_response(res, "X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/meshtastic/mesh.proto");
if (strcmp(req->http_verb, "OPTIONS") == 0) {
ulfius_set_response_properties(res, U_OPT_STATUS, 204);
return U_CALLBACK_COMPLETE;
}
byte buffer[MAX_TO_FROM_RADIO_SIZE];
size_t s = req->binary_body_length;
memcpy(buffer, req->binary_body, MAX_TO_FROM_RADIO_SIZE);
// FIXME* Problem with portdunio loosing mountpoint maybe because of running in a real sep. thread
portduinoVFS->mountpoint(configWeb.rootPath);
LOG_DEBUG("Received %d bytes from PUT request", s);
static_cast<HttpAPI *>(user_data)->handleToRadio(buffer, s);
LOG_DEBUG("end web->radio ");
if (strcmp(req->http_verb, "OPTIONS") == 0) {
ulfius_set_response_properties(res, U_OPT_STATUS, 204);
return U_CALLBACK_COMPLETE;
}
byte buffer[MAX_TO_FROM_RADIO_SIZE];
size_t s = req->binary_body_length;
memcpy(buffer, req->binary_body, MAX_TO_FROM_RADIO_SIZE);
// FIXME* Problem with portdunio loosing mountpoint maybe because of running in a real sep. thread
portduinoVFS->mountpoint(configWeb.rootPath);
LOG_DEBUG("Received %d bytes from PUT request", s);
static_cast<HttpAPI *>(user_data)->handleToRadio(buffer, s);
LOG_DEBUG("end web->radio ");
return U_CALLBACK_COMPLETE;
}
/*
* Adapt the radioapi to the Webservice handleAPIv1FromRadio
* Trigger : WebGui(POLL)->handleAPIv1FromRadio->phoneapi->Meshtastic(Radio) events
*/
int handleAPIv1FromRadio(const struct _u_request *req, struct _u_response *res, void *user_data)
{
int handleAPIv1FromRadio(const struct _u_request *req, struct _u_response *res, void *user_data) {
// LOG_DEBUG("handleAPIv1FromRadio radio -> web");
std::string valueAll;
// LOG_DEBUG("handleAPIv1FromRadio radio -> web");
std::string valueAll;
// Status code is 200 OK by default.
ulfius_add_header_to_response(res, "Content-Type", "application/x-protobuf");
ulfius_add_header_to_response(res, "Access-Control-Allow-Origin", "*");
ulfius_add_header_to_response(res, "Access-Control-Allow-Methods", "GET");
ulfius_add_header_to_response(res, "X-Protobuf-Schema",
"https://raw.githubusercontent.com/meshtastic/protobufs/master/meshtastic/mesh.proto");
// Status code is 200 OK by default.
ulfius_add_header_to_response(res, "Content-Type", "application/x-protobuf");
ulfius_add_header_to_response(res, "Access-Control-Allow-Origin", "*");
ulfius_add_header_to_response(res, "Access-Control-Allow-Methods", "GET");
ulfius_add_header_to_response(res, "X-Protobuf-Schema", "https://raw.githubusercontent.com/meshtastic/protobufs/master/meshtastic/mesh.proto");
if (strcmp(req->http_verb, "OPTIONS") == 0) {
ulfius_set_response_properties(res, U_OPT_STATUS, 204);
return U_CALLBACK_COMPLETE;
}
uint8_t txBuf[MAX_STREAM_BUF_SIZE];
uint32_t len = 1;
if (valueAll == "true") {
while (len) {
len = static_cast<HttpAPI *>(user_data)->getFromRadio(txBuf);
ulfius_set_response_properties(res, U_OPT_STATUS, 200, U_OPT_BINARY_BODY, txBuf, len);
const char *tmpa = (const char *)txBuf;
ulfius_set_string_body_response(res, 200, tmpa);
// LOG_DEBUG("\n----webAPI response all:----");
// LOG_DEBUG(tmpa);
// LOG_DEBUG("");
}
// Otherwise, just return one protobuf
} else {
len = static_cast<HttpAPI *>(user_data)->getFromRadio(txBuf);
const char *tmpa = (const char *)txBuf;
ulfius_set_binary_body_response(res, 200, tmpa, len);
// LOG_DEBUG("\n----webAPI response:");
// LOG_DEBUG(tmpa);
// LOG_DEBUG("");
}
// LOG_DEBUG("end radio->web", len);
if (strcmp(req->http_verb, "OPTIONS") == 0) {
ulfius_set_response_properties(res, U_OPT_STATUS, 204);
return U_CALLBACK_COMPLETE;
}
uint8_t txBuf[MAX_STREAM_BUF_SIZE];
uint32_t len = 1;
if (valueAll == "true") {
while (len) {
len = static_cast<HttpAPI *>(user_data)->getFromRadio(txBuf);
ulfius_set_response_properties(res, U_OPT_STATUS, 200, U_OPT_BINARY_BODY, txBuf, len);
const char *tmpa = (const char *)txBuf;
ulfius_set_string_body_response(res, 200, tmpa);
// LOG_DEBUG("\n----webAPI response all:----");
// LOG_DEBUG(tmpa);
// LOG_DEBUG("");
}
// Otherwise, just return one protobuf
} else {
len = static_cast<HttpAPI *>(user_data)->getFromRadio(txBuf);
const char *tmpa = (const char *)txBuf;
ulfius_set_binary_body_response(res, 200, tmpa, len);
// LOG_DEBUG("\n----webAPI response:");
// LOG_DEBUG(tmpa);
// LOG_DEBUG("");
}
// LOG_DEBUG("end radio->web", len);
return U_CALLBACK_COMPLETE;
}
/*
OpenSSL RSA Key Gen
*/
int generate_rsa_key(EVP_PKEY **pkey)
{
EVP_PKEY_CTX *pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
if (!pkey_ctx)
return -1;
if (EVP_PKEY_keygen_init(pkey_ctx) <= 0)
return -1;
if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, 2048) <= 0)
return -1;
if (EVP_PKEY_keygen(pkey_ctx, pkey) <= 0)
return -1;
EVP_PKEY_CTX_free(pkey_ctx);
return 0; // SUCCESS
int generate_rsa_key(EVP_PKEY **pkey) {
EVP_PKEY_CTX *pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
if (!pkey_ctx)
return -1;
if (EVP_PKEY_keygen_init(pkey_ctx) <= 0)
return -1;
if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, 2048) <= 0)
return -1;
if (EVP_PKEY_keygen(pkey_ctx, pkey) <= 0)
return -1;
EVP_PKEY_CTX_free(pkey_ctx);
return 0; // SUCCESS
}
int generate_self_signed_x509(EVP_PKEY *pkey, X509 **x509)
{
*x509 = X509_new();
if (!*x509)
return -1;
if (X509_set_version(*x509, 2) != 1)
return -1;
ASN1_INTEGER_set(X509_get_serialNumber(*x509), 1);
X509_gmtime_adj(X509_get_notBefore(*x509), 0);
X509_gmtime_adj(X509_get_notAfter(*x509), 31536000L); // 1 YEAR ACCESS
int generate_self_signed_x509(EVP_PKEY *pkey, X509 **x509) {
*x509 = X509_new();
if (!*x509)
return -1;
if (X509_set_version(*x509, 2) != 1)
return -1;
ASN1_INTEGER_set(X509_get_serialNumber(*x509), 1);
X509_gmtime_adj(X509_get_notBefore(*x509), 0);
X509_gmtime_adj(X509_get_notAfter(*x509), 31536000L); // 1 YEAR ACCESS
X509_set_pubkey(*x509, pkey);
X509_set_pubkey(*x509, pkey);
// SET Subject Name
X509_NAME *name = X509_get_subject_name(*x509);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"DE", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"Meshtastic", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"meshtastic.local", -1, -1, 0);
// Selfsigned, Issuer = Subject
X509_set_issuer_name(*x509, name);
// SET Subject Name
X509_NAME *name = X509_get_subject_name(*x509);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"DE", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"Meshtastic", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"meshtastic.local", -1, -1, 0);
// Selfsigned, Issuer = Subject
X509_set_issuer_name(*x509, name);
// Certificate signed with our privte key
if (X509_sign(*x509, pkey, EVP_sha256()) <= 0)
return -1;
// Certificate signed with our privte key
if (X509_sign(*x509, pkey, EVP_sha256()) <= 0)
return -1;
return 0;
return 0;
}
char *read_file_into_string(const char *filename)
{
FILE *file = fopen(filename, "rb");
if (file == NULL) {
LOG_ERROR("Error reading File : %s ", filename);
return NULL;
}
char *read_file_into_string(const char *filename) {
FILE *file = fopen(filename, "rb");
if (file == NULL) {
LOG_ERROR("Error reading File : %s ", filename);
return NULL;
}
// Size of file
fseek(file, 0, SEEK_END);
long filesize = ftell(file);
rewind(file);
// Size of file
fseek(file, 0, SEEK_END);
long filesize = ftell(file);
rewind(file);
// reserve mem for file + 1 byte
char *buffer = (char *)malloc(filesize + 1);
if (buffer == NULL) {
LOG_ERROR("Malloc of mem failed for file : %s ", filename);
fclose(file);
return NULL;
}
// read content
size_t readSize = fread(buffer, 1, filesize, file);
if (readSize != filesize) {
LOG_ERROR("Error reading file into buffer");
free(buffer);
fclose(file);
return NULL;
}
// add terminator sign at the end
buffer[filesize] = '\0';
// reserve mem for file + 1 byte
char *buffer = (char *)malloc(filesize + 1);
if (buffer == NULL) {
LOG_ERROR("Malloc of mem failed for file : %s ", filename);
fclose(file);
return buffer; // return pointer
return NULL;
}
// read content
size_t readSize = fread(buffer, 1, filesize, file);
if (readSize != filesize) {
LOG_ERROR("Error reading file into buffer");
free(buffer);
fclose(file);
return NULL;
}
// add terminator sign at the end
buffer[filesize] = '\0';
fclose(file);
return buffer; // return pointer
}
int PiWebServerThread::CheckSSLandLoad()
{
// read certificate
cert_pem = read_file_into_string(CERT_PATH);
if (cert_pem == NULL) {
LOG_ERROR("ERROR SSL Certificate File can't be loaded or is missing");
return 1;
}
// read private key
key_pem = read_file_into_string(KEY_PATH);
if (key_pem == NULL) {
LOG_ERROR("ERROR file private_key can't be loaded or is missing");
return 2;
}
int PiWebServerThread::CheckSSLandLoad() {
// read certificate
cert_pem = read_file_into_string(CERT_PATH);
if (cert_pem == NULL) {
LOG_ERROR("ERROR SSL Certificate File can't be loaded or is missing");
return 1;
}
// read private key
key_pem = read_file_into_string(KEY_PATH);
if (key_pem == NULL) {
LOG_ERROR("ERROR file private_key can't be loaded or is missing");
return 2;
}
return 0;
return 0;
}
int PiWebServerThread::CreateSSLCertificate()
{
int PiWebServerThread::CreateSSLCertificate() {
EVP_PKEY *pkey = NULL;
X509 *x509 = NULL;
EVP_PKEY *pkey = NULL;
X509 *x509 = NULL;
if (generate_rsa_key(&pkey) != 0) {
LOG_ERROR("Error generating RSA-Key");
return 1;
}
if (generate_rsa_key(&pkey) != 0) {
LOG_ERROR("Error generating RSA-Key");
return 1;
}
if (generate_self_signed_x509(pkey, &x509) != 0) {
LOG_ERROR("Error generating X509-Cert");
return 2;
}
if (generate_self_signed_x509(pkey, &x509) != 0) {
LOG_ERROR("Error generating X509-Cert");
return 2;
}
// Open file to write private key file
FILE *pkey_file = fopen(KEY_PATH, "wb");
if (!pkey_file) {
LOG_ERROR("Error opening private key file");
return 3;
}
// write private key file
PEM_write_PrivateKey(pkey_file, pkey, NULL, NULL, 0, NULL, NULL);
fclose(pkey_file);
// Open file to write private key file
FILE *pkey_file = fopen(KEY_PATH, "wb");
if (!pkey_file) {
LOG_ERROR("Error opening private key file");
return 3;
}
// write private key file
PEM_write_PrivateKey(pkey_file, pkey, NULL, NULL, 0, NULL, NULL);
fclose(pkey_file);
// open Certificate file
FILE *x509_file = fopen(CERT_PATH, "wb");
if (!x509_file) {
LOG_ERROR("Error opening cert");
return 4;
}
// write certificate
PEM_write_X509(x509_file, x509);
fclose(x509_file);
// open Certificate file
FILE *x509_file = fopen(CERT_PATH, "wb");
if (!x509_file) {
LOG_ERROR("Error opening cert");
return 4;
}
// write certificate
PEM_write_X509(x509_file, x509);
fclose(x509_file);
EVP_PKEY_free(pkey);
LOG_INFO("Create SSL Key %s successful", KEY_PATH);
X509_free(x509);
LOG_INFO("Create SSL Cert %s successful", CERT_PATH);
return 0;
EVP_PKEY_free(pkey);
LOG_INFO("Create SSL Key %s successful", KEY_PATH);
X509_free(x509);
LOG_INFO("Create SSL Cert %s successful", CERT_PATH);
return 0;
}
void initWebServer() {}
PiWebServerThread::PiWebServerThread()
{
int ret, retssl, webservport;
PiWebServerThread::PiWebServerThread() {
int ret, retssl, webservport;
if (CheckSSLandLoad() != 0) {
CreateSSLCertificate();
if (CheckSSLandLoad() != 0) {
CreateSSLCertificate();
if (CheckSSLandLoad() != 0) {
LOG_ERROR("Major Error Gen & Read SSL Certificate");
}
LOG_ERROR("Major Error Gen & Read SSL Certificate");
}
}
if (portduino_config.webserverport != 0) {
webservport = portduino_config.webserverport;
LOG_INFO("Use webserver port from yaml config %i ", webservport);
if (portduino_config.webserverport != 0) {
webservport = portduino_config.webserverport;
LOG_INFO("Use webserver port from yaml config %i ", webservport);
} else {
LOG_INFO("Webserver port in yaml config set to 0, defaulting to port 9443");
webservport = 9443;
}
// Web Content Service Instance
if (ulfius_init_instance(&instanceWeb, webservport, NULL, DEFAULT_REALM) != U_OK) {
LOG_ERROR("Webserver couldn't be started, abort execution");
} else {
LOG_INFO("Webserver started");
u_map_init(&configWeb.mime_types);
u_map_put(&configWeb.mime_types, "*", "application/octet-stream");
u_map_put(&configWeb.mime_types, ".html", "text/html");
u_map_put(&configWeb.mime_types, ".htm", "text/html");
u_map_put(&configWeb.mime_types, ".tsx", "application/javascript");
u_map_put(&configWeb.mime_types, ".ts", "application/javascript");
u_map_put(&configWeb.mime_types, ".css", "text/css");
u_map_put(&configWeb.mime_types, ".js", "application/javascript");
u_map_put(&configWeb.mime_types, ".json", "application/json");
u_map_put(&configWeb.mime_types, ".png", "image/png");
u_map_put(&configWeb.mime_types, ".gif", "image/gif");
u_map_put(&configWeb.mime_types, ".jpeg", "image/jpeg");
u_map_put(&configWeb.mime_types, ".jpg", "image/jpeg");
u_map_put(&configWeb.mime_types, ".ttf", "font/ttf");
u_map_put(&configWeb.mime_types, ".woff", "font/woff");
u_map_put(&configWeb.mime_types, ".ico", "image/x-icon");
u_map_put(&configWeb.mime_types, ".svg", "image/svg+xml");
webrootpath = portduino_config.webserver_root_path;
configWeb.files_path = (char *)webrootpath.c_str();
configWeb.url_prefix = "";
configWeb.rootPath = strdup(portduinoVFS->mountpoint());
u_map_put(instanceWeb.default_headers, "Access-Control-Allow-Origin", "*");
// Maximum body size sent by the client is 1 Kb
instanceWeb.max_post_body_size = 1024;
ulfius_add_endpoint_by_val(&instanceWeb, "GET", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, &webAPI);
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, &webAPI);
ulfius_add_endpoint_by_val(&instanceWeb, "PUT", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, &webAPI);
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, &webAPI);
// Add callback function to all endpoints for the Web Server
ulfius_add_endpoint_by_val(&instanceWeb, "GET", NULL, "/*", 2, &callback_static_file, &configWeb);
// thats for serving without SSL
// retssl = ulfius_start_framework(&instanceWeb);
// thats for serving with SSL
retssl = ulfius_start_secure_framework(&instanceWeb, key_pem, cert_pem);
if (retssl == U_OK) {
LOG_INFO("Web Server framework started on port: %i ", webservport);
LOG_INFO("Web Server root %s", (char *)webrootpath.c_str());
} else {
LOG_INFO("Webserver port in yaml config set to 0, defaulting to port 9443");
webservport = 9443;
}
// Web Content Service Instance
if (ulfius_init_instance(&instanceWeb, webservport, NULL, DEFAULT_REALM) != U_OK) {
LOG_ERROR("Webserver couldn't be started, abort execution");
} else {
LOG_INFO("Webserver started");
u_map_init(&configWeb.mime_types);
u_map_put(&configWeb.mime_types, "*", "application/octet-stream");
u_map_put(&configWeb.mime_types, ".html", "text/html");
u_map_put(&configWeb.mime_types, ".htm", "text/html");
u_map_put(&configWeb.mime_types, ".tsx", "application/javascript");
u_map_put(&configWeb.mime_types, ".ts", "application/javascript");
u_map_put(&configWeb.mime_types, ".css", "text/css");
u_map_put(&configWeb.mime_types, ".js", "application/javascript");
u_map_put(&configWeb.mime_types, ".json", "application/json");
u_map_put(&configWeb.mime_types, ".png", "image/png");
u_map_put(&configWeb.mime_types, ".gif", "image/gif");
u_map_put(&configWeb.mime_types, ".jpeg", "image/jpeg");
u_map_put(&configWeb.mime_types, ".jpg", "image/jpeg");
u_map_put(&configWeb.mime_types, ".ttf", "font/ttf");
u_map_put(&configWeb.mime_types, ".woff", "font/woff");
u_map_put(&configWeb.mime_types, ".ico", "image/x-icon");
u_map_put(&configWeb.mime_types, ".svg", "image/svg+xml");
webrootpath = portduino_config.webserver_root_path;
configWeb.files_path = (char *)webrootpath.c_str();
configWeb.url_prefix = "";
configWeb.rootPath = strdup(portduinoVFS->mountpoint());
u_map_put(instanceWeb.default_headers, "Access-Control-Allow-Origin", "*");
// Maximum body size sent by the client is 1 Kb
instanceWeb.max_post_body_size = 1024;
ulfius_add_endpoint_by_val(&instanceWeb, "GET", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, &webAPI);
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/fromradio/*", 1, &handleAPIv1FromRadio, &webAPI);
ulfius_add_endpoint_by_val(&instanceWeb, "PUT", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, &webAPI);
ulfius_add_endpoint_by_val(&instanceWeb, "OPTIONS", PREFIX, "/api/v1/toradio/*", 1, &handleAPIv1ToRadio, &webAPI);
// Add callback function to all endpoints for the Web Server
ulfius_add_endpoint_by_val(&instanceWeb, "GET", NULL, "/*", 2, &callback_static_file, &configWeb);
// thats for serving without SSL
// retssl = ulfius_start_framework(&instanceWeb);
// thats for serving with SSL
retssl = ulfius_start_secure_framework(&instanceWeb, key_pem, cert_pem);
if (retssl == U_OK) {
LOG_INFO("Web Server framework started on port: %i ", webservport);
LOG_INFO("Web Server root %s", (char *)webrootpath.c_str());
} else {
LOG_ERROR("Error starting Web Server framework, error number: %d", retssl);
}
LOG_ERROR("Error starting Web Server framework, error number: %d", retssl);
}
}
}
PiWebServerThread::~PiWebServerThread()
{
u_map_clean(&configWeb.mime_types);
PiWebServerThread::~PiWebServerThread() {
u_map_clean(&configWeb.mime_types);
ulfius_stop_framework(&instanceWeb);
ulfius_clean_instance(&instanceWeb);
free(configWeb.rootPath);
free(key_pem);
free(cert_pem);
LOG_INFO("End framework");
ulfius_stop_framework(&instanceWeb);
ulfius_clean_instance(&instanceWeb);
free(configWeb.rootPath);
free(key_pem);
free(cert_pem);
LOG_INFO("End framework");
}
#endif

View File

@@ -15,44 +15,42 @@ int callback_static_file(const struct _u_request *request, struct _u_response *r
const char *get_filename_ext(const char *path);
struct _file_config {
char *files_path;
char *url_prefix;
struct _u_map mime_types;
struct _u_map map_header;
char *redirect_on_404;
char *rootPath;
char *files_path;
char *url_prefix;
struct _u_map mime_types;
struct _u_map map_header;
char *redirect_on_404;
char *rootPath;
};
class HttpAPI : public PhoneAPI
{
class HttpAPI : public PhoneAPI {
public:
HttpAPI() { api_type = TYPE_HTTP; }
public:
HttpAPI() { api_type = TYPE_HTTP; }
private:
// Nothing here yet
private:
// Nothing here yet
protected:
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
protected:
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
};
class PiWebServerThread
{
private:
char *key_pem = NULL;
char *cert_pem = NULL;
// struct _u_map mime_types;
std::string webrootpath;
HttpAPI webAPI;
class PiWebServerThread {
private:
char *key_pem = NULL;
char *cert_pem = NULL;
// struct _u_map mime_types;
std::string webrootpath;
HttpAPI webAPI;
public:
PiWebServerThread();
~PiWebServerThread();
int CreateSSLCertificate();
int CheckSSLandLoad();
uint32_t requestRestart = 0;
struct _u_instance instanceWeb;
public:
PiWebServerThread();
~PiWebServerThread();
int CreateSSLCertificate();
int CheckSSLandLoad();
uint32_t requestRestart = 0;
struct _u_instance instanceWeb;
};
extern PiWebServerThread *piwebServerThread;