mirror of
https://github.com/cesanta/mongoose.git
synced 2025-01-14 01:38:01 +08:00
Better packed test
This commit is contained in:
parent
2af5d07467
commit
3a46055e52
39
Makefile
39
Makefile
@ -1,6 +1,6 @@
|
||||
SRCS = mongoose.c test/unit_test.c test/packed_fs.c
|
||||
HDRS = $(wildcard src/*.h)
|
||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES
|
||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1
|
||||
WARN ?= -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion
|
||||
OPTS ?= -O3 -g3
|
||||
INCS ?= -Isrc -I.
|
||||
@ -27,14 +27,14 @@ CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
|
||||
LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto
|
||||
endif
|
||||
|
||||
all: mg_prefix test test++ arm examples vc98 vc2017 mingw mingw++ linux linux++ fuzz
|
||||
all: mg_prefix unpacked test test++ arm examples vc98 vc2017 mingw mingw++ linux linux++ fuzz
|
||||
|
||||
examples:
|
||||
@for X in $(EXAMPLES); do $(MAKE) -C $$X example || break; done
|
||||
|
||||
test/packed_fs.c:
|
||||
$(CC) $(CFLAGS) examples/complete/pack.c -o pack
|
||||
./pack Makefile > $@
|
||||
test/packed_fs.c: Makefile src/fs.h src/ssi.h test/fuzz.c test/data/a.txt
|
||||
$(CC) $(CFLAGS) test/pack.c -o pack
|
||||
./pack $? > $@
|
||||
|
||||
# Check that all external (exported) symbols have "mg_" prefix
|
||||
mg_prefix: mongoose.c mongoose.h
|
||||
@ -49,8 +49,11 @@ test++: test
|
||||
unamalgamated: $(HDRS) Makefile
|
||||
$(CC) src/*.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -g -o unit_test
|
||||
|
||||
unpacked:
|
||||
$(CC) -I. mongoose.c test/unit_test.c -o unit_test
|
||||
|
||||
fuzzer: mongoose.c mongoose.h Makefile test/fuzz.c
|
||||
clang mongoose.c test/fuzz.c $(CFLAGS) -DMG_ENABLE_LINES -DMG_ENABLE_LOG=0 -fsanitize=fuzzer,signed-integer-overflow,address $(LDFLAGS) -g -o $@
|
||||
clang mongoose.c test/fuzz.c $(WARN) $(INCS) -DMG_ENABLE_LINES -DMG_ENABLE_LOG=0 -fsanitize=fuzzer,signed-integer-overflow,address -g -o $@
|
||||
|
||||
fuzz: fuzzer
|
||||
$(RUN) ./fuzzer
|
||||
@ -72,33 +75,33 @@ infer:
|
||||
infer run -- cc test/unit_test.c -c -W -Wall -Werror -Isrc -I. -O2 -DMG_ENABLE_MBEDTLS=1 -DMG_ENABLE_LINES -I/usr/local/Cellar/mbedtls/2.23.0/include -DMG_ENABLE_IPV6=1 -g -o /dev/null
|
||||
|
||||
arm: mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/armgcc arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $(SRCS) test/mongoose_custom.c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES=1 -o unit_test -nostartfiles --specs nosys.specs -e 0
|
||||
$(DOCKER) mdashnet/armgcc arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $(SRCS) test/mongoose_custom.c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) $(DEFS) -o unit_test -nostartfiles --specs nosys.specs -e 0
|
||||
|
||||
riscv: mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) test/mongoose_custom.c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES=1 -o unit_test
|
||||
$(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) test/mongoose_custom.c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) $(DEFS) -o unit_test
|
||||
|
||||
#vc98: VCFLAGS += -DMG_ENABLE_IPV6=1
|
||||
vc98: Makefile mongoose.c mongoose.h test/unit_test.c
|
||||
$(DOCKER) mdashnet/vc98 wine cl mongoose.c test/unit_test.c $(VCFLAGS) ws2_32.lib /Fe$@.exe
|
||||
vc98: Makefile mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/vc98 wine cl $(SRCS) $(VCFLAGS) ws2_32.lib /Fe$@.exe
|
||||
$(DOCKER) mdashnet/vc98 wine $@.exe
|
||||
|
||||
#vc2017: VCFLAGS += -DMG_ENABLE_IPV6=1
|
||||
vc2017: Makefile mongoose.c mongoose.h test/unit_test.c
|
||||
$(DOCKER) mdashnet/vc2017 wine64 cl mongoose.c test/unit_test.c $(VCFLAGS) ws2_32.lib /Fe$@.exe
|
||||
vc2017: Makefile mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/vc2017 wine64 cl $(SRCS) $(VCFLAGS) ws2_32.lib /Fe$@.exe
|
||||
$(DOCKER) mdashnet/vc2017 wine64 $@.exe
|
||||
|
||||
mingw: Makefile mongoose.c mongoose.h test/unit_test.c
|
||||
$(DOCKER) mdashnet/mingw i686-w64-mingw32-gcc mongoose.c test/unit_test.c -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe
|
||||
mingw: Makefile mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/mingw i686-w64-mingw32-gcc $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe
|
||||
$(DOCKER) mdashnet/vc98 wine test.exe
|
||||
|
||||
mingw++: Makefile mongoose.c mongoose.h test/unit_test.c
|
||||
$(DOCKER) mdashnet/mingw i686-w64-mingw32-g++ mongoose.c test/unit_test.c -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe
|
||||
mingw++: Makefile mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/mingw i686-w64-mingw32-g++ $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe
|
||||
# Note: for some reason, a binary built with mingw g++, fails to run
|
||||
|
||||
#linux: CFLAGS += -DMG_ENABLE_IPV6=$(IPV6)
|
||||
linux: CFLAGS += -fsanitize=address,undefined
|
||||
linux: Makefile mongoose.c mongoose.h test/unit_test.c
|
||||
$(DOCKER) mdashnet/cc2 gcc mongoose.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -o unit_test_gcc
|
||||
linux: Makefile mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/cc2 gcc $(SRCS) $(CFLAGS) $(LDFLAGS) -o unit_test_gcc
|
||||
$(DOCKER) mdashnet/cc2 ./unit_test_gcc
|
||||
|
||||
linux++: CC = g++
|
||||
|
@ -243,6 +243,8 @@ Here is a list of build constants and their default values:
|
||||
|MG_ENABLE_SOCKETPAIR | 0 | Enable `mg_socketpair()` for multi-threading |
|
||||
|MG_ENABLE_SSI | 1 | Enable serving SSI files by `mg_http_serve_dir()` |
|
||||
|MG_ENABLE_DIRLIST | 0 | Enable directory listing |
|
||||
|MG_ENABLE_CUSTOM_RANDOM | 0 | Provide custom RNG function `mg_random()` |
|
||||
|MG_ENABLE_PACKED_FS | 0 | Enable embedded FS support |
|
||||
|MG_IO_SIZE | 2048 | Granularity of the send/recv IO buffer growth |
|
||||
|MG_MAX_RECV_BUF_SIZE | (3 * 1024 * 1024) | Maximum recv buffer size |
|
||||
|MG_MAX_HTTP_HEADERS | 40 | Maximum number of HTTP headers |
|
||||
@ -755,6 +757,28 @@ parameter.
|
||||
- `headers` - extra headers, default NULL. If not NULL, must end with `\r\n`
|
||||
- `fmt` - a format string for the HTTP body, in a printf semantics
|
||||
|
||||
Example - send a simple JSON respose:
|
||||
```c
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{\"result\": %d}", 123);
|
||||
```
|
||||
|
||||
Example - send JSON response using [mjson](https://github.com/cesanta/mjson) library:
|
||||
```c
|
||||
char *json = NULL;
|
||||
mjson_printf(mjson_print_dynamic_buf, &json, "{%Q:%d}", "name", 123);
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s", json);
|
||||
free(json);
|
||||
```
|
||||
|
||||
Example - send a 302 redirect:
|
||||
```c
|
||||
mg_http_reply(c, 302, "Location: /\r\n", "");
|
||||
```
|
||||
|
||||
Example - send error:
|
||||
```c
|
||||
mg_http_reply(c, 403, "", "%s", "Not Authorised\n");
|
||||
```
|
||||
|
||||
### mg\_http\_get\_header()
|
||||
|
||||
|
@ -1,20 +1,20 @@
|
||||
PROG ?= example
|
||||
SOURCES ?= ../../mongoose.c main.c mjson.c packed_fs.c
|
||||
CFLAGS ?= -I../.. $(EXTRA)
|
||||
CFLAGS ?= -I../.. -DMG_ENABLE_PACKED_FS=1 $(EXTRA)
|
||||
FILES_TO_EMBED ?= $(wildcard web_root/*.js) $(wildcard web_root/*.css) $(wildcard web_root/*.html) $(wildcard web_root/images/*.png) $(wildcard images/*.jpg)
|
||||
|
||||
all: $(PROG)
|
||||
$(RUN) ./$(PROG)
|
||||
|
||||
$(PROG):
|
||||
$(CC) pack.c -o pack
|
||||
$(CC) ../../test/pack.c -o pack
|
||||
./pack $(FILES_TO_EMBED) > packed_fs.c
|
||||
$(CC) -W -Wall -Wextra -Os -g3 $(CFLAGS) -o $(PROG) $(SOURCES)
|
||||
|
||||
ROOT ?= $(realpath $(CURDIR)/../..)
|
||||
DOCKER ?= docker run -it --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98 wine
|
||||
windows:
|
||||
$(DOCKER) cl.exe /nologo $(CFLAGS) pack.c /Fepack.exe
|
||||
$(DOCKER) cl.exe /nologo $(CFLAGS) ../../test/pack.c /Fepack.exe
|
||||
$(DOCKER) cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
|
||||
$(DOCKER) cl.exe /nologo /O2 $(CFLAGS) $(SOURCES) ws2_32.lib /Fe$(PROG).exe
|
||||
$(DOCKER) $(PROG).exe
|
||||
|
@ -119,7 +119,8 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
"Pragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT\r\n"
|
||||
"Content-Type: multipart/x-mixed-replace; boundary=--foo\r\n\r\n");
|
||||
} else if (mg_http_match_uri(hm, "/api/log/static")) {
|
||||
struct mg_http_serve_opts opts = {.root_dir = NULL};
|
||||
struct mg_http_serve_opts opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
mg_http_serve_file(c, hm, "log.txt", &opts);
|
||||
} else if (mg_http_match_uri(hm, "/api/log/live")) {
|
||||
c->label[0] = 'L'; // Mark that connection as live log listener
|
||||
|
@ -15,4 +15,4 @@ flash:
|
||||
cd build && $(ESPTOOL) --chip esp32 -p $(COMPORT) -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x100000 mongoose-esp32-example.bin
|
||||
|
||||
clean:
|
||||
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.* build sdkconfig build
|
||||
rm -rf build
|
||||
|
44
mongoose.c
44
mongoose.c
@ -417,32 +417,55 @@ struct packed_file {
|
||||
size_t pos;
|
||||
};
|
||||
|
||||
const char *mg_unpack(const char *, size_t *) WEAK;
|
||||
const char *mg_unpack(const char *path, size_t *size) {
|
||||
(void) path, (void) size;
|
||||
const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
|
||||
const char *mg_unlist(size_t no);
|
||||
#if MG_ENABLE_PACKED_FS
|
||||
#else
|
||||
const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
|
||||
(void) path, (void) size, (void) mtime;
|
||||
return NULL;
|
||||
}
|
||||
const char *mg_unlist(size_t no) {
|
||||
(void) no;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *packed_realpath(const char *path, char *resolved_path) {
|
||||
if (resolved_path == NULL) resolved_path = (char *) malloc(strlen(path) + 1);
|
||||
while (*path == '.' || *path == '/') path++;
|
||||
strcpy(resolved_path, path);
|
||||
return resolved_path;
|
||||
}
|
||||
|
||||
static int is_dir_prefix(const char *prefix, size_t n, const char *path) {
|
||||
return n < strlen(path) && memcmp(prefix, path, n) == 0 &&
|
||||
(n == 0 || path[n] == MG_DIRSEP);
|
||||
}
|
||||
|
||||
static int packed_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
const char *data = mg_unpack(path, size);
|
||||
if (mtime) *mtime = 0;
|
||||
return data == NULL ? MG_FS_DIR : MG_FS_READ;
|
||||
const char *p;
|
||||
size_t i, n = strlen(path);
|
||||
if (mg_unpack(path, size, mtime)) return MG_FS_READ; // Regular file
|
||||
// Scan all files. If `path` is a dir prefix for any of them, it's a dir
|
||||
for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
|
||||
if (is_dir_prefix(path, n, p)) return MG_FS_DIR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void packed_list(const char *path, void (*fn)(const char *, void *),
|
||||
void *userdata) {
|
||||
(void) path, (void) fn, (void) userdata;
|
||||
const char *p;
|
||||
size_t i, n = strlen(path);
|
||||
for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
|
||||
if (is_dir_prefix(path, n, p)) fn(&p[n], userdata);
|
||||
}
|
||||
}
|
||||
|
||||
static struct mg_fd *packed_open(const char *path, int flags) {
|
||||
size_t size = 0;
|
||||
const char *data = mg_unpack(path, &size);
|
||||
const char *data = mg_unpack(path, &size, NULL);
|
||||
struct packed_file *fp = NULL;
|
||||
struct mg_fd *fd = NULL;
|
||||
if (data == NULL) return NULL;
|
||||
@ -1332,7 +1355,7 @@ static void printdirentry(const char *name, void *userdata) {
|
||||
char path[MG_PATH_MAX], sz[64], mod[64];
|
||||
int flags, n = 0;
|
||||
|
||||
if (snprintf(path, sizeof(path), "%s%c%s", d->dir, MG_DIRSEP, name) < 0) {
|
||||
if (snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) < 0) {
|
||||
LOG(LL_ERROR, ("%s truncated", name));
|
||||
} else if ((flags = fs->stat(path, &size, &mtime)) == 0) {
|
||||
LOG(LL_ERROR, ("%lu stat(%s): %d", d->c->id, path, errno));
|
||||
@ -4155,6 +4178,8 @@ bool mg_file_printf(const char *path, const char *fmt, ...) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#if MG_ENABLE_CUSTOM_RANDOM
|
||||
#else
|
||||
void mg_random(void *buf, size_t len) {
|
||||
bool done = false;
|
||||
unsigned char *p = (unsigned char *) buf;
|
||||
@ -4173,6 +4198,7 @@ void mg_random(void *buf, size_t len) {
|
||||
while (len--) *p++ = (unsigned char) (rand() & 255);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
|
||||
size_t i = 0, j = 0, ni = 0, nj = 0;
|
||||
|
23
mongoose.h
23
mongoose.h
@ -66,6 +66,14 @@ extern "C" {
|
||||
#define MG_ENABLE_SOCKETPAIR 0
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_CUSTOM_RANDOM
|
||||
#define MG_ENABLE_CUSTOM_RANDOM 0
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_PACKED_FS
|
||||
#define MG_ENABLE_PACKED_FS 0
|
||||
#endif
|
||||
|
||||
// Granularity of the send/recv IO buffer growth
|
||||
#ifndef MG_IO_SIZE
|
||||
#define MG_IO_SIZE 2048
|
||||
@ -517,23 +525,10 @@ void mg_timer_poll(unsigned long uptime_ms);
|
||||
|
||||
|
||||
|
||||
// WEAK symbol makes it possible to define a "default" function implementation,
|
||||
// which could be overridden by the user who can define a function with the
|
||||
// same name without linking conflict
|
||||
#if !defined(WEAK)
|
||||
#if (defined(__GNUC__) || defined(__clang__) || \
|
||||
defined(__TI_COMPILER_VERSION__)) && \
|
||||
!defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#define WEAK __attribute__((weak))
|
||||
#else
|
||||
#define WEAK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
char *mg_file_read(const char *path, size_t *size);
|
||||
bool mg_file_write(const char *path, const void *buf, size_t len);
|
||||
bool mg_file_printf(const char *path, const char *fmt, ...);
|
||||
void mg_random(void *buf, size_t len) WEAK;
|
||||
void mg_random(void *buf, size_t len);
|
||||
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||
uint16_t mg_ntohs(uint16_t net);
|
||||
|
@ -41,6 +41,14 @@
|
||||
#define MG_ENABLE_SOCKETPAIR 0
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_CUSTOM_RANDOM
|
||||
#define MG_ENABLE_CUSTOM_RANDOM 0
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_PACKED_FS
|
||||
#define MG_ENABLE_PACKED_FS 0
|
||||
#endif
|
||||
|
||||
// Granularity of the send/recv IO buffer growth
|
||||
#ifndef MG_IO_SIZE
|
||||
#define MG_IO_SIZE 2048
|
||||
|
@ -6,32 +6,55 @@ struct packed_file {
|
||||
size_t pos;
|
||||
};
|
||||
|
||||
const char *mg_unpack(const char *, size_t *) WEAK;
|
||||
const char *mg_unpack(const char *path, size_t *size) {
|
||||
(void) path, (void) size;
|
||||
const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
|
||||
const char *mg_unlist(size_t no);
|
||||
#if MG_ENABLE_PACKED_FS
|
||||
#else
|
||||
const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
|
||||
(void) path, (void) size, (void) mtime;
|
||||
return NULL;
|
||||
}
|
||||
const char *mg_unlist(size_t no) {
|
||||
(void) no;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *packed_realpath(const char *path, char *resolved_path) {
|
||||
if (resolved_path == NULL) resolved_path = (char *) malloc(strlen(path) + 1);
|
||||
while (*path == '.' || *path == '/') path++;
|
||||
strcpy(resolved_path, path);
|
||||
return resolved_path;
|
||||
}
|
||||
|
||||
static int is_dir_prefix(const char *prefix, size_t n, const char *path) {
|
||||
return n < strlen(path) && memcmp(prefix, path, n) == 0 &&
|
||||
(n == 0 || path[n] == MG_DIRSEP);
|
||||
}
|
||||
|
||||
static int packed_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
const char *data = mg_unpack(path, size);
|
||||
if (mtime) *mtime = 0;
|
||||
return data == NULL ? MG_FS_DIR : MG_FS_READ;
|
||||
const char *p;
|
||||
size_t i, n = strlen(path);
|
||||
if (mg_unpack(path, size, mtime)) return MG_FS_READ; // Regular file
|
||||
// Scan all files. If `path` is a dir prefix for any of them, it's a dir
|
||||
for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
|
||||
if (is_dir_prefix(path, n, p)) return MG_FS_DIR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void packed_list(const char *path, void (*fn)(const char *, void *),
|
||||
void *userdata) {
|
||||
(void) path, (void) fn, (void) userdata;
|
||||
const char *p;
|
||||
size_t i, n = strlen(path);
|
||||
for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
|
||||
if (is_dir_prefix(path, n, p)) fn(&p[n], userdata);
|
||||
}
|
||||
}
|
||||
|
||||
static struct mg_fd *packed_open(const char *path, int flags) {
|
||||
size_t size = 0;
|
||||
const char *data = mg_unpack(path, &size);
|
||||
const char *data = mg_unpack(path, &size, NULL);
|
||||
struct packed_file *fp = NULL;
|
||||
struct mg_fd *fd = NULL;
|
||||
if (data == NULL) return NULL;
|
||||
|
@ -596,7 +596,7 @@ static void printdirentry(const char *name, void *userdata) {
|
||||
char path[MG_PATH_MAX], sz[64], mod[64];
|
||||
int flags, n = 0;
|
||||
|
||||
if (snprintf(path, sizeof(path), "%s%c%s", d->dir, MG_DIRSEP, name) < 0) {
|
||||
if (snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) < 0) {
|
||||
LOG(LL_ERROR, ("%s truncated", name));
|
||||
} else if ((flags = fs->stat(path, &size, &mtime)) == 0) {
|
||||
LOG(LL_ERROR, ("%lu stat(%s): %d", d->c->id, path, errno));
|
||||
|
@ -57,6 +57,8 @@ bool mg_file_printf(const char *path, const char *fmt, ...) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#if MG_ENABLE_CUSTOM_RANDOM
|
||||
#else
|
||||
void mg_random(void *buf, size_t len) {
|
||||
bool done = false;
|
||||
unsigned char *p = (unsigned char *) buf;
|
||||
@ -75,6 +77,7 @@ void mg_random(void *buf, size_t len) {
|
||||
while (len--) *p++ = (unsigned char) (rand() & 255);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
|
||||
size_t i = 0, j = 0, ni = 0, nj = 0;
|
||||
|
15
src/util.h
15
src/util.h
@ -3,23 +3,10 @@
|
||||
#include "arch.h"
|
||||
#include "str.h"
|
||||
|
||||
// WEAK symbol makes it possible to define a "default" function implementation,
|
||||
// which could be overridden by the user who can define a function with the
|
||||
// same name without linking conflict
|
||||
#if !defined(WEAK)
|
||||
#if (defined(__GNUC__) || defined(__clang__) || \
|
||||
defined(__TI_COMPILER_VERSION__)) && \
|
||||
!defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#define WEAK __attribute__((weak))
|
||||
#else
|
||||
#define WEAK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
char *mg_file_read(const char *path, size_t *size);
|
||||
bool mg_file_write(const char *path, const void *buf, size_t len);
|
||||
bool mg_file_printf(const char *path, const char *fmt, ...);
|
||||
void mg_random(void *buf, size_t len) WEAK;
|
||||
void mg_random(void *buf, size_t len);
|
||||
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||
uint16_t mg_ntohs(uint16_t net);
|
||||
|
@ -20,13 +20,18 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static const char *code =
|
||||
"const char *mg_unpack(const char *name, size_t *size) {\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 (strcmp(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"
|
||||
@ -37,12 +42,13 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
printf("%s", "#include <stddef.h>\n");
|
||||
printf("%s", "#include <string.h>\n");
|
||||
printf("%s", "#include <time.h>\n");
|
||||
printf("%s", "\n");
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
FILE *fp = fopen(argv[i], "rb");
|
||||
char ascii[12];
|
||||
if (fp == NULL) exit(EXIT_FAILURE);
|
||||
FILE *fp = fopen(argv[i], "rb");
|
||||
if (fp == NULL) printf("Cannot open %s\n", argv[i]), exit(EXIT_FAILURE);
|
||||
|
||||
printf("static const unsigned char v%d[] = {\n", i);
|
||||
for (j = 0; (ch = fgetc(fp)) != EOF; j++) {
|
||||
@ -64,12 +70,15 @@ int main(int argc, char *argv[]) {
|
||||
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");
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
printf(" {\"%s\", v%d, sizeof(v%d) },\n", argv[i], i, i);
|
||||
struct stat st;
|
||||
stat(argv[i], &st);
|
||||
printf(" {\"%s\", v%d, sizeof(v%d), %lu},\n", argv[i], i, i, st.st_mtime);
|
||||
}
|
||||
printf("%s", " {NULL, NULL, 0}\n");
|
||||
printf("%s", " {NULL, NULL, 0, 0}\n");
|
||||
printf("%s", "};\n\n");
|
||||
printf("%s", code);
|
||||
|
@ -1368,19 +1368,22 @@ static void eh7(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
static void test_packed(void) {
|
||||
struct mg_mgr mgr;
|
||||
const char *url = "http://127.0.0.1:12351";
|
||||
char buf[FETCH_BUF_SIZE] = "";
|
||||
char buf[FETCH_BUF_SIZE] = "", *data = mg_file_read("Makefile", NULL);
|
||||
mg_mgr_init(&mgr);
|
||||
mg_http_listen(&mgr, url, eh7, NULL);
|
||||
// ASSERT(fetch(&mgr, buf, url, "GET /packed/ HTTP/1.0\n\n") == 404);
|
||||
// fetch(&mgr, buf, url, "GET / HTTP/1.0\n\n");
|
||||
fetch(&mgr, buf, url, "GET /Makefile HTTP/1.0\n\n");
|
||||
printf("--------\n%s\n", buf);
|
||||
ASSERT(fetch(&mgr, buf, url, "GET /Makefile HTTP/1.0\n\n") == 200);
|
||||
ASSERT(cmpbody(buf, data) == 0);
|
||||
free(data);
|
||||
ASSERT(fetch(&mgr, buf, url, "GET / HTTP/1.0\n\n") == 200);
|
||||
// printf("--------\n%s\n", buf);
|
||||
// exit(0);
|
||||
mg_mgr_free(&mgr);
|
||||
ASSERT(mgr.conns == NULL);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
mg_log_set("3");
|
||||
test_packed();
|
||||
test_crc32();
|
||||
test_multipart();
|
||||
test_http_chunked();
|
||||
@ -1403,7 +1406,6 @@ int main(void) {
|
||||
test_http_no_content_length();
|
||||
test_http_pipeline();
|
||||
test_http_range();
|
||||
test_packed();
|
||||
test_mqtt();
|
||||
printf("SUCCESS. Total tests: %d\n", s_num_tests);
|
||||
return EXIT_SUCCESS;
|
||||
|
Loading…
x
Reference in New Issue
Block a user