1
0
mirror of https://github.com/falk-werner/webfuse synced 2024-10-27 20:34:10 +00:00

use libwebsockets as loop for fuse fd; removed dependency to libuv, since it is not needed anymore; disabled jsonrpc temporary, until refactoring is finished (will not work properly)

This commit is contained in:
Falk Werner 2019-02-06 00:58:51 +01:00
parent 84aa5daf32
commit b74c459942
18 changed files with 433 additions and 364 deletions

View File

@ -7,7 +7,6 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBUV REQUIRED libuv)
pkg_check_modules(FUSE3 REQUIRED fuse3) pkg_check_modules(FUSE3 REQUIRED fuse3)
pkg_check_modules(LWS REQUIRED libwebsockets) pkg_check_modules(LWS REQUIRED libwebsockets)
pkg_check_modules(JANSSON REQUIRED jansson) pkg_check_modules(JANSSON REQUIRED jansson)
@ -15,7 +14,7 @@ pkg_check_modules(JANSSON REQUIRED jansson)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra")
set(EXTRA_INCLUDE_DIRS set(EXTRA_INCLUDE_DIRS
${LIBUV_INCLUDE_DIRS} "inc"
${FUSE3_INCLUDE_DIRS} ${FUSE3_INCLUDE_DIRS}
${LWS_INCLUDE_DIRS} ${LWS_INCLUDE_DIRS}
${JANSSON_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS}
@ -23,7 +22,6 @@ set(EXTRA_INCLUDE_DIRS
set(EXTRA_LIBS set(EXTRA_LIBS
${EXTRA_LIBS} ${EXTRA_LIBS}
${LIBUV_LIBRARIES}
${FUSE3_LIBRARIES} ${FUSE3_LIBRARIES}
${LWS_LIBRARIES} ${LWS_LIBRARIES}
${JANSSON_LIBRARIES} ${JANSSON_LIBRARIES}
@ -31,7 +29,6 @@ set(EXTRA_LIBS
) )
set(EXTRA_CFLAGS set(EXTRA_CFLAGS
${LIBUV_CFLAGS_OTHER}
${FUSE3_CFLAGS_OTHER} ${FUSE3_CFLAGS_OTHER}
${LWS_CFLAGS_OTHER} ${LWS_CFLAGS_OTHER}
${JANSSON_CFLAGS_OTHER} ${JANSSON_CFLAGS_OTHER}
@ -43,7 +40,7 @@ set(EXTRA_CFLAGS
add_library(fuse-wsfs add_library(fuse-wsfs
src/wsfs/status.c src/wsfs/status.c
src/wsfs/operations.c src/wsfs/filesystem.c
src/wsfs/operation/lookup.c src/wsfs/operation/lookup.c
src/wsfs/operation/getattr.c src/wsfs/operation/getattr.c
src/wsfs/operation/readdir.c src/wsfs/operation/readdir.c
@ -52,7 +49,8 @@ add_library(fuse-wsfs
src/wsfs/operation/read.c src/wsfs/operation/read.c
src/wsfs/response_parser.c src/wsfs/response_parser.c
src/wsfs/server.c src/wsfs/server.c
src/wsfs/protocol.c src/wsfs/server_config.c
src/wsfs/server_protocol.c
src/wsfs/jsonrpc.c src/wsfs/jsonrpc.c
) )
@ -66,7 +64,7 @@ add_executable(wsfs
) )
target_link_libraries(wsfs PUBLIC fuse-wsfs ${EXTRA_LIBS}) target_link_libraries(wsfs PUBLIC fuse-wsfs ${EXTRA_LIBS})
target_include_directories(wsfs PUBLIC src ${EXTRA_INCLUDE_DIRS}) target_include_directories(wsfs PUBLIC ${EXTRA_INCLUDE_DIRS})
target_compile_options(wsfs PUBLIC ${EXTRA_CFLAGS}) target_compile_options(wsfs PUBLIC ${EXTRA_CFLAGS})
# tests # tests

View File

@ -18,7 +18,6 @@ fuse-wsfs combines libwebsockets and libfuse. It allows ot attach a remote files
# Dependencies # Dependencies
- [libuv](https://github.com/libuv/libuv)
- [libfuse3](https://github.com/libfuse/libfuse/) - [libfuse3](https://github.com/libfuse/libfuse/)
- [libwebsockets](https://libwebsockets.org/) - [libwebsockets](https://libwebsockets.org/)
- [Jansson](https://jansson.readthedocs.io) - [Jansson](https://jansson.readthedocs.io)

7
inc/wsfs.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _WSFS_H
#define _WSFS_H
#include "wsfs/api.h"
#include "wsfs/server.h"
#endif

8
inc/wsfs/api.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _WSFS_API_H
#define _WSFS_API_H
#ifndef WSFS_API
#define WSFS_API
#endif
#endif

31
inc/wsfs/server.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef _WSFS_SERVER_H
#define _WSFS_SERVER_H
#include "wsfs/api.h"
struct wsfs_server;
struct wsfs_server_config;
#ifdef __cplusplus
extern "C"
{
#endif
extern WSFS_API struct wsfs_server * wsfs_server_create(
struct wsfs_server_config * config);
extern WSFS_API void wsfs_server_dispose(
struct wsfs_server * server);
extern WSFS_API void wsfs_server_run(
struct wsfs_server * server);
extern WSFS_API void wsfs_server_shutdown(
struct wsfs_server * server);
#ifdef __cplusplus
}
#endif
#endif

35
inc/wsfs/server_config.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef _WSFS_SERVER_CONFIG_H
#define _WSFS_SERVER_CONFIG_H
#include "wsfs/api.h"
struct wsfs_server_config
{
char * mount_point;
char * document_root;
char * key_path;
char * cert_path;
char * vhost_name;
int port;
};
#ifdef __cplusplus
extern "C"
{
#endif
extern WSFS_API void wsfs_server_config_init(
struct wsfs_server_config * config);
extern WSFS_API void wsfs_server_config_cleanup(
struct wsfs_server_config * config);
extern WSFS_API void wsfs_server_config_clone(
struct wsfs_server_config * config,
struct wsfs_server_config * clone);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,28 @@
#ifndef _WSFS_SERVER_PROTOCOL_H
#define _WSFS_SERVER_PROTOCOL_H
#include "wsfs/api.h"
struct wsfs_server_protocol;
struct lws_protocols;
#ifdef __cplusplus
extern "C"
{
#endif
extern WSFS_API struct wsfs_server_protocol * wsfs_server_protocol_create(
char * mount_point);
extern WSFS_API void wsfs_server_protocol_dispose(
struct wsfs_server_protocol * protocol);
extern WSFS_API void wsfs_server_protocol_init_lws(
struct wsfs_server_protocol * protocol,
struct lws_protocols * lws_protocol);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -3,20 +3,22 @@
#include <string.h> #include <string.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <getopt.h> #include <getopt.h>
#include "wsfs/operations.h"
#include "wsfs/server.h" #include "wsfs/server.h"
#include "wsfs/server_config.h"
struct args struct args
{ {
struct wsfs_server_config config; struct wsfs_server_config config;
char * mount_point;
bool show_help; bool show_help;
}; };
static struct wsfs_server * server;
static void show_help(void) static void show_help(void)
{ {
printf( printf(
@ -67,8 +69,8 @@ static int parse_arguments(int argc, char * argv[], struct args * args)
finished = true; finished = true;
break; break;
case 'm': case 'm':
free(args->mount_point); free(args->config.mount_point);
args->mount_point = strdup(optarg); args->config.mount_point = strdup(optarg);
break; break;
case 'd': case 'd':
free(args->config.document_root); free(args->config.document_root);
@ -98,7 +100,7 @@ static int parse_arguments(int argc, char * argv[], struct args * args)
if ((EXIT_SUCCESS == result) && (!args->show_help)) if ((EXIT_SUCCESS == result) && (!args->show_help))
{ {
if (NULL == args->mount_point) if (NULL == args->config.mount_point)
{ {
fprintf(stderr, "error: missing mount point\n"); fprintf(stderr, "error: missing mount point\n");
result = EXIT_FAILURE; result = EXIT_FAILURE;
@ -113,19 +115,26 @@ static int parse_arguments(int argc, char * argv[], struct args * args)
return result; return result;
} }
static void on_interrupt(int signal_id)
{
(void) signal_id;
wsfs_server_shutdown(server);
}
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
struct args args = struct args args =
{ {
.config = .config =
{ {
.mount_point = NULL,
.document_root = NULL, .document_root = NULL,
.cert_path = NULL, .cert_path = NULL,
.key_path = NULL, .key_path = NULL,
.vhost_name = strdup("localhost"), .vhost_name = strdup("localhost"),
.port = 8080, .port = 8080,
}, },
.mount_point = NULL,
.show_help = 0 .show_help = 0
}; };
@ -133,13 +142,11 @@ int main(int argc, char * argv[])
if (!args.show_help) if (!args.show_help)
{ {
struct wsfs_server * server = wsfs_server_create(&args.config); signal(SIGINT, on_interrupt);
server = wsfs_server_create(&args.config);
if (NULL != server) if (NULL != server)
{ {
wsfs_server_start(server); wsfs_server_run(server);
struct wsfs_jsonrpc * const rpc = wsfs_server_get_jsonrpc_service(server);
result = wsfs_operations_loop(args.mount_point, rpc);
wsfs_server_dispose(server); wsfs_server_dispose(server);
} }
else else
@ -153,9 +160,7 @@ int main(int argc, char * argv[])
show_help(); show_help();
} }
wsfs_server_config_clear(&args.config); wsfs_server_config_cleanup(&args.config);
free(args.mount_point);
return result; return result;
} }

79
src/wsfs/filesystem.c Normal file
View File

@ -0,0 +1,79 @@
#include "wsfs/filesystem.h"
#include "wsfs/operations.h"
#include "wsfs/jsonrpc.h"
#include <stddef.h>
#include <string.h>
#include <errno.h>
static struct fuse_lowlevel_ops const wsfs_filesystem_operations =
{
.lookup = &wsfs_operation_lookup,
.getattr = &wsfs_operation_getattr,
.readdir = &wsfs_operation_readdir,
.open = &wsfs_operation_open,
.release = &wsfs_operation_close,
.read = &wsfs_operation_read
};
void wsfs_filesystem_init(
struct wsfs_filesystem * filesystem,
char * mount_point)
{
char * argv[] = {"", NULL};
filesystem->args.argc = 1;
filesystem->args.argv = argv;
filesystem->args.allocated = 0;
filesystem->user_data.rpc = wsfs_jsonrpc_create(NULL, NULL, NULL);
filesystem->user_data.timeout = 1.0;
memset(&filesystem->buffer, 0, sizeof(struct fuse_buf));
filesystem->session = fuse_session_new(
&filesystem->args,
&wsfs_filesystem_operations,
sizeof(wsfs_filesystem_operations),
&filesystem->user_data);
if (NULL != filesystem->session)
{
fuse_session_mount(filesystem->session, mount_point);
}
}
void wsfs_filesystem_cleanup(
struct wsfs_filesystem * filesystem)
{
if (NULL != filesystem->session)
{
fuse_session_reset(filesystem->session);
fuse_session_unmount(filesystem->session);
fuse_session_destroy(filesystem->session);
filesystem->session = NULL;
}
free(filesystem->buffer.mem);
fuse_opt_free_args(&filesystem->args);
}
int wsfs_filesystem_get_fd(
struct wsfs_filesystem * filesystem)
{
return fuse_session_fd(filesystem->session);
}
void wsfs_filesystem_process_request(
struct wsfs_filesystem * filesystem)
{
int const result = fuse_session_receive_buf(filesystem->session, &filesystem->buffer);
if (0 < result)
{
fuse_session_process_buf(filesystem->session, &filesystem->buffer);
}
else if (-EINTR != result)
{
// ToDo
}
}

28
src/wsfs/filesystem.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef _WSFS_FILESYSTEM_H
#define _WSFS_FILESYSTEM_H
#include "wsfs/fuse_wrapper.h"
#include "wsfs/operations.h"
struct wsfs_filesystem
{
struct fuse_args args;
struct fuse_session * session;
struct fuse_buf buffer;
struct wsfs_operations_context user_data;
};
extern void wsfs_filesystem_init(
struct wsfs_filesystem * filesystem,
char * mount_point);
extern void wsfs_filesystem_cleanup(
struct wsfs_filesystem * filesystem);
extern int wsfs_filesystem_get_fd(
struct wsfs_filesystem * filesystem);
extern void wsfs_filesystem_process_request(
struct wsfs_filesystem * filesystem);
#endif

View File

@ -80,6 +80,8 @@ wsfs_status wsfs_jsonrpc_invoke(
... ...
) )
{ {
return WSFS_BAD_NOTIMPLEMENTED;
// enqueue message // enqueue message
pthread_mutex_lock(&rpc->lock); pthread_mutex_lock(&rpc->lock);
wsfs_status status = WSFS_BAD; wsfs_status status = WSFS_BAD;

View File

@ -1,142 +0,0 @@
#include "wsfs/operations.h"
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <uv.h>
#include "wsfs/util.h"
struct wsfs_fuse_context
{
struct fuse_args args;
struct fuse_session * session;
struct fuse_buf buffer;
struct wsfs_operations_context user_data;
int fd;
bool mounted;
};
static struct fuse_lowlevel_ops const wsfs_operations =
{
.lookup = &wsfs_operation_lookup,
.getattr = &wsfs_operation_getattr,
.readdir = &wsfs_operation_readdir,
.open = &wsfs_operation_open,
.release = &wsfs_operation_close,
.read = &wsfs_operation_read
};
static bool wsfs_fuse_init(
struct wsfs_fuse_context * context,
char * mount_point,
struct wsfs_jsonrpc * rpc)
{
bool result = false;
char * argv[] = {"", NULL};
context->args.argc = 1;
context->args.argv = argv;
context->args.allocated = 0;
context->user_data.rpc = rpc;
context->user_data.timeout = 1.0;
memset(&context->buffer, 0, sizeof(struct fuse_buf));
context->session = fuse_session_new(&context->args, &wsfs_operations, sizeof(wsfs_operations), &context->user_data);
if (NULL != context->session)
{
result = (0 == fuse_session_mount(context->session, mount_point));
context->fd = fuse_session_fd(context->session);
}
// cleanup on error
if (!result)
{
if (NULL != context->session)
{
fuse_session_destroy(context->session);
context->session = NULL;
}
free(context->buffer.mem);
fuse_opt_free_args(&context->args);
}
return result;
}
static void wsfs_fuse_cleanup(
struct wsfs_fuse_context * context)
{
if (NULL != context->session)
{
fuse_session_reset(context->session);
fuse_session_unmount(context->session);
fuse_session_destroy(context->session);
context->session = NULL;
}
free(context->buffer.mem);
fuse_opt_free_args(&context->args);
}
static void wsfs_fuse_onreadable(
uv_poll_t* handle,
int WSFS_UNUSED_PARAM(status),
int WSFS_UNUSED_PARAM(events))
{
struct wsfs_fuse_context * context = handle->data;
int const result = fuse_session_receive_buf(context->session, &context->buffer);
if (0 < result)
{
fuse_session_process_buf(context->session, &context->buffer);
}
else if (-EINTR != result)
{
uv_poll_stop(handle);
}
}
static void wsfs_fuse_oninterrupt(uv_signal_t* handle, int WSFS_UNUSED_PARAM(signum))
{
uv_poll_t * poll_handle = handle->data;
uv_poll_stop(poll_handle);
}
int wsfs_operations_loop(
char * mount_point,
struct wsfs_jsonrpc * rpc)
{
uv_loop_t * loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);
struct wsfs_fuse_context context;
if (wsfs_fuse_init(&context, mount_point, rpc))
{
uv_poll_t handle;
uv_poll_init(loop, &handle, context.fd);
handle.data = &context;
uv_poll_start(&handle, UV_READABLE, &wsfs_fuse_onreadable);
uv_signal_t signal_interrupt;
uv_signal_init(loop, &signal_interrupt);
signal_interrupt.data = &handle;
uv_signal_start_oneshot(&signal_interrupt, &wsfs_fuse_oninterrupt, SIGINT);
uv_run(loop, UV_RUN_DEFAULT);
uv_close((uv_handle_t*) &signal_interrupt, NULL);
uv_close((uv_handle_t*) &handle, NULL);
uv_run(loop, UV_RUN_DEFAULT);
wsfs_fuse_cleanup(&context);
}
uv_loop_close(loop);
free(loop);
return 0;
}

View File

@ -15,10 +15,6 @@ struct wsfs_operations_context
extern "C" { extern "C" {
#endif #endif
extern int wsfs_operations_loop(
char * mount_point,
struct wsfs_jsonrpc * rpc);
extern void wsfs_operation_lookup ( extern void wsfs_operation_lookup (
fuse_req_t req, fuse_req_t req,
fuse_ino_t parent, fuse_ino_t parent,

View File

@ -2,82 +2,37 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <libwebsockets.h> #include <libwebsockets.h>
#include "wsfs/util.h" #include "wsfs/server_config.h"
#include "wsfs/protocol.h" #include "wsfs/server_protocol_intern.h"
#include "wsfs/jsonrpc.h"
#define WSFS_SERVICE_INTERVAL (1 * 1000) #define WSFS_SERVER_PROTOCOL_COUNT 3
#define WSFS_SERVER_TIMEOUT (1 * 1000)
struct wsfs_server struct wsfs_server
{ {
pthread_t thread; struct wsfs_server_config config;
bool shutdown_flag; struct wsfs_server_protocol protocol;
pthread_mutex_t lock; struct lws_protocols ws_protocols[WSFS_SERVER_PROTOCOL_COUNT];
struct wsfs_server_config config; struct lws_context * context;
struct wsfs_protocol * protocol; volatile bool shutdown_requested;
struct wsfs_jsonrpc * rpc;
}; };
static char * wsfs_strdup(char const * value)
{
char * result = NULL;
if (NULL != value)
{
result = strdup(value);
}
return result;
}
static bool wsfs_server_isshutdown(
struct wsfs_server * server)
{
bool result;
pthread_mutex_lock(&server->lock);
result = server->shutdown_flag;
pthread_mutex_unlock(&server->lock);
return result;
}
static bool wsfs_server_tls_enabled( static bool wsfs_server_tls_enabled(
struct wsfs_server * server) struct wsfs_server * server)
{ {
return ((server->config.key_path != NULL) && (server->config.cert_path != NULL)); return ((server->config.key_path != NULL) && (server->config.cert_path != NULL));
} }
static void wsfs_server_request_shutdown( static struct lws_context * wsfs_server_context_create(
struct wsfs_server * server) struct wsfs_server * server)
{ {
pthread_mutex_lock(&server->lock); memset(server->ws_protocols, 0, sizeof(struct lws_protocols) * WSFS_SERVER_PROTOCOL_COUNT);
server->shutdown_flag = true; server->ws_protocols[0].name = "http";
pthread_mutex_unlock(&server->lock); server->ws_protocols[0].callback = lws_callback_http_dummy;
} server->ws_protocols[1].name = "fs";
wsfs_server_protocol_init_lws(&server->protocol, &server->ws_protocols[1]);
static void wsfs_ignore_signal(int WSFS_UNUSED_PARAM(signal_id))
{
}
static void* wsfs_server_run(void * arg)
{
struct wsfs_server * const server = arg;
struct lws_protocols protocols[] =
{
{"http", lws_callback_http_dummy, 0, 0, 0, NULL, 0},
{ "fs", NULL, 0 , 0, 0, NULL, 0},
{ NULL, NULL, 0 , 0, 0, NULL, 0}
};
struct lws_http_mount mount = struct lws_http_mount mount =
{ {
@ -99,13 +54,11 @@ static void* wsfs_server_run(void * arg)
.basic_auth_login_file = NULL .basic_auth_login_file = NULL
}; };
wsfs_protocol_init_lws(server->protocol, &protocols[1]);
struct lws_context_creation_info info; struct lws_context_creation_info info;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.port = server->config.port; info.port = server->config.port;
info.mounts = &mount; info.mounts = &mount;
info.protocols = protocols; info.protocols = server->ws_protocols;
info.vhost_name = server->config.vhost_name; info.vhost_name = server->config.vhost_name;
info.ws_ping_pong_interval = 10; info.ws_ping_pong_interval = 10;
info.options = LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; info.options = LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
@ -113,7 +66,7 @@ static void* wsfs_server_run(void * arg)
if (NULL == server->config.document_root) if (NULL == server->config.document_root)
{ {
// disable http // disable http
info.protocols = &(protocols[1]); info.protocols = &server->ws_protocols[1];
info.mounts = NULL; info.mounts = NULL;
} }
@ -124,97 +77,48 @@ static void* wsfs_server_run(void * arg)
info.ssl_private_key_filepath = server->config.key_path; info.ssl_private_key_filepath = server->config.key_path;
} }
struct lws_context * context = lws_create_context(&info); struct lws_context * const context = lws_create_context(&info);
if (NULL == context) return context;
{
fprintf(stderr, "error: unable to start websocket server\n");
return NULL;
}
int n = 0;
while ((0 <= n) && (!wsfs_server_isshutdown(server)))
{
wsfs_protocol_check(server->protocol);
n = lws_service(context, WSFS_SERVICE_INTERVAL);
}
lws_context_destroy(context);
return NULL;
}
static void wsfs_server_join(struct wsfs_server * server)
{
wsfs_server_request_shutdown(server);
pthread_join(server->thread, NULL);
} }
struct wsfs_server * wsfs_server_create( struct wsfs_server * wsfs_server_create(
struct wsfs_server_config * config) struct wsfs_server_config * config)
{ {
signal(SIGUSR1, &wsfs_ignore_signal); struct wsfs_server * server = malloc(sizeof(struct wsfs_server));
if (NULL != server)
{
server->shutdown_requested = false;
wsfs_server_config_clone(config, &server->config);
wsfs_server_protocol_init(&server->protocol, config->mount_point);
server->context = wsfs_server_context_create(server);
}
struct wsfs_server * server = malloc(sizeof(struct wsfs_server)); return server;
if (NULL != server)
{
pthread_mutex_init(&server->lock, NULL);
server->shutdown_flag = false;
server->config.document_root = wsfs_strdup(config->document_root);
server->config.cert_path = wsfs_strdup(config->cert_path);
server->config.key_path = wsfs_strdup(config->key_path);
server->config.vhost_name = wsfs_strdup(config->vhost_name);
server->config.port = config->port;
server->rpc = wsfs_jsonrpc_create(&wsfs_protocol_message_create, &wsfs_protocol_send, NULL);
server->protocol = wsfs_protocol_create(server);
wsfs_jsonrpc_set_user_data(server->rpc, server->protocol);
}
return server;
} }
void wsfs_server_dispose( void wsfs_server_dispose(
struct wsfs_server * server) struct wsfs_server * server)
{ {
wsfs_server_join(server); lws_context_destroy(server->context);
wsfs_server_protocol_cleanup(&server->protocol);
wsfs_jsonrpc_dispose(server->rpc); wsfs_server_config_cleanup(&server->config);
wsfs_protocol_dispose(server->protocol); free(server);
wsfs_server_config_clear(&server->config);
pthread_mutex_destroy(&server->lock);
free(server);
} }
void wsfs_server_start( void wsfs_server_run(
struct wsfs_server * server) struct wsfs_server * server)
{ {
pthread_create(&server->thread, NULL, &wsfs_server_run, server); int n = 0;
while ((0 <= n) && (!server->shutdown_requested))
{
n = lws_service(server->context, WSFS_SERVER_TIMEOUT);
}
} }
void wsfs_server_config_clear(struct wsfs_server_config * config) void wsfs_server_shutdown(
struct wsfs_server * server)
{ {
free(config->document_root); server->shutdown_requested = true;
free(config->cert_path);
free(config->key_path);
free(config->vhost_name);
}
struct wsfs_jsonrpc * wsfs_server_get_jsonrpc_service(
struct wsfs_server * server)
{
return server->rpc;
}
void wsfs_server_wakeup(
struct wsfs_server * server)
{
pthread_kill(server->thread, SIGUSR1);
}
void wsfs_server_handle_message(
struct wsfs_server * server,
char const * message,
size_t length)
{
wsfs_jsonrpc_on_message(message, length, server->rpc);
} }

View File

@ -1,55 +0,0 @@
#ifndef _WSFS_SERVER_H
#define _WSFS_SERVER_H
#ifndef __cplusplus
#include <stddef.h>
#else
#include <cstddef>
using std::size_t;
#endif
struct wsfs_server;
struct wsfs_jsonrpc;
struct wsfs_server_config
{
char * document_root;
char * key_path;
char * cert_path;
char * vhost_name;
int port;
};
#ifdef __cplusplus
extern "C" {
#endif
extern void wsfs_server_config_clear(
struct wsfs_server_config * config);
extern struct wsfs_server * wsfs_server_create(
struct wsfs_server_config * config);
extern void wsfs_server_dispose(
struct wsfs_server * server);
extern struct wsfs_jsonrpc * wsfs_server_get_jsonrpc_service(
struct wsfs_server * server);
extern void wsfs_server_start(
struct wsfs_server * server);
extern void wsfs_server_wakeup(
struct wsfs_server * server);
extern void wsfs_server_handle_message(
struct wsfs_server * server,
char const * message,
size_t length);
#ifdef __cplusplus
}
#endif
#endif

45
src/wsfs/server_config.c Normal file
View File

@ -0,0 +1,45 @@
#include "wsfs/server_config.h"
#include <stdlib.h>
#include <string.h>
static char * wsfs_server_config_strdup(char const * value)
{
char * result = NULL;
if (NULL != value)
{
result = strdup(value);
}
return result;
}
void wsfs_server_config_init(
struct wsfs_server_config * config)
{
memset(config, 0, sizeof(struct wsfs_server_config));
}
void wsfs_server_config_cleanup(
struct wsfs_server_config * config)
{
free(config->mount_point);
free(config->document_root);
free(config->key_path);
free(config->cert_path);
free(config->vhost_name);
wsfs_server_config_init(config);
}
void wsfs_server_config_clone(
struct wsfs_server_config * config,
struct wsfs_server_config * clone)
{
clone->mount_point = wsfs_server_config_strdup(config->mount_point);
clone->document_root = wsfs_server_config_strdup(config->document_root);
clone->key_path = wsfs_server_config_strdup(config->key_path);
clone->cert_path = wsfs_server_config_strdup(config->cert_path);
clone->vhost_name = wsfs_server_config_strdup(config->vhost_name);
clone->port = config->port;
}

View File

@ -0,0 +1,82 @@
#include "wsfs/server_protocol_intern.h"
#include <stdlib.h>
#include <libwebsockets.h>
#include "wsfs/filesystem.h"
#include "wsfs/util.h"
static int wsfs_server_protocol_callback(
struct lws * wsi,
enum lws_callback_reasons reason,
void * WSFS_UNUSED_PARAM(user),
void * WSFS_UNUSED_PARAM(in),
size_t WSFS_UNUSED_PARAM(len))
{
struct lws_protocols const * ws_protocol = lws_get_protocol(wsi);
struct wsfs_server_protocol * protocol = ws_protocol->user;
switch (reason)
{
case LWS_CALLBACK_PROTOCOL_INIT:
{
lws_sock_file_fd_type fd;
fd.filefd = wsfs_filesystem_get_fd(&protocol->filesystem);
if (!lws_adopt_descriptor_vhost(lws_get_vhost(wsi), LWS_ADOPT_RAW_FILE_DESC, fd, ws_protocol->name, NULL))
{
puts("error: unable to adopt fd");
}
}
break;
case LWS_CALLBACK_RAW_RX_FILE:
{
puts("fd readable");
wsfs_filesystem_process_request(&protocol->filesystem);
}
break;
default:
break;
}
return 0;
}
struct wsfs_server_protocol * wsfs_server_protocol_create(
char * mount_point)
{
struct wsfs_server_protocol * protocol = malloc(sizeof(struct wsfs_server_protocol));
if (NULL != protocol)
{
wsfs_server_protocol_init(protocol, mount_point);
}
return protocol;
}
void wsfs_server_protocol_dispose(
struct wsfs_server_protocol * protocol)
{
wsfs_server_protocol_cleanup(protocol);
free(protocol);
}
void wsfs_server_protocol_init_lws(
struct wsfs_server_protocol * protocol,
struct lws_protocols * lws_protocol)
{
lws_protocol->callback = &wsfs_server_protocol_callback;
lws_protocol->per_session_data_size = 0;
lws_protocol->user = protocol;
}
void wsfs_server_protocol_init(
struct wsfs_server_protocol * protocol,
char * mount_point)
{
wsfs_filesystem_init(&protocol->filesystem, mount_point);
}
void wsfs_server_protocol_cleanup(
struct wsfs_server_protocol * protocol)
{
wsfs_filesystem_cleanup(&protocol->filesystem);
}

View File

@ -0,0 +1,19 @@
#ifndef _WSFS_SERVER_PROTOCOL_INTERN_H
#define _WSFS_SERVER_PROTOCOL_INTERN_H
#include "wsfs/server_protocol.h"
#include "wsfs/filesystem.h"
struct wsfs_server_protocol
{
struct wsfs_filesystem filesystem;
};
extern void wsfs_server_protocol_init(
struct wsfs_server_protocol * protocol,
char * mount_point);
extern void wsfs_server_protocol_cleanup(
struct wsfs_server_protocol * protocol);
#endif