mirror of
https://github.com/cesanta/mongoose.git
synced 2025-07-25 14:46:14 +08:00
Enhance packed fs serving
This commit is contained in:
parent
3a46055e52
commit
b40b1232cc
29
mongoose.c
29
mongoose.c
@ -433,14 +433,14 @@ const char *mg_unlist(size_t no) {
|
||||
|
||||
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++;
|
||||
// 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);
|
||||
return n < strlen(path) && memcmp(prefix, path, n) == 0 && path[n] == '/';
|
||||
//(n == 0 || path[n] == MG_DIRSEP);
|
||||
}
|
||||
|
||||
static int packed_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
@ -454,12 +454,24 @@ static int packed_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void packed_list(const char *path, void (*fn)(const char *, void *),
|
||||
static void packed_list(const char *dir, void (*fn)(const char *, void *),
|
||||
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);
|
||||
char buf[256], tmp[sizeof(buf)];
|
||||
const char *path, *begin, *end;
|
||||
size_t i, n = strlen(dir);
|
||||
tmp[0] = '\0'; // Previously listed entry
|
||||
for (i = 0; (path = mg_unlist(i)) != NULL; i++) {
|
||||
if (!is_dir_prefix(dir, n, path)) continue;
|
||||
begin = &path[n + 1];
|
||||
end = strchr(begin, '/');
|
||||
if (end == NULL) end = begin + strlen(begin);
|
||||
snprintf(buf, sizeof(buf), "%.*s", (int) (end - begin), begin);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
// If this entry has been already listed, skip
|
||||
// NOTE: we're assuming that file list is sorted alphabetically
|
||||
if (strcmp(buf, tmp) == 0) continue;
|
||||
fn(buf, userdata); // Not yet listed, call user function
|
||||
strcpy(tmp, buf); // And save this entry as listed
|
||||
}
|
||||
}
|
||||
|
||||
@ -1355,6 +1367,7 @@ static void printdirentry(const char *name, void *userdata) {
|
||||
char path[MG_PATH_MAX], sz[64], mod[64];
|
||||
int flags, n = 0;
|
||||
|
||||
// LOG(LL_DEBUG, ("[%s] [%s]", d->dir, name));
|
||||
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) {
|
||||
|
@ -22,14 +22,14 @@ const char *mg_unlist(size_t no) {
|
||||
|
||||
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++;
|
||||
// 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);
|
||||
return n < strlen(path) && memcmp(prefix, path, n) == 0 && path[n] == '/';
|
||||
//(n == 0 || path[n] == MG_DIRSEP);
|
||||
}
|
||||
|
||||
static int packed_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
@ -43,12 +43,24 @@ static int packed_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void packed_list(const char *path, void (*fn)(const char *, void *),
|
||||
static void packed_list(const char *dir, void (*fn)(const char *, void *),
|
||||
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);
|
||||
char buf[256], tmp[sizeof(buf)];
|
||||
const char *path, *begin, *end;
|
||||
size_t i, n = strlen(dir);
|
||||
tmp[0] = '\0'; // Previously listed entry
|
||||
for (i = 0; (path = mg_unlist(i)) != NULL; i++) {
|
||||
if (!is_dir_prefix(dir, n, path)) continue;
|
||||
begin = &path[n + 1];
|
||||
end = strchr(begin, '/');
|
||||
if (end == NULL) end = begin + strlen(begin);
|
||||
snprintf(buf, sizeof(buf), "%.*s", (int) (end - begin), begin);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
// If this entry has been already listed, skip
|
||||
// NOTE: we're assuming that file list is sorted alphabetically
|
||||
if (strcmp(buf, tmp) == 0) continue;
|
||||
fn(buf, userdata); // Not yet listed, call user function
|
||||
strcpy(tmp, buf); // And save this entry as listed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,6 +596,7 @@ static void printdirentry(const char *name, void *userdata) {
|
||||
char path[MG_PATH_MAX], sz[64], mod[64];
|
||||
int flags, n = 0;
|
||||
|
||||
// LOG(LL_DEBUG, ("[%s] [%s]", d->dir, name));
|
||||
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) {
|
||||
|
@ -76,7 +76,7 @@ int main(int argc, char *argv[]) {
|
||||
for (i = 1; i < argc; 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\", v%d, sizeof(v%d), %lu},\n", argv[i], i, i, st.st_mtime);
|
||||
}
|
||||
printf("%s", " {NULL, NULL, 0, 0}\n");
|
||||
printf("%s", "};\n\n");
|
||||
|
@ -582,7 +582,6 @@ static void test_http_server(void) {
|
||||
// Directory listing
|
||||
fetch(&mgr, buf, url, "GET /test/ HTTP/1.0\n\n");
|
||||
ASSERT(fetch(&mgr, buf, url, "GET /test/ HTTP/1.0\n\n") == 200);
|
||||
printf("-------\n%s\n", buf);
|
||||
ASSERT(mg_strstr(mg_str(buf), mg_str(">Index of /test/<")) != NULL);
|
||||
ASSERT(mg_strstr(mg_str(buf), mg_str(">fuzz.c<")) != NULL);
|
||||
|
||||
@ -1358,7 +1357,7 @@ static void eh7(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
struct mg_http_serve_opts sopts;
|
||||
memset(&sopts, 0, sizeof(sopts));
|
||||
sopts.root_dir = ".";
|
||||
sopts.root_dir = "";
|
||||
sopts.fs = &mg_fs_packed;
|
||||
mg_http_serve_dir(c, hm, &sopts);
|
||||
}
|
||||
@ -1371,12 +1370,26 @@ static void test_packed(void) {
|
||||
char buf[FETCH_BUF_SIZE] = "", *data = mg_file_read("Makefile", NULL);
|
||||
mg_mgr_init(&mgr);
|
||||
mg_http_listen(&mgr, url, eh7, NULL);
|
||||
|
||||
// Load top level file directly
|
||||
ASSERT(fetch(&mgr, buf, url, "GET /Makefile HTTP/1.0\n\n") == 200);
|
||||
ASSERT(cmpbody(buf, data) == 0);
|
||||
free(data);
|
||||
|
||||
// Load file deeper in the FS tree directly
|
||||
data = mg_file_read("src/ssi.h", NULL);
|
||||
ASSERT(fetch(&mgr, buf, url, "GET /src/ssi.h HTTP/1.0\n\n") == 200);
|
||||
ASSERT(cmpbody(buf, data) == 0);
|
||||
free(data);
|
||||
|
||||
// List root dir
|
||||
ASSERT(fetch(&mgr, buf, url, "GET / HTTP/1.0\n\n") == 200);
|
||||
// printf("--------\n%s\n", buf);
|
||||
// exit(0);
|
||||
|
||||
// List nested dir
|
||||
ASSERT(fetch(&mgr, buf, url, "GET /test HTTP/1.0\n\n") == 200);
|
||||
// printf("--------\n%s\n", buf);
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
ASSERT(mgr.conns == NULL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user