mirror of
https://github.com/falk-werner/webfuse
synced 2025-06-13 12:54:15 +00:00
allow clients to register filesystems
This commit is contained in:
parent
6418d2c091
commit
9345f947cc
@ -1,5 +1,6 @@
|
||||
export class ConnectionView {
|
||||
constructor(client) {
|
||||
constructor(client, provider) {
|
||||
this._provider = provider;
|
||||
this._client = client;
|
||||
this._client.onopen = () => { this._onConnectionOpened(); };
|
||||
this._client.onclose = () => { this._onConnectionClosed(); };
|
||||
@ -73,6 +74,7 @@ export class ConnectionView {
|
||||
}
|
||||
|
||||
_onConnectionOpened() {
|
||||
this._client.addProvider("test", this._provider);
|
||||
this.connectButton.value = "disconnect";
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,8 @@ function startup() {
|
||||
"say_hello.sh": { inode: 3, mode: mode("0555"), type: "file", contents: "#!/bin/sh\necho hello\n"}
|
||||
}
|
||||
});
|
||||
const client = new Client(provider);
|
||||
const connectionView = new ConnectionView(client);
|
||||
const client = new Client();
|
||||
const connectionView = new ConnectionView(client, provider);
|
||||
document.getElementById('connection').appendChild(connectionView.element);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ export class Client {
|
||||
static get _PROTOCOL() { return "fs"; }
|
||||
|
||||
constructor(provider) {
|
||||
this._provider = provider;
|
||||
this._provider = { };
|
||||
this._ws = null;
|
||||
this.onopen = () => { };
|
||||
this.onclose = () => { };
|
||||
@ -34,6 +34,17 @@ export class Client {
|
||||
this._ws.send(JSON.stringify(request));
|
||||
}
|
||||
|
||||
addProvider(name, provider) {
|
||||
this._provider = provider;
|
||||
const request = {
|
||||
"method": "add_filesystem",
|
||||
"params": [name],
|
||||
"id": 23
|
||||
};
|
||||
|
||||
this._ws.send(JSON.stringify(request));
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this._ws) {
|
||||
this._ws.close();
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "webfuse/adapter/impl/filesystem.h"
|
||||
#include "webfuse/adapter/impl/operations.h"
|
||||
#include "webfuse/adapter/impl/session.h"
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@ -16,6 +19,31 @@ static struct fuse_lowlevel_ops const filesystem_operations =
|
||||
.read = &wf_impl_operation_read
|
||||
};
|
||||
|
||||
struct wf_impl_filesystem * wf_impl_filesystem_create(
|
||||
struct wf_impl_session * session,
|
||||
char const * mount_point)
|
||||
{
|
||||
struct wf_impl_filesystem * filesystem = malloc(sizeof(struct wf_impl_filesystem));
|
||||
if (NULL != filesystem)
|
||||
{
|
||||
bool success = wf_impl_filesystem_init(filesystem, session, mount_point);
|
||||
if (!success)
|
||||
{
|
||||
free(filesystem);
|
||||
filesystem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return filesystem;
|
||||
}
|
||||
|
||||
void wf_impl_filesystem_dispose(
|
||||
struct wf_impl_filesystem * filesystem)
|
||||
{
|
||||
wf_impl_filesystem_cleanup(filesystem);
|
||||
free(filesystem);
|
||||
}
|
||||
|
||||
|
||||
bool wf_impl_filesystem_init(
|
||||
struct wf_impl_filesystem * filesystem,
|
||||
@ -23,6 +51,7 @@ bool wf_impl_filesystem_init(
|
||||
char const * mount_point)
|
||||
{
|
||||
bool result = false;
|
||||
wf_dlist_item_init(&filesystem->item);
|
||||
|
||||
char * argv[] = {"", NULL};
|
||||
filesystem->args.argc = 1;
|
||||
@ -43,6 +72,21 @@ bool wf_impl_filesystem_init(
|
||||
result = (0 == fuse_session_mount(filesystem->session, mount_point));
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
lws_sock_file_fd_type fd;
|
||||
fd.filefd = fuse_session_fd(filesystem->session);
|
||||
struct lws_protocols const * protocol = lws_get_protocol(session->wsi);
|
||||
filesystem->wsi = lws_adopt_descriptor_vhost(lws_get_vhost(session->wsi), LWS_ADOPT_RAW_FILE_DESC, fd, protocol->name, session->wsi);
|
||||
|
||||
if (NULL == filesystem->wsi)
|
||||
{
|
||||
wf_impl_filesystem_cleanup(filesystem);
|
||||
result = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "webfuse/adapter/impl/fuse_wrapper.h"
|
||||
#include "webfuse/adapter/impl/operations.h"
|
||||
#include "webfuse/core/dlist.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@ -14,15 +15,25 @@ extern "C"
|
||||
#endif
|
||||
|
||||
struct wf_impl_session;
|
||||
struct lws;
|
||||
|
||||
struct wf_impl_filesystem
|
||||
{
|
||||
struct wf_dlist_item item;
|
||||
struct fuse_args args;
|
||||
struct fuse_session * session;
|
||||
struct fuse_buf buffer;
|
||||
struct wf_impl_operations_context user_data;
|
||||
struct lws * wsi;
|
||||
};
|
||||
|
||||
extern struct wf_impl_filesystem * wf_impl_filesystem_create(
|
||||
struct wf_impl_session * session,
|
||||
char const * mount_point);
|
||||
|
||||
extern void wf_impl_filesystem_dispose(
|
||||
struct wf_impl_filesystem * filesystem);
|
||||
|
||||
extern bool wf_impl_filesystem_init(
|
||||
struct wf_impl_filesystem * filesystem,
|
||||
struct wf_impl_session * session,
|
||||
|
@ -31,8 +31,7 @@ static int wf_impl_server_protocol_callback(
|
||||
&protocol->authenticators,
|
||||
&protocol->timeout_manager,
|
||||
&protocol->server,
|
||||
protocol->mount_point,
|
||||
ws_protocol->name);
|
||||
protocol->mount_point);
|
||||
|
||||
if (NULL != session)
|
||||
{
|
||||
@ -57,7 +56,7 @@ static int wf_impl_server_protocol_callback(
|
||||
case LWS_CALLBACK_RAW_RX_FILE:
|
||||
if (NULL != session)
|
||||
{
|
||||
wf_impl_filesystem_process_request(&session->filesystem);
|
||||
wf_impl_session_process_filesystem_request(session, wsi);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -130,6 +129,45 @@ static void wf_impl_server_protocol_authenticate(
|
||||
}
|
||||
}
|
||||
|
||||
static void wf_impl_server_protocol_add_filesystem(
|
||||
struct wf_impl_jsonrpc_request * request,
|
||||
char const * WF_UNUSED_PARAM(method_name),
|
||||
json_t * params,
|
||||
void * WF_UNUSED_PARAM(user_data))
|
||||
{
|
||||
struct wf_impl_session * session = wf_impl_jsonrpc_request_get_userdata(request);
|
||||
wf_status status = (session->is_authenticated) ? WF_GOOD : WF_BAD_ACCESS_DENIED;
|
||||
|
||||
char const * name = NULL;
|
||||
if (WF_GOOD == status)
|
||||
{
|
||||
json_t * name_holder = json_array_get(params, 0);
|
||||
if (json_is_string(name_holder))
|
||||
{
|
||||
name = json_string_value(name_holder);
|
||||
bool const success = wf_impl_session_add_filesystem(session, name);
|
||||
if (!success)
|
||||
{
|
||||
status = WF_BAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (WF_GOOD == status)
|
||||
{
|
||||
json_t * result = json_object();
|
||||
json_object_set_new(result, "id", json_string(name));
|
||||
wf_impl_jsonrpc_respond(request, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
wf_impl_jsonrpc_respond_error(request, status);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void wf_impl_server_protocol_init(
|
||||
struct wf_server_protocol * protocol,
|
||||
char * mount_point)
|
||||
@ -142,6 +180,7 @@ void wf_impl_server_protocol_init(
|
||||
|
||||
wf_impl_jsonrpc_server_init(&protocol->server);
|
||||
wf_impl_jsonrpc_server_add(&protocol->server, "authenticate", &wf_impl_server_protocol_authenticate, protocol);
|
||||
wf_impl_jsonrpc_server_add(&protocol->server, "add_filesystem", &wf_impl_server_protocol_add_filesystem, protocol);
|
||||
}
|
||||
|
||||
void wf_impl_server_protocol_cleanup(
|
||||
|
@ -6,6 +6,11 @@
|
||||
#include "webfuse/adapter/impl/jsonrpc/request.h"
|
||||
#include "webfuse/adapter/impl/jsonrpc/response.h"
|
||||
|
||||
#include "webfuse/core/container_of.h"
|
||||
#include "webfuse/core/util.h"
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@ -40,66 +45,48 @@ struct wf_impl_session * wf_impl_session_create(
|
||||
struct wf_impl_authenticators * authenticators,
|
||||
struct wf_impl_timeout_manager * timeout_manager,
|
||||
struct wf_impl_jsonrpc_server * server,
|
||||
char const * mount_point,
|
||||
char const * protocol_name)
|
||||
char const * mount_point)
|
||||
{
|
||||
static int session_id = 0;
|
||||
|
||||
struct wf_impl_session * session = malloc(sizeof(struct wf_impl_session));
|
||||
if (NULL != session)
|
||||
{
|
||||
snprintf(session->mount_point, PATH_MAX, "%s/%d", mount_point, session_id);
|
||||
session_id++;
|
||||
mkdir(session->mount_point, 0755);
|
||||
|
||||
wf_dlist_item_init(&session->item);
|
||||
wf_dlist_init(&session->filesystems);
|
||||
|
||||
session->mount_point = strdup(mount_point);
|
||||
session->wsi = wsi;
|
||||
session->is_authenticated = false;
|
||||
session->authenticators = authenticators;
|
||||
session->server = server;
|
||||
wf_impl_jsonrpc_proxy_init(&session->rpc, timeout_manager, &wf_impl_session_send, session);
|
||||
wf_message_queue_init(&session->queue);
|
||||
|
||||
bool success = wf_impl_filesystem_init(&session->filesystem, session, session->mount_point);
|
||||
if (success)
|
||||
{
|
||||
lws_sock_file_fd_type fd;
|
||||
fd.filefd = wf_impl_filesystem_get_fd(&session->filesystem);
|
||||
session->wsi_fuse = lws_adopt_descriptor_vhost(lws_get_vhost(wsi), LWS_ADOPT_RAW_FILE_DESC, fd, protocol_name, wsi);
|
||||
if (NULL == session->wsi_fuse)
|
||||
{
|
||||
success = false;
|
||||
fprintf(stderr, "error: unable to adopt fd");
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
rmdir(session->mount_point);
|
||||
wf_impl_jsonrpc_proxy_cleanup(&session->rpc);
|
||||
wf_message_queue_cleanup(&session->queue);
|
||||
free(session);
|
||||
session = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
static void wf_impl_session_cleanup_filesystem(
|
||||
struct wf_dlist_item * item,
|
||||
void * WF_UNUSED_PARAM(user_data))
|
||||
{
|
||||
struct wf_impl_filesystem * filesystem = WF_CONTAINER_OF(item, struct wf_impl_filesystem, item);
|
||||
wf_impl_filesystem_dispose(filesystem);
|
||||
|
||||
}
|
||||
|
||||
void wf_impl_session_dispose(
|
||||
struct wf_impl_session * session)
|
||||
{
|
||||
wf_impl_filesystem_cleanup(&session->filesystem);
|
||||
rmdir(session->mount_point);
|
||||
wf_dlist_cleanup(&session->filesystems, &wf_impl_session_cleanup_filesystem, NULL);
|
||||
|
||||
wf_impl_jsonrpc_proxy_cleanup(&session->rpc);
|
||||
wf_message_queue_cleanup(&session->queue);
|
||||
session->is_authenticated = false;
|
||||
session->wsi = NULL;
|
||||
session->wsi_fuse = NULL;
|
||||
session->authenticators = NULL;
|
||||
session->server = NULL;
|
||||
free(session->mount_point);
|
||||
free(session);
|
||||
}
|
||||
|
||||
@ -112,6 +99,25 @@ bool wf_impl_session_authenticate(
|
||||
return session->is_authenticated;
|
||||
}
|
||||
|
||||
bool wf_impl_session_add_filesystem(
|
||||
struct wf_impl_session * session,
|
||||
char const * name)
|
||||
{
|
||||
uuid_t uuid;
|
||||
uuid_generate(uuid);
|
||||
char id[UUID_STR_LEN];
|
||||
uuid_unparse(uuid, id);
|
||||
|
||||
char mount_point[PATH_MAX];
|
||||
snprintf(mount_point, PATH_MAX, "%s/%s/%s", session->mount_point, name, id);
|
||||
mkdir(mount_point, 0755);
|
||||
|
||||
struct wf_impl_filesystem * filesystem = wf_impl_filesystem_create(session, mount_point);
|
||||
wf_dlist_prepend(&session->filesystems, &filesystem->item);
|
||||
return (NULL != filesystem);
|
||||
}
|
||||
|
||||
|
||||
void wf_impl_session_onwritable(
|
||||
struct wf_impl_session * session)
|
||||
{
|
||||
@ -149,4 +155,48 @@ void wf_impl_session_receive(
|
||||
json_decref(message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static struct wf_impl_filesystem * wf_impl_session_get_filesystem(
|
||||
struct wf_impl_session * session,
|
||||
struct lws * wsi)
|
||||
{
|
||||
struct wf_impl_filesystem * filesystem = WF_CONTAINER_OF(session->filesystems.first, struct wf_impl_filesystem, item);
|
||||
while (NULL != filesystem)
|
||||
{
|
||||
if (wsi == filesystem->wsi)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
filesystem = WF_CONTAINER_OF(filesystem->item.next, struct wf_impl_filesystem, item);
|
||||
}
|
||||
}
|
||||
|
||||
return filesystem;
|
||||
}
|
||||
|
||||
|
||||
bool wf_impl_session_contains_wsi(
|
||||
struct wf_dlist_item * item,
|
||||
void * user_data)
|
||||
{
|
||||
struct lws * wsi = user_data;
|
||||
struct wf_impl_session * session = WF_CONTAINER_OF(item, struct wf_impl_session, item);
|
||||
|
||||
bool const result = (NULL != wsi) && ((wsi == session->wsi) || (NULL != wf_impl_session_get_filesystem(session, wsi)));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void wf_impl_session_process_filesystem_request(
|
||||
struct wf_impl_session * session,
|
||||
struct lws * wsi)
|
||||
{
|
||||
struct wf_impl_filesystem * filesystem = wf_impl_session_get_filesystem(session, wsi);
|
||||
if (NULL != filesystem)
|
||||
{
|
||||
wf_impl_filesystem_process_request(filesystem);
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,6 @@
|
||||
using std::size_t;
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "webfuse/core/message_queue.h"
|
||||
#include "webfuse/adapter/impl/jsonrpc/proxy.h"
|
||||
#include "webfuse/adapter/impl/jsonrpc/server.h"
|
||||
@ -31,15 +29,14 @@ struct wf_impl_timeout_manager;
|
||||
struct wf_impl_session
|
||||
{
|
||||
struct wf_dlist_item item;
|
||||
char mount_point[PATH_MAX];
|
||||
char * mount_point;
|
||||
struct lws * wsi;
|
||||
struct lws * wsi_fuse;
|
||||
bool is_authenticated;
|
||||
struct wf_message_queue queue;
|
||||
struct wf_impl_filesystem filesystem;
|
||||
struct wf_impl_authenticators * authenticators;
|
||||
struct wf_impl_jsonrpc_server * server;
|
||||
struct wf_impl_jsonrpc_proxy rpc;
|
||||
struct wf_dlist filesystems;
|
||||
};
|
||||
|
||||
extern struct wf_impl_session * wf_impl_session_create(
|
||||
@ -47,8 +44,7 @@ extern struct wf_impl_session * wf_impl_session_create(
|
||||
struct wf_impl_authenticators * authenticators,
|
||||
struct wf_impl_timeout_manager * timeout_manager,
|
||||
struct wf_impl_jsonrpc_server * server,
|
||||
char const * mount_point,
|
||||
char const * protocol_name);
|
||||
char const * mount_point);
|
||||
|
||||
extern void wf_impl_session_dispose(
|
||||
struct wf_impl_session * session);
|
||||
@ -57,6 +53,10 @@ extern bool wf_impl_session_authenticate(
|
||||
struct wf_impl_session * session,
|
||||
struct wf_credentials * creds);
|
||||
|
||||
extern bool wf_impl_session_add_filesystem(
|
||||
struct wf_impl_session * session,
|
||||
char const * name);
|
||||
|
||||
extern void wf_impl_session_receive(
|
||||
struct wf_impl_session * session,
|
||||
char const * data,
|
||||
@ -65,6 +65,15 @@ extern void wf_impl_session_receive(
|
||||
extern void wf_impl_session_onwritable(
|
||||
struct wf_impl_session * session);
|
||||
|
||||
extern bool wf_impl_session_contains_wsi(
|
||||
struct wf_dlist_item * item,
|
||||
void * user_data);
|
||||
|
||||
extern void wf_impl_session_process_filesystem_request(
|
||||
struct wf_impl_session * session,
|
||||
struct lws * wsi);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -33,11 +33,10 @@ struct wf_impl_session * wf_impl_session_manager_add(
|
||||
struct wf_impl_authenticators * authenticators,
|
||||
struct wf_impl_timeout_manager * timeout_manager,
|
||||
struct wf_impl_jsonrpc_server * server,
|
||||
char const * mount_point,
|
||||
char const * protocol_name)
|
||||
char const * mount_point)
|
||||
{
|
||||
struct wf_impl_session * session = wf_impl_session_create(
|
||||
wsi, authenticators, timeout_manager, server, mount_point, protocol_name);
|
||||
wsi, authenticators, timeout_manager, server, mount_point);
|
||||
if (NULL != session)
|
||||
{
|
||||
wf_dlist_prepend(&manager->sessions, &session->item);
|
||||
@ -46,23 +45,13 @@ struct wf_impl_session * wf_impl_session_manager_add(
|
||||
return session;
|
||||
}
|
||||
|
||||
static bool wf_impl_session_manager_get_predicate(
|
||||
struct wf_dlist_item * item,
|
||||
void * user_data)
|
||||
{
|
||||
struct lws * wsi = user_data;
|
||||
struct wf_impl_session * session = WF_CONTAINER_OF(item, struct wf_impl_session, item);
|
||||
|
||||
return ((wsi == session->wsi) || (wsi == session->wsi_fuse));
|
||||
}
|
||||
|
||||
struct wf_impl_session * wf_impl_session_manager_get(
|
||||
struct wf_impl_session_manager * manager,
|
||||
struct lws * wsi)
|
||||
{
|
||||
struct wf_impl_session * session = NULL;
|
||||
struct wf_dlist_item * item = wf_dlist_find_first(
|
||||
&manager->sessions, &wf_impl_session_manager_get_predicate, wsi);
|
||||
&manager->sessions, &wf_impl_session_contains_wsi, wsi);
|
||||
if (NULL != item)
|
||||
{
|
||||
session = WF_CONTAINER_OF(item, struct wf_impl_session, item);
|
||||
|
@ -35,8 +35,7 @@ extern struct wf_impl_session * wf_impl_session_manager_add(
|
||||
struct wf_impl_authenticators * authenticators,
|
||||
struct wf_impl_timeout_manager * timeout_manager,
|
||||
struct wf_impl_jsonrpc_server * server,
|
||||
char const * mount_point,
|
||||
char const * protocol_name);
|
||||
char const * mount_point);
|
||||
|
||||
extern struct wf_impl_session * wf_impl_session_manager_get(
|
||||
struct wf_impl_session_manager * manager,
|
||||
|
Loading…
Reference in New Issue
Block a user