1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-30 00:00:16 +01:00

file_ops: vfs: support prefix matches and use of bound ops members

VFS needs some small updates... pass in the bound fops as well as the
context fops to the member callbacks.  ZIP_FOPS only cared about doing
operations on the platform / context vfs to walk the ZIP file, but other
uses are valid where we are doing operation inside the bound VFS itself.

Also, stash a cx pointer into file ops struct for convenience.
This commit is contained in:
Andy Green 2022-02-17 06:37:42 +00:00
parent b61174b4b0
commit 2de67dd0ae
9 changed files with 54 additions and 15 deletions

View file

@ -93,10 +93,15 @@ struct lws_fops_index {
}; };
struct lws_plat_file_ops { 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, const char *filename, const char *vpath,
lws_fop_flags_t *flags); lws_fop_flags_t *flags);
/**< Open file (always binary access if plat supports it) /**< 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 * vpath may be NULL, or if the fops understands it, the point at which
* the filename's virtual part starts. * the filename's virtual part starts.
* *flags & LWS_FOP_FLAGS_MASK should be set to O_RDONLY or O_RDWR. * *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 */ /**< vfs path signatures implying use of this fops */
const struct lws_plat_file_ops *next; 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 ---^ /* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility */ * 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_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); const char *vpath, lws_fop_flags_t *flags);
LWS_VISIBLE LWS_EXTERN int LWS_VISIBLE LWS_EXTERN int
_lws_plat_file_close(lws_fop_fd_t *fop_fd); _lws_plat_file_close(lws_fop_fd_t *fop_fd);

View file

@ -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_READ = _lws_plat_file_read;
context->fops_platform.LWS_FOP_WRITE = _lws_plat_file_write; context->fops_platform.LWS_FOP_WRITE = _lws_plat_file_write;
context->fops_platform.fi[0].sig = NULL; context->fops_platform.fi[0].sig = NULL;
context->fops_platform.cx = context;
/* /*
* arrange a linear linked-list of fops starting from context->fops * 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 */ /* make a soft copy so we can set .next */
context->fops_zip = fops_zip; context->fops_zip = fops_zip;
prev->next = &context->fops_zip; prev->next = &context->fops_zip;
context->fops_zip.cx = context;
prev = (struct lws_plat_file_ops *)prev->next; prev = (struct lws_plat_file_ops *)prev->next;
#endif #endif

View file

@ -88,20 +88,41 @@ lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path,
* handled by a specific fops * 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) { while (p && *p) {
if (*p != '/') { if (*p != '/') {
p++; p++;
continue; 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) { while (pf) {
n = 0; n = 0;
while (n < (int)LWS_ARRAY_SIZE(pf->fi) && pf->fi[n].sig) { 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) if (p >= vfs_path + pf->fi[n].len)
/*
* Accept sigs like .... .zip or
* mysig...
*/
if (!strncmp(p - (pf->fi[n].len - 1), if (!strncmp(p - (pf->fi[n].len - 1),
pf->fi[n].sig, 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; *vpath = p + 1;
return pf; 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); 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);
} }

View file

@ -31,7 +31,8 @@ int lws_plat_apply_FD_CLOEXEC(int n)
lws_fop_fd_t IRAM_ATTR 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) const char *vpath, lws_fop_flags_t *flags)
{ {
struct stat stat_buf; struct stat stat_buf;

View file

@ -79,7 +79,8 @@ lws_plat_read_file(const char *filename, void *buf, size_t len)
} }
lws_fop_fd_t 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) const char *vpath, lws_fop_flags_t *flags)
{ {
struct stat stat_buf; struct stat stat_buf;

View file

@ -33,7 +33,8 @@ int lws_plat_apply_FD_CLOEXEC(int n)
} }
lws_fop_fd_t 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) const char *vpath, lws_fop_flags_t *flags)
{ {
HANDLE ret; HANDLE ret;

View file

@ -315,7 +315,8 @@ lws_fops_zip_reset_inflate(lws_fops_zip_t priv)
} }
static lws_fop_fd_t 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) const char *vpath, lws_fop_flags_t *flags)
{ {
lws_fop_flags_t local_flags = 0; 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 */ /* 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) { if (!priv->zip_fop_fd) {
lwsl_err("%s: unable to open zip %s\n", __func__, rp); lwsl_err("%s: unable to open zip %s\n", __func__, rp);
goto bail1; goto bail1;
@ -652,4 +653,5 @@ struct lws_plat_file_ops fops_zip = {
NULL, NULL,
{ { ".zip/", 5 }, { ".jar/", 5 }, { ".war/", 5 } }, { { ".zip/", 5 }, { ".jar/", 5 }, { ".war/", 5 } },
NULL, NULL,
NULL,
}; };

View file

@ -698,7 +698,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
if (wsi->http.fop_fd) if (wsi->http.fop_fd)
lws_vfs_file_close(&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); path, vpath, &fflags);
if (!wsi->http.fop_fd) { if (!wsi->http.fop_fd) {
lwsl_info("%s: Unable to open '%s': errno %d\n", 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) { if (!wsi->http.fop_fd) {
fops = lws_vfs_select_fops(wsi->a.context->fops, file, &vpath); fops = lws_vfs_select_fops(wsi->a.context->fops, file, &vpath);
fflags |= lws_vfs_prepare_flags(wsi); 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); file, vpath, &fflags);
if (!wsi->http.fop_fd) { if (!wsi->http.fop_fd) {
lwsl_info("%s: Unable to open: '%s': errno %d\n", lwsl_info("%s: Unable to open: '%s': errno %d\n",

View file

@ -562,7 +562,7 @@ int main(int argc, const char **argv)
* It will just allocate for 1 internal and COUNT + 1 (allowing for h2 * It will just allocate for 1 internal and COUNT + 1 (allowing for h2
* network wsi) that we will use. * 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.register_notifier_list = na;
info.pcontext = &context; info.pcontext = &context;