fixed unit tests; added logging support; allow to specify filesystem name

pull/4/head
Falk Werner 4 years ago
parent 8140afe2ab
commit c26342cefd

@ -16,6 +16,7 @@ struct config
char * url; char * url;
struct wfp_client_config * client_config; struct wfp_client_config * client_config;
bool show_help; bool show_help;
bool is_verbose;
}; };
enum fs_entry_type enum fs_entry_type
@ -37,6 +38,8 @@ struct fs_entry
struct fs struct fs
{ {
bool is_verbose;
bool connection_closed;
struct fs_entry const * entries; struct fs_entry const * entries;
}; };
@ -52,6 +55,8 @@ static void show_help()
"\t-u, --url URL of webfuse server (required)\n" "\t-u, --url URL of webfuse server (required)\n"
"\t-k, --key_path Path to private key of provider (default: not set, TLS disabled)\n" "\t-k, --key_path Path to private key of provider (default: not set, TLS disabled)\n"
"\t-c, --cert_path Path to certificate of provider (defautl: not set, TLS disabled)\n" "\t-c, --cert_path Path to certificate of provider (defautl: not set, TLS disabled)\n"
"\t-n, --filesystem_name Name of the filesystem (default: \"cprovider\")\n"
"\t-v, --verbose print additional log messages\n"
"\t-h, --help prints this message\n" "\t-h, --help prints this message\n"
"\n" "\n"
"Example:\n" "Example:\n"
@ -70,16 +75,20 @@ static int parse_arguments(
{"url", required_argument, NULL, 'u'}, {"url", required_argument, NULL, 'u'},
{"key_path", required_argument, NULL, 'k'}, {"key_path", required_argument, NULL, 'k'},
{"cert_path", required_argument, NULL, 'c'}, {"cert_path", required_argument, NULL, 'c'},
{"filesystem_name", required_argument, NULL, 'n'},
{"verbose", required_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
optind = 0;
opterr = 0;
int result = EXIT_SUCCESS; int result = EXIT_SUCCESS;
bool finished = false; bool finished = false;
while (!finished) while (!finished)
{ {
int option_index = 0; int option_index = 0;
int const c = getopt_long(argc, argv, "u:k:c:h", options, &option_index); int const c = getopt_long(argc, argv, "u:k:c:n:vh", options, &option_index);
switch (c) switch (c)
{ {
@ -100,6 +109,12 @@ static int parse_arguments(
case 'c': case 'c':
wfp_client_config_set_certpath(config->client_config, optarg); wfp_client_config_set_certpath(config->client_config, optarg);
break; break;
case 'n':
wfp_client_config_set_fsname(config->client_config, optarg);
break;
case 'v':
config->is_verbose = true;
break;
default: default:
fprintf(stderr, "error: unknown argument\n"); fprintf(stderr, "error: unknown argument\n");
finished = true; finished = true;
@ -322,11 +337,43 @@ static void on_interrupt(int signal_id)
shutdown_requested = true; shutdown_requested = true;
} }
static void on_connected(void* user_data)
{
struct fs * fs = user_data;
if (fs->is_verbose) { puts("connected"); }
}
static void on_disconnected(void* user_data)
{
struct fs * fs = user_data;
if (fs->is_verbose) { puts("disconnected"); }
fs->connection_closed = true;
}
static void do_log(
void * user_data,
int level,
char const * format,
...)
{
struct fs * fs = user_data;
if (fs->is_verbose)
{
printf("LOG: ");
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
puts("");
}
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
struct config config; struct config config;
config.url = NULL; config.url = NULL;
config.show_help = false; config.show_help = false;
config.is_verbose = false;
config.client_config = wfp_client_config_create(); config.client_config = wfp_client_config_create();
int result = parse_arguments(argc, argv, &config); int result = parse_arguments(argc, argv, &config);
@ -349,6 +396,8 @@ int main(int argc, char* argv[])
struct fs fs = struct fs fs =
{ {
.is_verbose = config.is_verbose,
.connection_closed = false,
.entries = entries .entries = entries
}; };
@ -360,11 +409,14 @@ int main(int argc, char* argv[])
wfp_client_config_set_onreaddir(config.client_config, &fs_readdir); wfp_client_config_set_onreaddir(config.client_config, &fs_readdir);
wfp_client_config_set_onopen(config.client_config, &fs_open); wfp_client_config_set_onopen(config.client_config, &fs_open);
wfp_client_config_set_onread(config.client_config, &fs_read); wfp_client_config_set_onread(config.client_config, &fs_read);
wfp_client_config_set_onconnected(config.client_config, &on_connected);
wfp_client_config_set_ondisconnected(config.client_config, &on_disconnected);
wfp_client_config_set_logger(config.client_config, &do_log);
struct wfp_client * client = wfp_client_create(config.client_config); struct wfp_client * client = wfp_client_create(config.client_config);
wfp_client_connect(client, config.url); wfp_client_connect(client, config.url);
while (!shutdown_requested) while ((!shutdown_requested) && (!fs.connection_closed))
{ {
wfp_client_service(client); wfp_client_service(client);
} }

@ -16,6 +16,12 @@
#include <webfuse_provider/operation/read.h> #include <webfuse_provider/operation/read.h>
#include <webfuse_provider/credentials.h> #include <webfuse_provider/credentials.h>
#ifndef __cplusplus
#include <stdarg.h>
#else
#include <cstdarg>
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
@ -45,6 +51,20 @@ typedef void wfp_connected_fn(
typedef void wfp_disconnected_fn( typedef void wfp_disconnected_fn(
void * user_data); void * user_data);
//------------------------------------------------------------------------------
/// \brief Callback to log
///
/// \param user data user defined context
/// \param level log level
/// \param format format string (see printf)
/// \param ... arguments
//------------------------------------------------------------------------------
typedef void wfp_log_fn(
void * user_data,
int level,
char const * format,
...);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// \brief Creates a new client configuration. /// \brief Creates a new client configuration.
/// ///
@ -232,6 +252,26 @@ extern WFP_API void wfp_client_config_enable_authentication(
struct wfp_client_config * config, struct wfp_client_config * config,
wfp_get_credentials_fn * get_credentials); wfp_get_credentials_fn * get_credentials);
//------------------------------------------------------------------------------
/// \brief Set filesystem name.
///
/// \param config pointer to client configuration
/// \param name Name of the filesystem ("cprovider" will be used if unset)
//------------------------------------------------------------------------------
extern WFP_API void wfp_client_config_set_fsname(
struct wfp_client_config * config,
char const * name);
//------------------------------------------------------------------------------
/// \brief Set logger function.
///
/// \param config pointer to client configuration
/// \param log logger function
//------------------------------------------------------------------------------
extern WFP_API void wfp_client_config_set_logger(
struct wfp_client_config * config,
wfp_log_fn * log);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -165,6 +165,20 @@ void wfp_client_config_enable_authentication(
wfp_impl_client_config_enable_authentication(config, get_credentials); wfp_impl_client_config_enable_authentication(config, get_credentials);
} }
void wfp_client_config_set_fsname(
struct wfp_client_config * config,
char const * name)
{
wfp_impl_client_config_set_fsname(config, name);
}
void wfp_client_config_set_logger(
struct wfp_client_config * config,
wfp_log_fn * log)
{
wfp_impl_client_config_set_logger(config, log);
}
// protocol // protocol

@ -30,7 +30,7 @@ struct wfp_client * wfp_impl_client_create(
wfp_impl_lwslog_disable(); wfp_impl_lwslog_disable();
struct wfp_client * client = malloc(sizeof(struct wfp_client)); struct wfp_client * client = malloc(sizeof(struct wfp_client));
wfp_impl_client_protocol_init(&client->protocol, &config->provider, config->user_data); wfp_impl_client_protocol_init(&client->protocol, &config->provider, config->fs_name, config->user_data);
memset(client->protocols, 0, sizeof(struct lws_protocols) * WFP_CLIENT_PROTOCOL_COUNT); memset(client->protocols, 0, sizeof(struct lws_protocols) * WFP_CLIENT_PROTOCOL_COUNT);
wfp_impl_client_protocol_init_lws(&client->protocol, &client->protocols[0]); wfp_impl_client_protocol_init_lws(&client->protocol, &client->protocols[0]);

@ -11,6 +11,7 @@ struct wfp_client_config * wfp_impl_client_config_create(void)
config->key_path = NULL; config->key_path = NULL;
config->cert_path = NULL; config->cert_path = NULL;
config->ca_filepath = NULL; config->ca_filepath = NULL;
config->fs_name = strdup("cprovider");
return config; return config;
} }
@ -18,6 +19,7 @@ struct wfp_client_config * wfp_impl_client_config_create(void)
void wfp_impl_client_config_dispose( void wfp_impl_client_config_dispose(
struct wfp_client_config * config) struct wfp_client_config * config)
{ {
free(config->fs_name);
free(config->key_path); free(config->key_path);
free(config->cert_path); free(config->cert_path);
free(config->ca_filepath); free(config->ca_filepath);
@ -117,3 +119,18 @@ void wfp_impl_client_config_enable_authentication(
{ {
config->provider.get_credentials = get_credentials; config->provider.get_credentials = get_credentials;
} }
void wfp_impl_client_config_set_fsname(
struct wfp_client_config * config,
char const * name)
{
free(config->fs_name);
config->fs_name = strdup(name);
}
void wfp_impl_client_config_set_logger(
struct wfp_client_config * config,
wfp_log_fn * log)
{
config->provider.log = log;
}

@ -16,6 +16,7 @@ struct wfp_client_config
char * key_path; char * key_path;
char * cert_path; char * cert_path;
char * ca_filepath; char * ca_filepath;
char * fs_name;
}; };
extern struct wfp_client_config * wfp_impl_client_config_create(void); extern struct wfp_client_config * wfp_impl_client_config_create(void);
@ -75,6 +76,14 @@ extern void wfp_impl_client_config_enable_authentication(
struct wfp_client_config * config, struct wfp_client_config * config,
wfp_get_credentials_fn * get_credentials); wfp_get_credentials_fn * get_credentials);
extern void wfp_impl_client_config_set_fsname(
struct wfp_client_config * config,
char const * name);
extern void wfp_impl_client_config_set_logger(
struct wfp_client_config * config,
wfp_log_fn * log);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -75,11 +75,14 @@ wfp_impl_client_protocol_on_add_filesystem_finished(
if (NULL != result) if (NULL != result)
{ {
protocol->provider.log(protocol->user_data, 0, "filesystem added");
protocol->provider.log(protocol->user_data, 0, "handshake finished");
protocol->is_connected = true; protocol->is_connected = true;
protocol->provider.connected(protocol->user_data); protocol->provider.connected(protocol->user_data);
} }
else else
{ {
protocol->provider.log(protocol->user_data, 0, "add filesystem failed");
protocol->is_shutdown_requested = true; protocol->is_shutdown_requested = true;
lws_callback_on_writable(protocol->wsi); lws_callback_on_writable(protocol->wsi);
} }
@ -88,13 +91,15 @@ wfp_impl_client_protocol_on_add_filesystem_finished(
static void wfp_impl_client_protocol_add_filesystem( static void wfp_impl_client_protocol_add_filesystem(
struct wfp_client_protocol * protocol) struct wfp_client_protocol * protocol)
{ {
protocol->provider.log(protocol->user_data, 0, "begin add filesystem");
wfp_jsonrpc_proxy_invoke( wfp_jsonrpc_proxy_invoke(
protocol->proxy, protocol->proxy,
&wfp_impl_client_protocol_on_add_filesystem_finished, &wfp_impl_client_protocol_on_add_filesystem_finished,
protocol, protocol,
"add_filesystem", "add_filesystem",
"s", "s",
"cprovider"); protocol->fs_name);
} }
static void static void
@ -108,10 +113,12 @@ wfp_impl_client_protocol_on_authenticate_finished(
if (NULL != result) if (NULL != result)
{ {
protocol->provider.log(protocol->user_data, 0, "authentication finished");
wfp_impl_client_protocol_add_filesystem(protocol); wfp_impl_client_protocol_add_filesystem(protocol);
} }
else else
{ {
protocol->provider.log(protocol->user_data, 0, "authentication failed");
protocol->is_shutdown_requested = true; protocol->is_shutdown_requested = true;
lws_callback_on_writable(protocol->wsi); lws_callback_on_writable(protocol->wsi);
} }
@ -120,6 +127,8 @@ wfp_impl_client_protocol_on_authenticate_finished(
static void wfp_impl_client_protocol_authenticate( static void wfp_impl_client_protocol_authenticate(
struct wfp_client_protocol * protocol) struct wfp_client_protocol * protocol)
{ {
protocol->provider.log(protocol->user_data, 0, "begin authenticate");
struct wfp_credentials credentials; struct wfp_credentials credentials;
wfp_impl_credentials_init(&credentials); wfp_impl_credentials_init(&credentials);
@ -141,12 +150,15 @@ static void wfp_impl_client_protocol_authenticate(
static void wfp_impl_client_protocol_handshake( static void wfp_impl_client_protocol_handshake(
struct wfp_client_protocol * protocol) struct wfp_client_protocol * protocol)
{ {
protocol->provider.log(protocol->user_data, 0, "begin connection handshake");
if (wfp_impl_provider_is_authentication_enabled(&protocol->provider)) if (wfp_impl_provider_is_authentication_enabled(&protocol->provider))
{ {
wfp_impl_client_protocol_authenticate(protocol); wfp_impl_client_protocol_authenticate(protocol);
} }
else else
{ {
protocol->provider.log(protocol->user_data, 0, "skip authentication");
wfp_impl_client_protocol_add_filesystem(protocol); wfp_impl_client_protocol_add_filesystem(protocol);
} }
} }
@ -169,18 +181,22 @@ static int wfp_impl_client_protocol_callback(
switch (reason) switch (reason)
{ {
case LWS_CALLBACK_CLIENT_ESTABLISHED: case LWS_CALLBACK_CLIENT_ESTABLISHED:
protocol->provider.log(protocol->user_data, 0, "connection established");
wfp_impl_client_protocol_handshake(protocol); wfp_impl_client_protocol_handshake(protocol);
break; break;
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
protocol->provider.log(protocol->user_data, 0, "connect error");
protocol->is_connected = false; protocol->is_connected = false;
protocol->provider.disconnected(protocol->user_data); protocol->provider.disconnected(protocol->user_data);
break; break;
case LWS_CALLBACK_CLIENT_CLOSED: case LWS_CALLBACK_CLIENT_CLOSED:
protocol->provider.log(protocol->user_data, 0, "connection closed");
protocol->is_connected = false; protocol->is_connected = false;
protocol->provider.disconnected(protocol->user_data); protocol->provider.disconnected(protocol->user_data);
protocol->wsi = NULL; protocol->wsi = NULL;
break; break;
case LWS_CALLBACK_CLIENT_RECEIVE: case LWS_CALLBACK_CLIENT_RECEIVE:
protocol->provider.log(protocol->user_data, 0, "received: \"%.*s\"", len, in);
wfp_impl_client_protocol_process(protocol, in, len); wfp_impl_client_protocol_process(protocol, in, len);
break; break;
case LWS_CALLBACK_SERVER_WRITEABLE: case LWS_CALLBACK_SERVER_WRITEABLE:
@ -194,8 +210,10 @@ static int wfp_impl_client_protocol_callback(
} }
else if (!wfp_slist_empty(&protocol->messages)) else if (!wfp_slist_empty(&protocol->messages))
{ {
struct wfp_slist_item * item = wfp_slist_remove_first(&protocol->messages); struct wfp_slist_item * item = wfp_slist_remove_first(&protocol->messages);
struct wfp_message * message = wfp_container_of(item, struct wfp_message, item); struct wfp_message * message = wfp_container_of(item, struct wfp_message, item);
protocol->provider.log(protocol->user_data, 0, "send: \"%.*s\"", message->length, message->data);
lws_write(wsi, (unsigned char*) message->data, message->length, LWS_WRITE_TEXT); lws_write(wsi, (unsigned char*) message->data, message->length, LWS_WRITE_TEXT);
wfp_message_dispose(message); wfp_message_dispose(message);
@ -229,6 +247,7 @@ static void wfp_impl_client_protocol_send(
void wfp_impl_client_protocol_init( void wfp_impl_client_protocol_init(
struct wfp_client_protocol * protocol, struct wfp_client_protocol * protocol,
struct wfp_provider const * provider, struct wfp_provider const * provider,
char const * fs_name,
void * user_data) void * user_data)
{ {
protocol->is_connected = false; protocol->is_connected = false;
@ -243,6 +262,7 @@ void wfp_impl_client_protocol_init(
protocol->timer_manager = wfp_timer_manager_create(); protocol->timer_manager = wfp_timer_manager_create();
protocol->proxy = wfp_jsonrpc_proxy_create(protocol->timer_manager, WFP_DEFAULT_TIMEOUT, &wfp_impl_client_protocol_send, protocol); protocol->proxy = wfp_jsonrpc_proxy_create(protocol->timer_manager, WFP_DEFAULT_TIMEOUT, &wfp_impl_client_protocol_send, protocol);
protocol->fs_name = strdup(fs_name);
protocol->user_data = user_data; protocol->user_data = user_data;
wfp_impl_provider_init_from_prototype(&protocol->provider, provider); wfp_impl_provider_init_from_prototype(&protocol->provider, provider);
} }
@ -253,13 +273,14 @@ void wfp_impl_client_protocol_cleanup(
wfp_jsonrpc_proxy_dispose(protocol->proxy); wfp_jsonrpc_proxy_dispose(protocol->proxy);
wfp_timer_manager_dispose(protocol->timer_manager); wfp_timer_manager_dispose(protocol->timer_manager);
wfp_message_queue_cleanup(&protocol->messages); wfp_message_queue_cleanup(&protocol->messages);
free(protocol->fs_name);
} }
struct wfp_client_protocol * wfp_impl_client_protocol_create( struct wfp_client_protocol * wfp_impl_client_protocol_create(
struct wfp_client_config const * config) struct wfp_client_config const * config)
{ {
struct wfp_client_protocol * protocol = malloc(sizeof(struct wfp_client_protocol)); struct wfp_client_protocol * protocol = malloc(sizeof(struct wfp_client_protocol));
wfp_impl_client_protocol_init(protocol, &config->provider, config->user_data); wfp_impl_client_protocol_init(protocol, &config->provider, config->fs_name, config->user_data);
return protocol; return protocol;
} }

@ -23,6 +23,7 @@ struct wfp_client_protocol
bool is_shutdown_requested; bool is_shutdown_requested;
struct wfp_request request; struct wfp_request request;
struct wfp_provider provider; struct wfp_provider provider;
char * fs_name;
void * user_data; void * user_data;
struct lws * wsi; struct lws * wsi;
struct wfp_timer_manager * timer_manager; struct wfp_timer_manager * timer_manager;
@ -33,6 +34,7 @@ struct wfp_client_protocol
extern void wfp_impl_client_protocol_init( extern void wfp_impl_client_protocol_init(
struct wfp_client_protocol * protocol, struct wfp_client_protocol * protocol,
struct wfp_provider const * provider, struct wfp_provider const * provider,
char const * fs_name,
void * user_data); void * user_data);
extern void wfp_impl_client_protocol_cleanup( extern void wfp_impl_client_protocol_cleanup(

@ -70,6 +70,7 @@ void wfp_impl_provider_init(
provider->connected = &wfp_impl_connected_default; provider->connected = &wfp_impl_connected_default;
provider->disconnected = &wfp_impl_disconnected_default; provider->disconnected = &wfp_impl_disconnected_default;
provider->get_credentials = NULL; provider->get_credentials = NULL;
provider->log = &wfp_impl_log_default;
} }
void wfp_impl_provider_init_from_prototype( void wfp_impl_provider_init_from_prototype(
@ -85,6 +86,7 @@ void wfp_impl_provider_init_from_prototype(
provider->connected = prototype->connected; provider->connected = prototype->connected;
provider->disconnected = prototype->disconnected; provider->disconnected = prototype->disconnected;
provider->get_credentials = prototype->get_credentials; provider->get_credentials = prototype->get_credentials;
provider->log = prototype->log;
} }
void wfp_impl_provider_invoke( void wfp_impl_provider_invoke(
@ -120,9 +122,22 @@ void wfp_impl_disconnected_default(
// empty // empty
} }
void wfp_impl_log_default(
void * user_data,
int level,
char const * format,
...)
{
(void) user_data;
(void) level;
(void) format;
// empty
}
bool wfp_impl_provider_is_authentication_enabled( bool wfp_impl_provider_is_authentication_enabled(
struct wfp_provider * provider) struct wfp_provider * provider)
{ {
return (NULL != provider->get_credentials); return (NULL != provider->get_credentials);
} }

@ -3,6 +3,9 @@
#ifndef __cplusplus #ifndef __cplusplus
#include <stdbool.h> #include <stdbool.h>
#include <stdarg.h>
#else
#include <cstdarg>
#endif #endif
#include "webfuse_provider/client_config.h" #include "webfuse_provider/client_config.h"
@ -26,6 +29,7 @@ struct wfp_provider
wfp_close_fn * close; wfp_close_fn * close;
wfp_read_fn * read; wfp_read_fn * read;
wfp_get_credentials_fn * get_credentials; wfp_get_credentials_fn * get_credentials;
wfp_log_fn * log;
}; };
struct wfp_impl_invokation_context struct wfp_impl_invokation_context
@ -56,6 +60,12 @@ extern void wfp_impl_connected_default(
extern void wfp_impl_disconnected_default( extern void wfp_impl_disconnected_default(
void * user_data); void * user_data);
extern void wfp_impl_log_default(
void * user_data,
int level,
char const * format,
...);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -1,4 +1,5 @@
project('webfuse-provider', 'c', 'cpp', version: '0.3.0', license: 'LGPL-3.0+') project('webfuse-provider', 'c', 'cpp', version: '0.3.0', license: 'LGPL-3.0+',
default_options: ['c_std=gnu99', 'cpp_std=gnu++14'])
without_tests = get_option('without_tests') without_tests = get_option('without_tests')
without_examples = get_option('without_examples') without_examples = get_option('without_examples')

@ -13,8 +13,10 @@
#include <libwebsockets.h> #include <libwebsockets.h>
#include <cstring> #include <cstring>
#include <queue>
#include <sstream> #include <sstream>
#include <thread> #include <thread>
#include <mutex>
using webfuse_test::WsServer; using webfuse_test::WsServer;
using webfuse_test::MockProviderClient; using webfuse_test::MockProviderClient;
@ -37,7 +39,10 @@ class ClientProtocolFixture
public: public:
explicit ClientProtocolFixture(IProviderClient& client, bool enableAuthentication = false) explicit ClientProtocolFixture(IProviderClient& client, bool enableAuthentication = false)
{ {
server = new WsServer(WFP_PROTOCOL_NAME_ADAPTER_SERVER); server = new WsServer(WFP_PROTOCOL_NAME_ADAPTER_SERVER,
[&](std::string const& message) mutable {
OnMessageReceived(message);
});
config = wfp_client_config_create(); config = wfp_client_config_create();
client.AttachTo(config, enableAuthentication); client.AttachTo(config, enableAuthentication);
@ -85,15 +90,36 @@ public:
server->SendMessage(request); server->SendMessage(request);
} }
void OnMessageReceived(std::string const message)
{
{
std::lock_guard<std::mutex> lock(mutex);
recv_queue.push(message);
}
lws_cancel_service(context);
}
std::string ReceiveMessage()
{
std::lock_guard<std::mutex> lock(mutex);
std::string result;
if (!recv_queue.empty())
{
result = recv_queue.front();
recv_queue.pop();
}
return result;
}
std::string ReceiveMessageFromClient() std::string ReceiveMessageFromClient()
{ {
TimeoutWatcher watcher(DEFAULT_TIMEOUT); TimeoutWatcher watcher(DEFAULT_TIMEOUT);
std::string result = server->ReceiveMessage(); std::string result = ReceiveMessage();
while (result.empty()) while (result.empty())
{ {
watcher.check(); watcher.check();
lws_service(context, 0); lws_service(context, 0);
result = server->ReceiveMessage(); result = ReceiveMessage();
} }
return result; return result;
@ -171,6 +197,8 @@ private:
struct lws_context_creation_info info; struct lws_context_creation_info info;
struct lws_protocols protocols[2]; struct lws_protocols protocols[2];
struct lws_context * context; struct lws_context * context;
std::queue<std::string> recv_queue;
std::mutex mutex;
}; };

@ -101,12 +101,10 @@ public:
info.mounts = NULL; info.mounts = NULL;
info.protocols = protocols; info.protocols = protocols;
info.vhost_name = "localhost"; info.vhost_name = "localhost";
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;
info.options |= LWS_SERVER_OPTION_EXPLICIT_VHOSTS; info.options |= LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
context = lws_create_context(&info);
if (use_tls) if (use_tls)
{ {
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
@ -114,6 +112,8 @@ public:
info.ssl_private_key_filepath = "server-key.pem"; info.ssl_private_key_filepath = "server-key.pem";
} }
context = lws_create_context(&info);
struct lws_vhost * vhost = lws_create_vhost(context, &info); struct lws_vhost * vhost = lws_create_vhost(context, &info);
int port = lws_get_vhost_port(vhost); int port = lws_get_vhost_port(vhost);
std::ostringstream stream; std::ostringstream stream;

@ -31,7 +31,10 @@ class WsServer::Private : IServer
Private(Private const &) = delete; Private(Private const &) = delete;
Private & operator=(Private const &) = delete; Private & operator=(Private const &) = delete;
public: public:
Private(std::string const & protocol, int port); Private(
std::string const & protocol,
std::function<void(std::string const &)> handleMessage,
int port);
~Private(); ~Private();
bool IsConnected(); bool IsConnected();
std::string GetUrl() const; std::string GetUrl() const;
@ -45,6 +48,7 @@ public:
private: private:
static void run(Private * self); static void run(Private * self);
std::string protocol_; std::string protocol_;
std::function<void(std::string const &)> handleMessage_;
int port_; int port_;
bool is_connected; bool is_connected;
bool is_shutdown_requested; bool is_shutdown_requested;
@ -55,7 +59,6 @@ private:
std::thread context; std::thread context;
std::mutex mutex; std::mutex mutex;
std::queue<std::string> writeQueue; std::queue<std::string> writeQueue;
std::queue<std::string> recvQueue;
}; };
} }
@ -107,8 +110,11 @@ static int wfp_test_utils_ws_server_callback(
namespace webfuse_test namespace webfuse_test
{ {
WsServer::WsServer(std::string const & protocol, int port) WsServer::WsServer(
: d(new Private(protocol, port)) std::string const & protocol,
std::function<void(std::string const &)> handleMessage,
int port)
: d(new Private(protocol, handleMessage, port))
{ {
} }
@ -128,19 +134,18 @@ void WsServer::SendMessage(std::string const & message)
d->SendMessage(message); d->SendMessage(message);
} }
std::string WsServer::ReceiveMessage()
{
return d->ReceiveMessage();
}
std::string WsServer::GetUrl() const std::string WsServer::GetUrl() const
{ {
return d->GetUrl(); return d->GetUrl();
} }
WsServer::Private::Private(std::string const & protocol, int port) WsServer::Private::Private(
std::string const & protocol,
std::function<void(std::string const &)> handleMessage,
int port)
: protocol_(protocol) : protocol_(protocol)
, handleMessage_(handleMessage)
, port_(port) , port_(port)
, is_connected(false) , is_connected(false)
, is_shutdown_requested(false) , is_shutdown_requested(false)
@ -160,7 +165,7 @@ WsServer::Private::Private(std::string const & protocol, int port)
info.mounts = NULL; info.mounts = NULL;
info.protocols =ws_protocols; info.protocols =ws_protocols;
info.vhost_name = "localhost"; info.vhost_name = "localhost";
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;
info.options |= LWS_SERVER_OPTION_EXPLICIT_VHOSTS; info.options |= LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
@ -270,25 +275,16 @@ void WsServer::Private::SendMessage(std::string const & message)
void WsServer::Private::OnMessageReceived(struct lws * wsi, char const * data, size_t length) void WsServer::Private::OnMessageReceived(struct lws * wsi, char const * data, size_t length)
{ {
std::unique_lock<std::mutex> lock(mutex); bool handleMessage;
if (wsi == wsi_)
{ {
recvQueue.push(std::string(data, length));
}
}
std::string WsServer::Private::ReceiveMessage()
{
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
handleMessage = (wsi == wsi_);
}
std::string message; if (handleMessage)
if (!recvQueue.empty())
{ {
message = recvQueue.front(); handleMessage_(std::string(data, length));
recvQueue.pop();
} }
return message;
} }
std::string WsServer::Private::GetUrl() const std::string WsServer::Private::GetUrl() const

@ -2,6 +2,7 @@
#define WFP_TEST_UTILS_WS_SERVER_HPP #define WFP_TEST_UTILS_WS_SERVER_HPP
#include <string> #include <string>
#include <functional>
namespace webfuse_test namespace webfuse_test
{ {
@ -11,12 +12,14 @@ class WsServer
WsServer(WsServer const &) = delete; WsServer(WsServer const &) = delete;
WsServer & operator=(WsServer const &) = delete; WsServer & operator=(WsServer const &) = delete;
public: public:
WsServer(std::string const & protocol, int port = 0); WsServer(
std::string const & protocol,
std::function<void(std::string const &)> handleMessage,
int port = 0);
~WsServer(); ~WsServer();
bool IsConnected(); bool IsConnected();
std::string GetUrl() const; std::string GetUrl() const;
void SendMessage(std::string const & message); void SendMessage(std::string const & message);
std::string ReceiveMessage();
private: private:
class Private; class Private;
Private * d; Private * d;

Loading…
Cancel
Save