mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-29 12:41:03 +00:00
Merge pull request #3477 from cesanta/mem
Make packed fs always available, and manually settable
This commit is contained in:
83 files changed
+289
-8052
No files matched your search
+2
-3
@@ -1,6 +1,6 @@
|
||||
SRCS = mongoose.c unit_test.c packed_fs.c
|
||||
HDRS = $(wildcard ../src/*.h) $(wildcard ../src/drivers/*.h)
|
||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_SSI=1 -DMG_ENABLE_ASSERT=1
|
||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_SSI=1 -DMG_ENABLE_ASSERT=1
|
||||
WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef
|
||||
OPTS ?= -O3 -g3
|
||||
INCS ?= -Isrc -I.
|
||||
@@ -172,7 +172,7 @@ valgrind: Makefile mongoose.h $(SRCS)
|
||||
$(VALGRIND_RUN) ./unit_test
|
||||
|
||||
misra:
|
||||
cppcheck --addon=misra -DMG_ARCH=MG_ARCH_UNIX -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_SSI=1 mongoose.c >/tmp/x 2>&1
|
||||
cppcheck --addon=misra -DMG_ARCH=MG_ARCH_UNIX -DMG_ENABLE_SSI=1 mongoose.c >/tmp/x 2>&1
|
||||
cppcheck --addon=misra -DMG_ARCH=MG_ARCH_CUSTOM -DMG_ENABLE_LINES=1 -DTLS=MG_TLS_BUILTIN -DMG_ENABLE_TCPIP=1 mongoose.c >>/tmp/x 2>&1
|
||||
cppcheck --addon=misra --clang -DMG_ENABLE_LINES=1 -DTLS=MG_TLS_BUILTIN -DMG_ENABLE_TCPIP=1 mongoose.c >>/tmp/x 2>&1
|
||||
cppcheck --addon=misra --clang -DMG_ENABLE_LINES=1 -DMG_ENABLE_SSI=1 mongoose.c >>/tmp/x 2>&1
|
||||
@@ -285,4 +285,3 @@ tutorials_embedded:
|
||||
@for X in $(TUTORIALS_EMBEDDED); do test -f $$X/Makefile || continue; $(MAKE) -C $$X build || exit 1; done
|
||||
clean_tutorials_embedded:
|
||||
for X in $(TUTORIALS_EMBEDDED); do test -f $$X/Makefile || continue; $(MAKE) -C $$X clean || exit 1; done
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Build environment. Possible options are at https://github.com/cesanta/mongoose/blob/master/src/arch.h
|
||||
// #define MG_ARCH MG_ARCH_CUSTOM
|
||||
|
||||
// Choice of the network stack. By default, use an external BSD-compatible stack
|
||||
// #define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP
|
||||
// #define MG_ENABLE_LWIP 0 // lWIP
|
||||
// #define MG_ENABLE_TCPIP 0 // Mongoose built-in
|
||||
// #define MG_ENABLE_RL 0 // ARM MDK
|
||||
// #define MG_ENABLE_POLL 0 // Only for BSD stack. Use poll()
|
||||
// #define MG_ENABLE_EPOLL 0 // Only for Linux/BSD stack. Use epoll()
|
||||
// #define MG_ENABLE_WINSOCK 1 // Only for Windows stack. Use Winsock
|
||||
// #define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP
|
||||
// #define MG_SOCK_LISTEN_BACKLOG_SIZE 3 // Only for socket-based stacks
|
||||
|
||||
// Only for built-in network stack, MG_ENABLE_TCPIP == 1
|
||||
// #define MG_ENABLE_TCPIP_DRIVER_INIT 1 // enabled built-in driver for
|
||||
// #define MG_SET_MAC_ADDRESS(mac) // set MAC address for built-in driver
|
||||
// #define MG_SET_WIFI_CONFIG(data)
|
||||
// #define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0
|
||||
|
||||
// Choose a driver for built-in network stack, MG_ENABLE_TCPIP == 1
|
||||
// #define MG_ENABLE_DRIVER_STM32H 0
|
||||
// #define MG_ENABLE_DRIVER_STM32F 0
|
||||
// #define MG_ENABLE_DRIVER_IMXRT 0
|
||||
// #define MG_ENABLE_DRIVER_CMSIS 0
|
||||
// #define MG_ENABLE_DRIVER_RA 0
|
||||
// #define MG_ENABLE_DRIVER_RW612 0
|
||||
// #define MG_ENABLE_DRIVER_SAME54 0
|
||||
// #define MG_ENABLE_DRIVER_MCXN 0
|
||||
// #define MG_ENABLE_DRIVER_TM4C 0
|
||||
// #define MG_ENABLE_DRIVER_TMS570 0
|
||||
// #define MG_ENABLE_DRIVER_XMC7 0
|
||||
// #define MG_ENABLE_DRIVER_XMC 0
|
||||
|
||||
// Filesystem support
|
||||
// #define MG_ENABLE_PACKED_FS 0 // Enable packed filesystem support
|
||||
// #define MG_ENABLE_FATFS 0 // Enable FATFS support, mg_fs_packed
|
||||
// #define MG_ENABLE_POSIX_FS 0 // Enable POSIX filesystem support, mg_fs_posix
|
||||
// #define MG_PATH_MAX 128 // Maximum path length
|
||||
// #define MG_DIRSEP '/' // Directory separator
|
||||
|
||||
// Misc options
|
||||
// #define MG_ENABLE_LOG 1 // Enable logging
|
||||
// #define MG_TLS MG_TLS_NONE // MG_TLS_NONE, MG_TLS_MBED, MG_TLS_OPENSSL, MG_TLS_CUSTOM
|
||||
// #define MG_ENABLE_IPV6 0 // Enable IPv6 support
|
||||
// #define MG_IPV6_V6ONLY 0 // IPv6 socket binds only to V6, not V4 address
|
||||
// #define MG_ENABLE_CUSTOM_CALLOC 0 // Set to 1 to let user define mg_calloc() and mg_free()
|
||||
// #define MG_ENABLE_CUSTOM_RANDOM 0 // Set to 1 to let user define mg_random()
|
||||
// #define MG_ENABLE_CUSTOM_MILLIS 0 // Set to 1 to let user define mg_millis()
|
||||
// #define MG_ENABLE_SSI 0 // Enable SSI support
|
||||
// #define MG_ENABLE_DIRLIST 0 // Enable directory listing
|
||||
// #define MG_IO_SIZE 512 // Granularity of the send/recv IO buffer growth
|
||||
// #define MG_MAX_RECV_SIZE (3UL * 1024UL * 1024UL) // Maximum recv IO buffer size
|
||||
// #define MG_DATA_SIZE 32 // struct mg_connection :: data size
|
||||
// #define MG_MAX_HTTP_HEADERS 30 // Maximum number of HTTP headers
|
||||
// #define MG_HTTP_INDEX "index.html" // Default HTTP index file
|
||||
// #define MG_ENABLE_LINES 0 // Show unamalgamated line numbers
|
||||
+3
-33
@@ -2,7 +2,7 @@
|
||||
// All rights reserved.
|
||||
|
||||
// This program is used to pack arbitrary data into a C binary. It takes
|
||||
// a list of files as an input, and produces a .c data file that contains
|
||||
// a list of files as an input, and produc es a .c data file that contains
|
||||
// contents of all these files as a collection of byte arrays.
|
||||
//
|
||||
// Usage:
|
||||
@@ -24,35 +24,12 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static const char *code =
|
||||
"static int scmp(const char *a, const char *b) {\n"
|
||||
" while (*a && (*a == *b)) a++, b++;\n"
|
||||
" return *(const unsigned char *) a - *(const unsigned char *) b;\n"
|
||||
"}\n"
|
||||
"const char *mg_unlist(size_t no) {\n"
|
||||
" return packed_files[no].name;\n"
|
||||
"}\n"
|
||||
"const char *mg_unpack(const char *name, size_t *size, time_t *mtime) {\n"
|
||||
" const struct packed_file *p;\n"
|
||||
" for (p = packed_files; p->name != NULL; p++) {\n"
|
||||
" if (scmp(p->name, name) != 0) continue;\n"
|
||||
" if (size != NULL) *size = p->size - 1;\n"
|
||||
" if (mtime != NULL) *mtime = p->mtime;\n"
|
||||
" return (const char *) p->data;\n"
|
||||
" }\n"
|
||||
" return NULL;\n"
|
||||
"}\n";
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i, j, ch;
|
||||
const char *strip_prefix = "";
|
||||
|
||||
printf("%s", "#include \"mongoose.h\"\n");
|
||||
printf("%s", "\n");
|
||||
printf("%s", "#if defined(__cplusplus)\nextern \"C\" {\n#endif\n");
|
||||
printf("%s", "const char *mg_unlist(size_t no);\n");
|
||||
printf("%s", "const char *mg_unpack(const char *, size_t *, time_t *);\n");
|
||||
printf("%s", "#if defined(__cplusplus)\n}\n#endif\n\n");
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-s") == 0) {
|
||||
@@ -79,18 +56,12 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
// Append zero byte at the end, to make text files appear in memory
|
||||
// as nul-terminated strings.
|
||||
// printf(" 0 // %.*s\n", (int) sizeof(ascii), ascii);
|
||||
printf(" 0 // %.*s\n};\n", j, ascii);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s", "\nstatic const struct packed_file {\n");
|
||||
printf("%s", " const char *name;\n");
|
||||
printf("%s", " const unsigned char *data;\n");
|
||||
printf("%s", " size_t size;\n");
|
||||
printf("%s", " time_t mtime;\n");
|
||||
printf("%s", "} packed_files[] = {\n");
|
||||
printf("%s", "\nconst struct mg_mem_file mg_packed_files[] = {\n");
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
struct stat st;
|
||||
@@ -102,12 +73,11 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
stat(argv[i], &st);
|
||||
if (strncmp(name, strip_prefix, n) == 0) name += n;
|
||||
printf(" {\"/%s\", v%d, sizeof(v%d), %lu},\n", name, i, i,
|
||||
printf(" {\"/%s\", v%d, sizeof(v%d) - 1, %lu},\n", name, i, i,
|
||||
(unsigned long) st.st_mtime);
|
||||
}
|
||||
printf("%s", " {NULL, NULL, 0, 0}\n");
|
||||
printf("%s", "};\n\n");
|
||||
printf("%s", code);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
+38
-98
@@ -1,103 +1,43 @@
|
||||
// Copyright (c) 2013-2024 Cesanta Software Limited
|
||||
|
||||
const Pack = async function(files) {
|
||||
let out = `// DO NOT EDIT. This file is generated
|
||||
#include "mongoose.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char *mg_unlist(size_t no);
|
||||
const char *mg_unpack(const char *, size_t *, time_t *);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
`;
|
||||
//const str2bytes = str => new TextEncoder().encode(str);
|
||||
let no = 1;
|
||||
for (const f of files) {
|
||||
let byteArray = new TextEncoder().encode(f.data);
|
||||
if (f.zip) {
|
||||
const cs = new CompressionStream('gzip');
|
||||
const writer = cs.writable.getWriter();
|
||||
writer.write(byteArray);
|
||||
writer.close();
|
||||
const resp = new Response(cs.readable);
|
||||
const arr = await resp.arrayBuffer();
|
||||
byteArray = new Uint8Array(arr);
|
||||
}
|
||||
const bytes = Array.from(byteArray);
|
||||
|
||||
// console.log(f.path, bytes);
|
||||
out += `
|
||||
static const unsigned char v${no}[] = {`;
|
||||
// concat(0) appends trailing 0, in order to make any file an asciz string
|
||||
out += bytes.concat(0).join(',');
|
||||
out +=`};`;
|
||||
no++;
|
||||
}
|
||||
|
||||
out += `
|
||||
|
||||
static const struct packed_file {
|
||||
const char *name;
|
||||
const unsigned char *data;
|
||||
size_t size;
|
||||
time_t mtime;
|
||||
} packed_files[] = {`;
|
||||
|
||||
no = 1;
|
||||
for (const f of files) {
|
||||
out += `
|
||||
{"/${f.path}${f.zip ? '.gz' : ''}", v${no}, sizeof(v${no}), 0},`;
|
||||
no++;
|
||||
}
|
||||
out +=`
|
||||
{NULL, NULL, 0, 0}
|
||||
};
|
||||
`;
|
||||
|
||||
out += `
|
||||
static int scmp(const char *a, const char *b) {
|
||||
while (*a && (*a == *b)) a++, b++;
|
||||
return *(const unsigned char *) a - *(const unsigned char *) b;
|
||||
}
|
||||
|
||||
const char *mg_unlist(size_t no) {
|
||||
return packed_files[no].name;
|
||||
}
|
||||
|
||||
const char *mg_unpack(const char *name, size_t *size, time_t *mtime) {
|
||||
const struct packed_file *p;
|
||||
for (p = packed_files; p->name != NULL; p++) {
|
||||
if (scmp(p->name, name) != 0) continue;
|
||||
if (size != NULL) *size = p->size - 1;
|
||||
if (mtime != NULL) *mtime = p->mtime;
|
||||
return (const char *) p->data;
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
`;
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
// Script entry point
|
||||
// Copyright (c) 2024 Cesanta Software Limited
|
||||
//
|
||||
// Utility that generates packed filesystem C file compatible with the
|
||||
// Mongoose Network Library, https://github.com/cesanta/mongoose
|
||||
//
|
||||
// Usage:
|
||||
// node pack.js FILE[:DESTINATION[:gzip]] ...
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const [, , ...args] = process.argv;
|
||||
const zlib = require('zlib');
|
||||
const argv = process.argv.slice(2);
|
||||
|
||||
const files = args.map(f => ({
|
||||
path: f,
|
||||
data: fs.readFileSync(f, 'utf8'),
|
||||
zip: !!f.match(/web_root\/.+/),
|
||||
}));
|
||||
// Convert each command-line arguments into [ DATA_ARRAY, STRUCT_INITIALIZER ]
|
||||
const entries = argv.map(function(filename, i) {
|
||||
const parts = filename.split(':');
|
||||
const stat = fs.statSync(parts[0]);
|
||||
const data = fs.readFileSync(parts[0], null);
|
||||
let bytes = Array.from(data);
|
||||
let destination = (parts[1] || parts[0]).replace(/^\.+[\/\\]*/, '');
|
||||
if (parts[2] == 'gzip') {
|
||||
bytes = Array.from(zlib.gzipSync(data));
|
||||
destination += '.gz';
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const text = await Pack(files);
|
||||
process.stdout.write(text);
|
||||
})();
|
||||
// concat(0) appends trailing 0, in order to make any file an asciz string
|
||||
return [
|
||||
`static const unsigned char v${i}[] = {${bytes.concat(0).join(',')}};`,
|
||||
` {"/${destination}", v${i}, sizeof(v${i}) - 1, ${parseInt(stat.mtimeMs / 1000)}}`,
|
||||
];
|
||||
});
|
||||
|
||||
process.stdout.write(`// DO NOT EDIT. This file is generated using this command:
|
||||
// ${process.argv.join(' ')}
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
${entries.map(x => x[0]).join('\n\n')}
|
||||
|
||||
const struct mg_mem_file mg_packed_files[] = {
|
||||
${entries.map(x => x[1]).join(',\n')},
|
||||
{NULL, NULL, 0, 0}
|
||||
};
|
||||
`);
|
||||
@@ -3211,6 +3211,7 @@ static void eh7(struct mg_connection *c, int ev, void *ev_data) {
|
||||
memset(&sopts, 0, sizeof(sopts));
|
||||
sopts.root_dir = "/";
|
||||
sopts.fs = &mg_fs_packed;
|
||||
mg_mem_files = mg_packed_files;
|
||||
mg_http_serve_dir(c, hm, &sopts);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user