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:
parent
b61174b4b0
commit
2de67dd0ae
9 changed files with 54 additions and 15 deletions
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue