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

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

@ -16,6 +16,7 @@ struct config
char * url;
struct wfp_client_config * client_config;
bool show_help;
bool is_verbose;
};
enum fs_entry_type
@ -37,6 +38,8 @@ struct fs_entry
struct fs
{
bool is_verbose;
bool connection_closed;
struct fs_entry const * entries;
};
@ -49,10 +52,12 @@ static void show_help()
"Usage: webfuse-provider -u <url> [-k <key_path>] [-c <cert_path>]\n"
"\n"
"Options:\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-c, --cert_path Path to certificate of provider (defautl: not set, TLS disabled)\n"
"\t-h, --help prints this message\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-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"
"\n"
"Example:\n"
"\twebfuse-provider -u ws://localhost:8080/\n"
@ -70,16 +75,20 @@ static int parse_arguments(
{"url", required_argument, NULL, 'u'},
{"key_path", required_argument, NULL, 'k'},
{"cert_path", required_argument, NULL, 'c'},
{"filesystem_name", required_argument, NULL, 'n'},
{"verbose", required_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
optind = 0;
opterr = 0;
int result = EXIT_SUCCESS;
bool finished = false;
while (!finished)
{
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)
{
@ -100,6 +109,12 @@ static int parse_arguments(
case 'c':
wfp_client_config_set_certpath(config->client_config, optarg);
break;
case 'n':
wfp_client_config_set_fsname(config->client_config, optarg);
break;
case 'v':
config->is_verbose = true;
break;
default:
fprintf(stderr, "error: unknown argument\n");
finished = true;
@ -133,7 +148,7 @@ static struct fs_entry const * fs_getentry(
{
return entry;
}
}
}
return NULL;
}
@ -269,7 +284,7 @@ static void fs_open(
else
{
wfp_respond_error(request, WFP_BAD_ACCESS_DENIED);
}
}
}
else
{
@ -306,7 +321,7 @@ static void fs_read(
else
{
wfp_respond_error(request, WFP_BAD);
}
}
}
else
{
@ -322,11 +337,43 @@ static void on_interrupt(int signal_id)
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[])
{
struct config config;
config.url = NULL;
config.show_help = false;
config.is_verbose = false;
config.client_config = wfp_client_config_create();
int result = parse_arguments(argc, argv, &config);
@ -349,6 +396,8 @@ int main(int argc, char* argv[])
struct fs fs =
{
.is_verbose = config.is_verbose,
.connection_closed = false,
.entries = entries
};
@ -360,17 +409,20 @@ int main(int argc, char* argv[])
wfp_client_config_set_onreaddir(config.client_config, &fs_readdir);
wfp_client_config_set_onopen(config.client_config, &fs_open);
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);
wfp_client_connect(client, config.url);
while (!shutdown_requested)
while ((!shutdown_requested) && (!fs.connection_closed))
{
wfp_client_service(client);
}
wfp_client_dispose(client);
}
}
if (config.show_help)
{
@ -380,4 +432,4 @@ int main(int argc, char* argv[])
free(config.url);
wfp_client_config_dispose(config.client_config);
return result;
}
}

