diff --git a/include/libwebsockets/lws-vfs.h b/include/libwebsockets/lws-vfs.h index 4b0c70738..b59b4ac75 100644 --- a/include/libwebsockets/lws-vfs.h +++ b/include/libwebsockets/lws-vfs.h @@ -93,10 +93,15 @@ struct lws_fops_index { }; struct lws_plat_file_ops { - lws_fop_fd_t (*LWS_FOP_OPEN)(const struct lws_plat_file_ops *fops, + lws_fop_fd_t (*LWS_FOP_OPEN)(const struct lws_plat_file_ops *fops_own, + const struct lws_plat_file_ops *fops, const char *filename, const char *vpath, lws_fop_flags_t *flags); /**< Open file (always binary access if plat supports it) + * fops_own is the fops this was called through. fops is the base + * fops the open can use to find files to process as present as its own, + * like the zip fops does. + * * vpath may be NULL, or if the fops understands it, the point at which * the filename's virtual part starts. * *flags & LWS_FOP_FLAGS_MASK should be set to O_RDONLY or O_RDWR. @@ -121,7 +126,12 @@ struct lws_plat_file_ops { /**< vfs path signatures implying use of this fops */ const struct lws_plat_file_ops *next; - /**< NULL or next fops in list */ + /**< NULL or next fops in list... eg copy static fops def to heap + * and modify copy at runtime */ + + struct lws_context *cx; + /**< the lws_context... eg copy static fops def to heap + * and modify copy at runtime */ /* Add new things just above here ---^ * This is part of the ABI, don't needlessly break compatibility */ @@ -254,7 +264,8 @@ lws_vfs_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, */ LWS_VISIBLE LWS_EXTERN lws_fop_fd_t -_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, +_lws_plat_file_open(const struct lws_plat_file_ops *fops_own, + const struct lws_plat_file_ops *fops, const char *filename, const char *vpath, lws_fop_flags_t *flags); LWS_VISIBLE LWS_EXTERN int _lws_plat_file_close(lws_fop_fd_t *fop_fd); diff --git a/lib/core/context.c b/lib/core/context.c index b927b448f..c1fbf45dc 100644 --- a/lib/core/context.c +++ b/lib/core/context.c @@ -892,6 +892,7 @@ lws_create_context(const struct lws_context_creation_info *info) context->fops_platform.LWS_FOP_READ = _lws_plat_file_read; context->fops_platform.LWS_FOP_WRITE = _lws_plat_file_write; context->fops_platform.fi[0].sig = NULL; + context->fops_platform.cx = context; /* * arrange a linear linked-list of fops starting from context->fops @@ -908,6 +909,7 @@ lws_create_context(const struct lws_context_creation_info *info) /* make a soft copy so we can set .next */ context->fops_zip = fops_zip; prev->next = &context->fops_zip; + context->fops_zip.cx = context; prev = (struct lws_plat_file_ops *)prev->next; #endif diff --git a/lib/core/vfs.c b/lib/core/vfs.c index e14d41592..01c44d0f3 100644 --- a/lib/core/vfs.c +++ b/lib/core/vfs.c @@ -88,20 +88,41 @@ lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path, * handled by a specific fops */ + pf = fops->next; /* the first one is always platform fops, so skip */ + while (pf) { + n = 0; + while (pf && n < (int)LWS_ARRAY_SIZE(pf->fi) && pf->fi[n].sig) { + if (!strncmp(p, pf->fi[n].sig, pf->fi[n].len)) { + *vpath = p + pf->fi[n].len; + //lwsl_notice("%s: hit, vpath '%s'\n", + // __func__, *vpath); + return pf; + } + pf = pf->next; + n++; + } + } + while (p && *p) { if (*p != '/') { p++; continue; } - /* the first one is always platform fops, so skip */ - pf = fops->next; + + pf = fops->next; /* the first one is always platform fops, so skip */ while (pf) { n = 0; while (n < (int)LWS_ARRAY_SIZE(pf->fi) && pf->fi[n].sig) { + lwsl_warn("%s %s\n", p, pf->fi[n].sig); if (p >= vfs_path + pf->fi[n].len) + /* + * Accept sigs like .... .zip or + * mysig... + */ if (!strncmp(p - (pf->fi[n].len - 1), pf->fi[n].sig, - (unsigned int)(pf->fi[n].len - 1))) { + (unsigned int)(pf->fi[n].len - 1)) || + !strncmp(p, pf->fi[n].sig, pf->fi[n].len)) { *vpath = p + 1; return pf; } @@ -125,7 +146,7 @@ lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path, selected = lws_vfs_select_fops(fops, vfs_path, &vpath); - return selected->LWS_FOP_OPEN(fops, vfs_path, vpath, flags); + return selected->LWS_FOP_OPEN(selected, fops, vfs_path, vpath, flags); } diff --git a/lib/plat/freertos/freertos-file.c b/lib/plat/freertos/freertos-file.c index 033d2587f..f4ff76ef5 100644 --- a/lib/plat/freertos/freertos-file.c +++ b/lib/plat/freertos/freertos-file.c @@ -31,7 +31,8 @@ int lws_plat_apply_FD_CLOEXEC(int n) lws_fop_fd_t IRAM_ATTR -_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, +_lws_plat_file_open(const struct lws_plat_file_ops *fops_own, + const struct lws_plat_file_ops *fops, const char *filename, const char *vpath, lws_fop_flags_t *flags) { struct stat stat_buf; diff --git a/lib/plat/unix/unix-file.c b/lib/plat/unix/unix-file.c index 81cbb222e..fe4960d7d 100644 --- a/lib/plat/unix/unix-file.c +++ b/lib/plat/unix/unix-file.c @@ -79,7 +79,8 @@ lws_plat_read_file(const char *filename, void *buf, size_t len) } lws_fop_fd_t -_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, +_lws_plat_file_open(const struct lws_plat_file_ops *fops_own, + const struct lws_plat_file_ops *fops, const char *filename, const char *vpath, lws_fop_flags_t *flags) { struct stat stat_buf; diff --git a/lib/plat/windows/windows-file.c b/lib/plat/windows/windows-file.c index ba78bc64e..1cbdd0cee 100644 --- a/lib/plat/windows/windows-file.c +++ b/lib/plat/windows/windows-file.c @@ -33,7 +33,8 @@ int lws_plat_apply_FD_CLOEXEC(int n) } lws_fop_fd_t -_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, +_lws_plat_file_open(const struct lws_plat_file_ops *fops_own, + const struct lws_plat_file_ops *fops, const char *filename, const char *vpath, lws_fop_flags_t *flags) { HANDLE ret; diff --git a/lib/roles/http/server/fops-zip.c b/lib/roles/http/server/fops-zip.c index 832dcfc1d..43ed0c04e 100644 --- a/lib/roles/http/server/fops-zip.c +++ b/lib/roles/http/server/fops-zip.c @@ -315,7 +315,8 @@ lws_fops_zip_reset_inflate(lws_fops_zip_t priv) } static lws_fop_fd_t -lws_fops_zip_open(const struct lws_plat_file_ops *fops, const char *vfs_path, +lws_fops_zip_open(const struct lws_plat_file_ops *fops_own, + const struct lws_plat_file_ops *fops, const char *vfs_path, const char *vpath, lws_fop_flags_t *flags) { lws_fop_flags_t local_flags = 0; @@ -342,7 +343,7 @@ lws_fops_zip_open(const struct lws_plat_file_ops *fops, const char *vfs_path, /* open the zip file itself using the incoming fops, not fops_zip */ - priv->zip_fop_fd = fops->LWS_FOP_OPEN(fops, rp, NULL, &local_flags); + priv->zip_fop_fd = fops->LWS_FOP_OPEN(fops_own, fops, rp, NULL, &local_flags); if (!priv->zip_fop_fd) { lwsl_err("%s: unable to open zip %s\n", __func__, rp); goto bail1; @@ -652,4 +653,5 @@ struct lws_plat_file_ops fops_zip = { NULL, { { ".zip/", 5 }, { ".jar/", 5 }, { ".war/", 5 } }, NULL, + NULL, }; diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c index 667980d85..b93fb861f 100644 --- a/lib/roles/http/server/server.c +++ b/lib/roles/http/server/server.c @@ -698,7 +698,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, if (wsi->http.fop_fd) lws_vfs_file_close(&wsi->http.fop_fd); - wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->a.context->fops, + wsi->http.fop_fd = fops->LWS_FOP_OPEN(fops, wsi->a.context->fops, path, vpath, &fflags); if (!wsi->http.fop_fd) { lwsl_info("%s: Unable to open '%s': errno %d\n", @@ -2755,7 +2755,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (!wsi->http.fop_fd) { fops = lws_vfs_select_fops(wsi->a.context->fops, file, &vpath); fflags |= lws_vfs_prepare_flags(wsi); - wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->a.context->fops, + wsi->http.fop_fd = fops->LWS_FOP_OPEN(fops, wsi->a.context->fops, file, vpath, &fflags); if (!wsi->http.fop_fd) { lwsl_info("%s: Unable to open: '%s': errno %d\n", diff --git a/minimal-examples-lowlevel/http-client/minimal-http-client-multi/minimal-http-client-multi.c b/minimal-examples-lowlevel/http-client/minimal-http-client-multi/minimal-http-client-multi.c index b521b3db6..bd43ba8b7 100644 --- a/minimal-examples-lowlevel/http-client/minimal-http-client-multi/minimal-http-client-multi.c +++ b/minimal-examples-lowlevel/http-client/minimal-http-client-multi/minimal-http-client-multi.c @@ -562,7 +562,7 @@ int main(int argc, const char **argv) * It will just allocate for 1 internal and COUNT + 1 (allowing for h2 * network wsi) that we will use. */ - info.fd_limit_per_thread = 1 + COUNT + 1; + info.fd_limit_per_thread = 1 + COUNT + 8 + 1; info.register_notifier_list = na; info.pcontext = &context;