From a5f1cdc7e7362bb08a3f717eb66b49a0b6acefdb Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 13 Nov 2022 22:22:35 +0100 Subject: [PATCH] added basic websockets protocol --- CMakeLists.txt | 2 + script/provider.py | 11 ++++ script/requirements.txt | 1 + src/webfuse/webfuse.cpp | 29 +++++++++ src/webfuse/ws/config.cpp | 13 +++++ src/webfuse/ws/config.hpp | 19 ++++++ src/webfuse/ws/server.cpp | 120 ++++++++++++++++++++++++++++++++++++++ src/webfuse/ws/server.hpp | 27 +++++++++ 8 files changed, 222 insertions(+) create mode 100755 script/provider.py create mode 100644 script/requirements.txt create mode 100644 src/webfuse/ws/config.cpp create mode 100644 src/webfuse/ws/config.hpp create mode 100644 src/webfuse/ws/server.cpp create mode 100644 src/webfuse/ws/server.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f54bb8f..b74745e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,8 @@ add_library(webfuse_static STATIC src/webfuse/filesystem/fileattributes.cpp src/webfuse/filesystem/filesystem_statistics.cpp src/webfuse/filesystem/empty_filesystem.cpp + src/webfuse/ws/config.cpp + src/webfuse/ws/server.cpp ) target_include_directories(webfuse_static PUBLIC src) diff --git a/script/provider.py b/script/provider.py new file mode 100755 index 0000000..f61a57e --- /dev/null +++ b/script/provider.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 + +import asyncio +import websockets + +async def hello(): + async with websockets.connect('ws://localhost:8081') as websocket: + await websocket.send('Hello') + await websocket.recv() + +asyncio.run(hello()) diff --git a/script/requirements.txt b/script/requirements.txt new file mode 100644 index 0000000..707d0d3 --- /dev/null +++ b/script/requirements.txt @@ -0,0 +1 @@ +websockets==10.4 \ No newline at end of file diff --git a/src/webfuse/webfuse.cpp b/src/webfuse/webfuse.cpp index 6ebb5b2..8158417 100644 --- a/src/webfuse/webfuse.cpp +++ b/src/webfuse/webfuse.cpp @@ -1,16 +1,45 @@ #include "webfuse/webfuse.hpp" #include "webfuse/fuse.hpp" #include "webfuse/filesystem/empty_filesystem.hpp" +#include "webfuse/ws/server.hpp" +#include "webfuse/ws/config.hpp" + +#include + +namespace +{ + +bool shutdown_requested = false; + +void on_shutdown_requested(int) +{ + shutdown_requested = true; +} + +} namespace webfuse { int app::run(int argc, char * argv[]) { +/* empty_filesystem filesystem; fuse fuse_fs(filesystem); return fuse_fs.run(argc, argv); +*/ + signal(SIGINT, &on_shutdown_requested); + + ws_config config; + ws_server server(config); + + while (!shutdown_requested) + { + server.service(); + } + + return 0; } } \ No newline at end of file diff --git a/src/webfuse/ws/config.cpp b/src/webfuse/ws/config.cpp new file mode 100644 index 0000000..4acbbe6 --- /dev/null +++ b/src/webfuse/ws/config.cpp @@ -0,0 +1,13 @@ +#include "webfuse/ws/config.hpp" + +namespace webfuse +{ + +ws_config::ws_config() +: port(8081) +{ + +} + + +} \ No newline at end of file diff --git a/src/webfuse/ws/config.hpp b/src/webfuse/ws/config.hpp new file mode 100644 index 0000000..97c20e7 --- /dev/null +++ b/src/webfuse/ws/config.hpp @@ -0,0 +1,19 @@ +#ifndef WEBFUSE_WS_CONFIG_HPP +#define WEBFUSE_WS_CONFIG_HPP + +#include + +namespace webfuse +{ + +class ws_config +{ +public: + ws_config(); + + uint16_t port; +}; + +} + +#endif diff --git a/src/webfuse/ws/server.cpp b/src/webfuse/ws/server.cpp new file mode 100644 index 0000000..4942cf8 --- /dev/null +++ b/src/webfuse/ws/server.cpp @@ -0,0 +1,120 @@ +#include "webfuse/ws/server.hpp" +#include +#include + +#include + +extern "C" +{ + +static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason, + void *user, void *in, size_t len) +{ + switch(reason) + { + case LWS_CALLBACK_PROTOCOL_INIT: + std::cout << "lws: protocol init "<< std::endl; + break; + case LWS_CALLBACK_ESTABLISHED: + std::cout << "lws: established "<< std::endl; + break; + case LWS_CALLBACK_CLOSED: + std::cout << "lws: closed "<< std::endl; + break; + case LWS_CALLBACK_RECEIVE: + std::cout << "lws: receive "<< std::endl; + break; + case LWS_CALLBACK_SERVER_WRITEABLE: + std::cout << "lws: server writable "<< std::endl; + break; + default: + break; + } + + return 0; +} + + +} + +namespace webfuse +{ + +class ws_server::detail +{ + detail(detail const &) = delete; + detail& operator=(detail const &) = delete; + detail(detail &&) = delete; + detail& operator=(detail &&) = delete; +public: + detail(ws_config const & config) + { + memset(reinterpret_cast(protocols), 0, sizeof(protocols)); + protocols[0].name = "webfuse2"; + protocols[0].callback = &ws_server_callback; + protocols[0].per_session_data_size = 0; + protocols[0].user = nullptr; + + memset(reinterpret_cast(&info), 0, sizeof(info)); + info.port = config.port; + info.protocols = protocols; + info.vhost_name = "localhost"; + info.options = LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE | LWS_SERVER_OPTION_EXPLICIT_VHOSTS; + + context = lws_create_context(&info); + + lws_vhost * const vhost = lws_create_vhost(context, &info); + // port = lws_get_vhost_port(vhost); + } + + ~detail() + { + lws_context_destroy(context); + } + + lws_protocols protocols[2]; + lws_context_creation_info info; + lws_context * context; +}; + +ws_server::ws_server(ws_config const & config) +: d(new detail(config)) +{ + +} + +ws_server::~ws_server() +{ + delete d; +} + +ws_server::ws_server(ws_server && other) +{ + this->d = other.d; + other.d = nullptr; +} + +ws_server& ws_server::operator=(ws_server && other) +{ + if (this != &other) + { + delete this->d; + this->d = other.d; + other.d = nullptr; + } + + return *this; +} + +void ws_server::service() +{ + lws_service(d->context, 0); +} + +void ws_server::interrupt() +{ + lws_cancel_service(d->context); +} + + +} \ No newline at end of file diff --git a/src/webfuse/ws/server.hpp b/src/webfuse/ws/server.hpp new file mode 100644 index 0000000..fd752ac --- /dev/null +++ b/src/webfuse/ws/server.hpp @@ -0,0 +1,27 @@ +#ifndef WEBFUSE_WSSERVER_HPP +#define WEBFUSE_WSSERBER_HPP + +#include "webfuse/ws/config.hpp" + +namespace webfuse +{ + +class ws_server +{ + ws_server(ws_server const &) = delete; + ws_server& operator=(ws_server const &) = delete; +public: + ws_server(ws_config const & config); + ~ws_server(); + ws_server(ws_server && other); + ws_server& operator=(ws_server && other); + void service(); + void interrupt(); +private: + class detail; + detail * d; +}; + +} + +#endif