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

ss: support VFS via file://

This gives you a way to access VFS files via a generic SS.

Typcially you would use the default streamtype having set the ${endpoint}
metadata to file://mypath/vpath.suffix or similar.

The lws VFS lets you register handlers for path prefixes (like /myvfsname)
or suffixes (like .zip).  Matches create a vfs fd that is bound to the
matching file_ops that receives the open, close, read, write etc
"syscalls" for lws VFS operations on the vfs fd.

This gives you a way not just to access files from the platform root
filesystem, but also VFS layers like DLO filesystem blobs, by name,
from a normal SS.
This commit is contained in:
Andy Green 2022-02-17 11:48:44 +00:00
parent 2de67dd0ae
commit 64144e0c15
2 changed files with 80 additions and 0 deletions

View file

@ -97,6 +97,10 @@ typedef struct lws_ss_handle {
lws_sorted_usec_list_t sul_timeout;
lws_sorted_usec_list_t sul;
#if defined(LWS_WITH_FILE_OPS)
lws_sorted_usec_list_t fops_sul;
lws_fop_fd_t fop_fd;
#endif
lws_ss_tx_ordinal_t txord;
/* protocol-specific connection helpers */

View file

@ -654,6 +654,41 @@ lws_ss_smd_tx_cb(lws_sorted_usec_list_t *sul)
#endif
#if defined(LWS_WITH_FILE_OPS)
static void
lws_ss_fops_sul_cb(lws_sorted_usec_list_t *sul)
{
lws_ss_handle_t *h = lws_container_of(sul, lws_ss_handle_t, fops_sul);
lws_ss_state_return_t r = LWSSSSRET_DISCONNECT_ME;
lws_filepos_t amount;
uint8_t lump[1400];
amount = sizeof(lump);
if (lws_vfs_file_read(h->fop_fd, &amount, lump, sizeof(lump)))
goto disconn;
r = h->info.rx(h + 1, lump, (size_t)amount,
(!h->fop_fd->pos ? LWSSS_FLAG_SOM : 0) |
(h->fop_fd->pos == h->fop_fd->len ?
LWSSS_FLAG_EOM : 0));
if (!r) {
if (h->fop_fd->pos != h->fop_fd->len)
lws_sul_schedule(h->context, 0, &h->fops_sul,
lws_ss_fops_sul_cb, 1);
return;
}
disconn:
lws_vfs_file_close(&h->fop_fd);
if (lws_ss_event_helper(h, LWSSSCS_DISCONNECTED))
return;
if (r == LWSSSSRET_DESTROY_ME)
lws_ss_destroy(&h);
}
#endif
lws_ss_state_return_t
_lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw)
{
@ -740,6 +775,39 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw)
_ipath = ipath = "";
_ads = ads = ep;
#if defined(LWS_WITH_FILE_OPS)
if (!strncmp(ep, "file://", 7)) {
lws_fop_flags_t fl = 0;
h->fop_fd = lws_vfs_file_open(h->context->fops, ep + 7, &fl);
/* we opened the file */
r = lws_ss_event_helper(h, LWSSSCS_CONNECTING);
if (r) {
lws_vfs_file_close(&h->fop_fd);
return r;
}
if (!h->fop_fd) {
lws_vfs_file_close(&h->fop_fd);
lwsl_ss_warn(h, "Unable to find %s", ep);
goto fail_out;
}
r = lws_ss_event_helper(h, LWSSSCS_CONNECTED);
if (r) {
lws_vfs_file_close(&h->fop_fd);
return r;
}
/* start issuing the file as rx next time around the event loop */
lws_sul_schedule(h->context, 0, &h->fops_sul,
lws_ss_fops_sul_cb, 1);
return LWSSSSRET_OK;
}
#endif
if (strchr(ep, ':') &&
!lws_parse_uri(ep, &_prot, &_ads, &_port, &_ipath)) {
lwsl_debug("%s: using uri parse results '%s' '%s' %d '%s'\n",
@ -880,6 +948,9 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw)
if (h->pending_ret)
return h->pending_ret;
#if defined(LWS_WITH_FILE_OPS)
fail_out:
#endif
if (h->prev_ss_state != LWSSSCS_UNREACHABLE &&
h->prev_ss_state != LWSSSCS_ALL_RETRIES_FAILED) {
/*
@ -1394,6 +1465,11 @@ lws_ss_destroy(lws_ss_handle_t **ppss)
lws_pt_lock(pt, __func__);
*ppss = NULL;
lws_dll2_remove(&h->list);
#if defined(LWS_WITH_FILE_OPS)
lws_sul_cancel(&h->fops_sul);
if (h->fop_fd)
lws_vfs_file_close(&h->fop_fd);
#endif
#if defined(LWS_WITH_SERVER)
lws_dll2_remove(&h->cli_list);
#endif