@ -16,6 +16,12 @@
#include <webfuse_provider/operation/read.h>
#include <webfuse_provider/credentials.h>
#ifndef __cplusplus
#include <stdarg.h>
#else
#include <cstdarg>
#endif
#ifdef __cplusplus
extern "C"
{
@ -45,6 +51,20 @@ typedef void wfp_connected_fn(
typedef void wfp_disconnected_fn(
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.
///
@ -225,13 +245,33 @@ extern WFP_API void wfp_client_config_set_onread(
/// \brief Enabled authentication.
///
/// \param config pointer to client configuration
/// \param get_credentials pointer to function providing credentials when
/// \param get_credentials pointer to function providing credentials when
// needed.
//------------------------------------------------------------------------------
extern WFP_API void wfp_client_config_enable_authentication(
struct wfp_client_config * config,
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
}
#endif

@ -165,6 +165,20 @@ void wfp_client_config_enable_authentication(
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

@ -28,9 +28,9 @@ struct wfp_client * wfp_impl_client_create(
struct wfp_client_config * config)
{
wfp_impl_lwslog_disable();
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);
wfp_impl_client_protocol_init_lws(&client->protocol, &client->protocols[0]);
@ -65,7 +65,7 @@ void wfp_impl_client_dispose(
struct wfp_client * client)
{
lws_context_destroy(client->context);
wfp_impl_client_protocol_cleanup(&client->protocol);
wfp_impl_client_protocol_cleanup(&client->protocol);
free(client);
}

@ -11,6 +11,7 @@ struct wfp_client_config * wfp_impl_client_config_create(void)
config->key_path = NULL;
config->cert_path = NULL;
config->ca_filepath = NULL;
config->fs_name = strdup("cprovider");
return config;
}
@ -18,6 +19,7 @@ struct wfp_client_config * wfp_impl_client_config_create(void)
void wfp_impl_client_config_dispose(
struct wfp_client_config * config)
{
free(config->fs_name);
free(config->key_path);
free(config->cert_path);
free(config->ca_filepath);
@ -52,7 +54,7 @@ void wfp_impl_client_config_set_ca_filepath(
char const * ca_filepath)
{
free(config->ca_filepath);
config->ca_filepath = strdup(ca_filepath);
config->ca_filepath = strdup(ca_filepath);
}
void wfp_impl_client_config_set_onconnected(
@ -117,3 +119,18 @@ void wfp_impl_client_config_enable_authentication(
{
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 * cert_path;
char * ca_filepath;
char * fs_name;
};
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,
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
}
#endif

@ -35,7 +35,7 @@ static void wfp_impl_client_protocol_respond(
}
static void wfp_impl_client_protocol_process(
struct wfp_client_protocol * protocol,
struct wfp_client_protocol * protocol,
char * data,
size_t length)
{
@ -64,62 +64,71 @@ static void wfp_impl_client_protocol_process(
}
}
static void
static void
wfp_impl_client_protocol_on_add_filesystem_finished(
void * user_data,
struct wfp_json const * result,
struct wfp_jsonrpc_error const * WFP_UNUSED_PARAM(error))
struct wfp_jsonrpc_error const * WFP_UNUSED_PARAM(error))
{
struct wfp_client_protocol * protocol = user_data;
if (NULL == protocol->wsi) { return; }
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->provider.connected(protocol->user_data);
}
else
{
protocol->provider.log(protocol->user_data, 0, "add filesystem failed");
protocol->is_shutdown_requested = true;
lws_callback_on_writable(protocol->wsi);
}
}
}
static void wfp_impl_client_protocol_add_filesystem(
struct wfp_client_protocol * protocol)
{
protocol->provider.log(protocol->user_data, 0, "begin add filesystem");
wfp_jsonrpc_proxy_invoke(
protocol->proxy,
protocol->proxy,
&wfp_impl_client_protocol_on_add_filesystem_finished,
protocol,
"add_filesystem",
"s",
"cprovider");
protocol->fs_name);
}
static void
static void
wfp_impl_client_protocol_on_authenticate_finished(
void * user_data,
struct wfp_json const * result,
struct wfp_jsonrpc_error const * WFP_UNUSED_PARAM(error))
struct wfp_jsonrpc_error const * WFP_UNUSED_PARAM(error))
{
struct wfp_client_protocol * protocol = user_data;
if (NULL == protocol->wsi) { return; }
if (NULL != result)
{
protocol->provider.log(protocol->user_data, 0, "authentication finished");
wfp_impl_client_protocol_add_filesystem(protocol);
}
else
{
protocol->provider.log(protocol->user_data, 0, "authentication failed");
protocol->is_shutdown_requested = true;
lws_callback_on_writable(protocol->wsi);
}
}
}
static void wfp_impl_client_protocol_authenticate(
struct wfp_client_protocol * protocol)
{
protocol->provider.log(protocol->user_data, 0, "begin authenticate");
struct wfp_credentials credentials;
wfp_impl_credentials_init(&credentials);
@ -128,10 +137,10 @@ static void wfp_impl_client_protocol_authenticate(
char const * cred_type = wfp_impl_credentials_get_type(&credentials);
wfp_jsonrpc_proxy_invoke(
protocol->proxy,
&wfp_impl_client_protocol_on_authenticate_finished,
protocol,
"authenticate",
protocol->proxy,
&wfp_impl_client_protocol_on_authenticate_finished,
protocol,
"authenticate",
"sj",
cred_type, &wfp_impl_credentials_write, &credentials);
@ -141,12 +150,15 @@ static void wfp_impl_client_protocol_authenticate(
static void wfp_impl_client_protocol_handshake(
struct wfp_client_protocol * protocol)
{
protocol->provider.log(protocol->user_data, 0, "begin connection handshake");
if (wfp_impl_provider_is_authentication_enabled(&protocol->provider))
{
wfp_impl_client_protocol_authenticate(protocol);
}
else
{
protocol->provider.log(protocol->user_data, 0, "skip authentication");
wfp_impl_client_protocol_add_filesystem(protocol);
}
}
@ -159,7 +171,7 @@ static int wfp_impl_client_protocol_callback(
size_t len)
{
int result = 0;
struct lws_protocols const * ws_protocol = lws_get_protocol(wsi);
struct lws_protocols const * ws_protocol = lws_get_protocol(wsi);
struct wfp_client_protocol * protocol = (NULL != ws_protocol) ? ws_protocol->user: NULL;
if (NULL != protocol)
@ -169,24 +181,28 @@ static int wfp_impl_client_protocol_callback(
switch (reason)
{
case LWS_CALLBACK_CLIENT_ESTABLISHED:
protocol->provider.log(protocol->user_data, 0, "connection established");
wfp_impl_client_protocol_handshake(protocol);
break;
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
protocol->provider.log(protocol->user_data, 0, "connect error");
protocol->is_connected = false;
protocol->provider.disconnected(protocol->user_data);
break;
case LWS_CALLBACK_CLIENT_CLOSED:
protocol->provider.log(protocol->user_data, 0, "connection closed");
protocol->is_connected = false;
protocol->provider.disconnected(protocol->user_data);
protocol->provider.disconnected(protocol->user_data);
protocol->wsi = NULL;
break;
case LWS_CALLBACK_CLIENT_RECEIVE:
protocol->provider.log(protocol->user_data, 0, "received: \"%.*s\"", len, in);
wfp_impl_client_protocol_process(protocol, in, len);
break;
case LWS_CALLBACK_SERVER_WRITEABLE:
// fall-through
case LWS_CALLBACK_CLIENT_WRITEABLE:
if (wsi == protocol->wsi)
if (wsi == protocol->wsi)
{
if (protocol->is_shutdown_requested)
{
@ -194,8 +210,10 @@ static int wfp_impl_client_protocol_callback(
}
else if (!wfp_slist_empty(&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);
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);
wfp_message_dispose(message);
@ -207,7 +225,7 @@ static int wfp_impl_client_protocol_callback(
}
break;
default:
break;
break;
}
}
@ -229,6 +247,7 @@ static void wfp_impl_client_protocol_send(
void wfp_impl_client_protocol_init(
struct wfp_client_protocol * protocol,
struct wfp_provider const * provider,
char const * fs_name,
void * user_data)
{
protocol->is_connected = false;
@ -243,6 +262,7 @@ void wfp_impl_client_protocol_init(
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->fs_name = strdup(fs_name);
protocol->user_data = user_data;
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_timer_manager_dispose(protocol->timer_manager);
wfp_message_queue_cleanup(&protocol->messages);
free(protocol->fs_name);
}
struct wfp_client_protocol * wfp_impl_client_protocol_create(
struct wfp_client_config const * config)
{
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;
}
@ -311,7 +332,7 @@ void wfp_impl_client_protocol_connect(
{
protocol->provider.disconnected(protocol->user_data);
}
}
void wfp_impl_client_protocol_disconnect(

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

@ -28,7 +28,7 @@ struct wfp_impl_method
};
static void wfp_impl_provider_invoke_method(
struct wfp_impl_invokation_context * context,
struct wfp_impl_invokation_context * context,
char const * method_name,
struct wfp_json const * params,
int id)
@ -70,6 +70,7 @@ void wfp_impl_provider_init(
provider->connected = &wfp_impl_connected_default;
provider->disconnected = &wfp_impl_disconnected_default;
provider->get_credentials = NULL;
provider->log = &wfp_impl_log_default;
}
void wfp_impl_provider_init_from_prototype(
@ -85,6 +86,7 @@ void wfp_impl_provider_init_from_prototype(
provider->connected = prototype->connected;
provider->disconnected = prototype->disconnected;
provider->get_credentials = prototype->get_credentials;
provider->log = prototype->log;
}
void wfp_impl_provider_invoke(
@ -120,9 +122,22 @@ void wfp_impl_disconnected_default(
// 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(
struct wfp_provider * provider)
{
return (NULL != provider->get_credentials);
}

@ -3,6 +3,9 @@
#ifndef __cplusplus
#include <stdbool.h>
#include <stdarg.h>
#else
#include <cstdarg>
#endif
#include "webfuse_provider/client_config.h"
@ -26,6 +29,7 @@ struct wfp_provider
wfp_close_fn * close;
wfp_read_fn * read;
wfp_get_credentials_fn * get_credentials;
wfp_log_fn * log;
};
struct wfp_impl_invokation_context
@ -49,15 +53,21 @@ extern void wfp_impl_provider_invoke(
extern bool wfp_impl_provider_is_authentication_enabled(
struct wfp_provider * provider);
extern void wfp_impl_connected_default(
void * user_data);
extern void wfp_impl_disconnected_default(
void * user_data);
#ifdef __cplusplus
extern void wfp_impl_log_default(
void * user_data,
int level,
char const * format,
...);
#ifdef __cplusplus
}
#endif
#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_examples = get_option('without_examples')
@ -87,7 +88,7 @@ pkg_config.generate(
if not without_tests
gtest_dep = dependency('gtest', version: '>=1.10.0', fallback: ['gtest', 'gtest_dep'])
gtest_dep = dependency('gtest', version: '>=1.10.0', fallback: ['gtest', 'gtest_dep'])
gmock_main_dep = dependency('gmock_main', version: '>=1.10.0', fallback: ['gtest', 'gmock_main_dep'])
openssl = find_program('openssl')
@ -180,4 +181,4 @@ executable('static-filesystem-provider',
dependencies: [webfuse_provider_dep])
endif
endif

@ -13,8 +13,10 @@
#include <libwebsockets.h>
#include <cstring>
#include <queue>
#include <sstream>
#include <thread>
#include <mutex>
using webfuse_test::WsServer;
using webfuse_test::MockProviderClient;
@ -37,7 +39,10 @@ class ClientProtocolFixture
public:
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();
client.AttachTo(config, enableAuthentication);
@ -67,7 +72,7 @@ public:
{
TimeoutWatcher watcher(DEFAULT_TIMEOUT);
wfp_client_protocol_connect(protocol, context, server->GetUrl().c_str());
wfp_client_protocol_connect(protocol, context, server->GetUrl().c_str());
while (!server->IsConnected())
{
watcher.check();
@ -85,15 +90,36 @@ public:
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()
{
TimeoutWatcher watcher(DEFAULT_TIMEOUT);
std::string result = server->ReceiveMessage();
std::string result = ReceiveMessage();
while (result.empty())
{
watcher.check();
lws_service(context, 0);
result = server->ReceiveMessage();
result = ReceiveMessage();
}
return result;
@ -128,7 +154,7 @@ public:
wfp_json const * username = wfp_impl_json_object_get(credentials, "username");
ASSERT_TRUE(wfp_impl_json_is_string(username));
ASSERT_STREQ(expected_username.c_str(), wfp_impl_json_string_get(username));
wfp_json const * password = wfp_impl_json_object_get(credentials, "password");
ASSERT_TRUE(wfp_impl_json_is_string(password));
ASSERT_STREQ(expected_password.c_str(), wfp_impl_json_string_get(password));
@ -171,6 +197,8 @@ private:
struct lws_context_creation_info info;
struct lws_protocols protocols[2];
struct lws_context * context;
std::queue<std::string> recv_queue;
std::mutex mutex;
};
@ -217,7 +245,7 @@ TEST(client_protocol, connect_with_username_authentication)
EXPECT_CALL(provider, OnConnected()).Times(AtMost(1));
EXPECT_CALL(provider, OnDisconnected()).Times(1);
EXPECT_CALL(provider, GetCredentials(_)).Times(1).WillOnce(Invoke(GetCredentials));
fixture.Connect();
if (HasFatalFailure()) { return; }
@ -253,4 +281,4 @@ TEST(client_protocol, getattr)
ASSERT_FALSE(response.empty());
fixture.Disconnect();
}
}

@ -101,12 +101,10 @@ public:
info.mounts = NULL;
info.protocols = protocols;
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_EXPLICIT_VHOSTS;
context = lws_create_context(&info);
if (use_tls)
{
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
@ -114,9 +112,11 @@ public:
info.ssl_private_key_filepath = "server-key.pem";
}
context = lws_create_context(&info);
struct lws_vhost * vhost = lws_create_vhost(context, &info);
int port = lws_get_vhost_port(vhost);
std::ostringstream stream;
std::ostringstream stream;
stream << (use_tls ? "wss://" : "ws://") << "localhost:" << port << "/";
url = stream.str();
@ -149,7 +149,7 @@ public:
std::string Invoke(std::string const & method, std::string const & params)
{
std::promise<std::string> response;
{
{
std::unique_lock<std::mutex> lock(mutex);
message = &response;
id++;
@ -220,7 +220,7 @@ public:
lws_callback_on_writable(wsi);
}
}
wfp_impl_json_doc_dispose(doc);
}
}
@ -337,4 +337,4 @@ std::string WebfuseServer::ReadDir(int inode)
return d->Invoke("readdir", params.str());
}
}
}

@ -31,7 +31,10 @@ class WsServer::Private : IServer
Private(Private const &) = delete;
Private & operator=(Private const &) = delete;
public:
Private(std::string const & protocol, int port);
Private(
std::string const & protocol,
std::function<void(std::string const &)> handleMessage,
int port);
~Private();
bool IsConnected();
std::string GetUrl() const;
@ -45,6 +48,7 @@ public:
private:
static void run(Private * self);
std::string protocol_;
std::function<void(std::string const &)> handleMessage_;
int port_;
bool is_connected;
bool is_shutdown_requested;
@ -55,7 +59,6 @@ private:
std::thread context;
std::mutex mutex;
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
{
WsServer::WsServer(std::string const & protocol, int port)
: d(new Private(protocol, port))
WsServer::WsServer(
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);
}
std::string WsServer::ReceiveMessage()
{
return d->ReceiveMessage();
}
std::string WsServer::GetUrl() const
{
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)
, handleMessage_(handleMessage)
, port_(port)
, is_connected(false)
, is_shutdown_requested(false)
@ -160,7 +165,7 @@ WsServer::Private::Private(std::string const & protocol, int port)
info.mounts = NULL;
info.protocols =ws_protocols;
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_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)
{
std::unique_lock<std::mutex> lock(mutex);
if (wsi == wsi_)
bool handleMessage;
{
recvQueue.push(std::string(data, length));
std::unique_lock<std::mutex> lock(mutex);
handleMessage = (wsi == wsi_);
}
}
std::string WsServer::Private::ReceiveMessage()
{
std::unique_lock<std::mutex> lock(mutex);
std::string message;
if (!recvQueue.empty())
if (handleMessage)
{
message = recvQueue.front();
recvQueue.pop();
handleMessage_(std::string(data, length));
}
return message;
}
std::string WsServer::Private::GetUrl() const
@ -299,4 +295,4 @@ std::string WsServer::Private::GetUrl() const
}
}
}

@ -2,6 +2,7 @@
#define WFP_TEST_UTILS_WS_SERVER_HPP
#include <string>
#include <functional>
namespace webfuse_test
{
@ -11,12 +12,14 @@ class WsServer
WsServer(WsServer const &) = delete;
WsServer & operator=(WsServer const &) = delete;
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();
bool IsConnected();
std::string GetUrl() const;
void SendMessage(std::string const & message);
std::string ReceiveMessage();
private:
class Private;
Private * d;

Loading…
Cancel
Save