Merge pull request #87 from falk-werner/remove_jansson

Remove dependency to libjansson
pull/88/head
Falk Werner 4 years ago committed by GitHub
commit 9bcf2a4434
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -28,7 +28,7 @@ RUN set -x \
openssl \
openssl-dev \
linux-headers \
&& pip3 install meson
&& pip3 install 'meson==0.54.3'
COPY src /usr/local/src

@ -26,7 +26,7 @@ RUN set -x \
ca-certificates \
openssl \
libssl-dev \
&& pip3 install --system meson
&& pip3 install --system 'meson==0.54.3'
COPY src /usr/local/src

@ -25,7 +25,7 @@ RUN set -x \
openssl \
openssl-dev \
linux-headers \
&& pip3 install meson
&& pip3 install 'meson==0.54.3'
COPY src /usr/local/src

@ -23,7 +23,7 @@ RUN set -x \
ca-certificates \
openssl \
libssl-dev \
&& pip3 install --system meson
&& pip3 install --system 'meson==0.54.3'
COPY src /usr/local/src

@ -2,6 +2,10 @@
## 0.5.0 _(unknown)_
### Features
* Removed dependency to libjansson
### Fixes
* Fix deadlock reading files larger that a few KBytes (Isseue #82)

@ -39,7 +39,6 @@ After that, you will find the API documentation in the doc/api subdirectory.
- [libfuse3](https://github.com/libfuse/libfuse/)
- [libwebsockets](https://libwebsockets.org/)
- [Jansson](https://jansson.readthedocs.io)
- [GoogleTest](https://github.com/google/googletest) *(optional)*
### Installation from source
@ -66,17 +65,6 @@ After that, you will find the API documentation in the doc/api subdirectory.
make
sudo make install
#### Jansson
wget -O libjansson-2.12.tar.gz https://github.com/akheron/jansson/archive/v2.12.tar.gz
tar -xf libjansson-2.12.tar.gz
cd jansson-2.12
mkdir .build
cd .build
cmake ..
make
sudo make install
#### GoogleTest
Installation of GoogleTest is optional webfuse library, but required to compile tests.

@ -9,6 +9,8 @@
#include "webfuse/impl/timer/manager.h"
#include "webfuse/impl/jsonrpc/response.h"
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/json/doc.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/message.h"
#include "webfuse/impl/message_queue.h"
@ -30,26 +32,26 @@ struct wf_impl_client_protocol_add_filesystem_context
static void
wf_impl_client_protocol_process(
struct wf_client_protocol * protocol,
char const * data,
char * data,
size_t length)
{
json_t * message = json_loadb(data, length, 0, NULL);
if (NULL != message)
struct wf_json_doc * doc = wf_impl_json_doc_loadb(data, length);
if (NULL != doc)
{
struct wf_json const * message = wf_impl_json_doc_root(doc);
if (wf_impl_jsonrpc_is_response(message))
{
wf_impl_jsonrpc_proxy_onresult(protocol->proxy, message);
}
json_decref(message);
wf_impl_json_doc_dispose(doc);
}
}
static void
wf_impl_client_protocol_receive(
struct wf_client_protocol * protocol,
char const * data,
char * data,
size_t length,
bool is_final_fragment)
{
@ -77,7 +79,7 @@ wf_impl_client_protocol_receive(
static bool
wf_impl_client_protocol_send(
json_t * request,
struct wf_message * message,
void * user_data)
{
bool result = false;
@ -85,13 +87,13 @@ wf_impl_client_protocol_send(
if (NULL != protocol->wsi)
{
struct wf_message * message = wf_impl_message_create(request);
if (NULL != message)
{
wf_impl_slist_append(&protocol->messages, &message->item);
lws_callback_on_writable(protocol->wsi);
result = true;
}
wf_impl_slist_append(&protocol->messages, &message->item);
lws_callback_on_writable(protocol->wsi);
result = true;
}
else
{
wf_impl_message_dispose(message);
}
return result;
@ -101,8 +103,8 @@ wf_impl_client_protocol_send(
static void
wf_impl_client_protocol_on_authenticate_finished(
void * user_data,
json_t const * result,
json_t const * WF_UNUSED_PARAM(error))
struct wf_json const * result,
struct wf_jsonrpc_error const * WF_UNUSED_PARAM(error))
{
struct wf_client_protocol * protocol = user_data;
int const reason = (NULL != result) ? WF_CLIENT_AUTHENTICATED : WF_CLIENT_AUTHENTICATION_FAILED;
@ -113,19 +115,19 @@ wf_impl_client_protocol_on_authenticate_finished(
static void
wf_impl_client_protocol_on_add_filesystem_finished(
void * user_data,
json_t const * result,
json_t const * WF_UNUSED_PARAM(error))
struct wf_json const * result,
struct wf_jsonrpc_error const * WF_UNUSED_PARAM(error))
{
struct wf_impl_client_protocol_add_filesystem_context * context = user_data;
struct wf_client_protocol * protocol = context->protocol;
int reason = WF_CLIENT_FILESYSTEM_ADD_FAILED;
if (NULL == protocol->filesystem)
if ((NULL == protocol->filesystem) && (NULL != result))
{
json_t * id = json_object_get(result, "id");
if (json_is_string(id))
struct wf_json const * id = wf_impl_json_object_get(result, "id");
if (wf_impl_json_is_string(id))
{
char const * name = json_string_value(id);
char const * name = wf_impl_json_string_get(id);
struct wf_mountpoint * mountpoint = wf_impl_mountpoint_create(context->local_path);
protocol->filesystem = wf_impl_filesystem_create(protocol->wsi,protocol->proxy, name, mountpoint);
if (NULL != protocol->filesystem)
@ -330,14 +332,13 @@ wf_impl_client_protocol_authenticate(
wf_impl_credentials_init_default(&creds);
protocol->callback(protocol->user_data, WF_CLIENT_AUTHENTICATE_GET_CREDENTIALS, &creds);
json_incref(creds.data);
wf_impl_jsonrpc_proxy_invoke(
protocol->proxy,
&wf_impl_client_protocol_on_authenticate_finished,
protocol,
"authenticate",
"sj",
creds.type, creds.data);
creds.type, &wf_impl_credentials_write, &creds);
wf_impl_credentials_cleanup(&creds);
}

@ -1,28 +1,54 @@
#include "webfuse/impl/credentials.h"
#include "webfuse/impl/json/writer.h"
#include "webfuse/impl/json/node.h"
#include <stdlib.h>
#include <string.h>
#define WF_CREDENTIALS_INITIAL_CAPACITY 2
void wf_impl_credentials_init_default(
struct wf_credentials * credentials)
{
credentials->type = NULL;
credentials->data = json_object();
credentials->capacity = WF_CREDENTIALS_INITIAL_CAPACITY;
credentials->entries = malloc(sizeof(struct wf_credentials_entry) * credentials->capacity);
credentials->size = 0;
}
void wf_impl_credentials_init(
struct wf_credentials * credentials,
char const * type,
json_t * data)
struct wf_json const * data)
{
size_t count = (NULL != data) ? wf_impl_json_object_size(data) : 0;
credentials->type = strdup(type);
credentials->data = data;
json_incref(credentials->data);
credentials->capacity = (count > 0) ? count : WF_CREDENTIALS_INITIAL_CAPACITY;
credentials->entries = malloc(sizeof(struct wf_credentials_entry) * credentials->capacity);
credentials->size = 0;
for (size_t i = 0; i < count; i++)
{
char const * key = wf_impl_json_object_key(data, i);
struct wf_json const * value = wf_impl_json_object_value(data, i);
if (wf_impl_json_is_string(value))
{
wf_impl_credentials_add(credentials, key, wf_impl_json_string_get(value));
}
}
}
void wf_impl_credentials_cleanup(
struct wf_credentials * credentials)
{
for (size_t i = 0; i < credentials->size; i++)
{
free(credentials->entries[i].key);
free(credentials->entries[i].value);
}
free(credentials->entries);
free(credentials->type);
json_decref(credentials->data);
}
char const * wf_impl_credentials_type(
@ -35,15 +61,15 @@ char const * wf_impl_credentials_get(
struct wf_credentials const * credentials,
char const * key)
{
char const * result = NULL;
json_t * value_holder = json_object_get(credentials->data, key);
if (json_is_string(value_holder))
for (size_t i = 0; i < credentials->size; i++)
{
result = json_string_value(value_holder);
if (0 == strcmp(key, credentials->entries[i].key))
{
return credentials->entries[i].value;
}
}
return result;
return NULL;
}
void wf_impl_credentials_set_type(
@ -59,6 +85,41 @@ void wf_impl_credentials_add(
char const * key,
char const * value)
{
json_object_set_new(credentials->data, key, json_string(value));
for(size_t i = 0; i < credentials->size; i++)
{
if (0 == strcmp(key, credentials->entries[i].key))
{
free(credentials->entries[i].value);
credentials->entries[i].value = strdup(value);
return;
}
}
if (credentials->size >= credentials->capacity)
{
credentials->capacity *= 2;
credentials->entries = realloc(credentials->entries, credentials->capacity);
}
credentials->entries[credentials->size].key = strdup(key);
credentials->entries[credentials->size].value = strdup(value);
credentials->size++;
}
void
wf_impl_credentials_write(
struct wf_json_writer * writer,
void * data)
{
struct wf_credentials * credentials = data;
wf_impl_json_write_object_begin(writer);
for (size_t i = 0; i < credentials->size; i++)
{
char const * key = credentials->entries[i].key;
char const * value = credentials->entries[i].value;
wf_impl_json_write_object_string(writer, key, value);
}
wf_impl_json_write_object_end(writer);
}

@ -1,23 +1,38 @@
#ifndef WF_ADAPTER_IMPL_CREDENTIALS_H
#define WF_ADAPTER_IMPL_CREDENTIALS_H
#include <jansson.h>
#ifndef __cplusplus
#include <stddef.h>
#else
#include <cstddef>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_json_writer;
struct wf_json;
struct wf_credentials_entry
{
char * key;
char * value;
};
struct wf_credentials
{
char * type;
json_t * data;
struct wf_credentials_entry * entries;
size_t capacity;
size_t size;
};
extern void wf_impl_credentials_init(
struct wf_credentials * credentials,
char const * type,
json_t * data);
struct wf_json const * data);
extern void wf_impl_credentials_init_default(
struct wf_credentials * credentials);
@ -41,6 +56,11 @@ extern void wf_impl_credentials_add(
char const * key,
char const * value);
extern void
wf_impl_credentials_write(
struct wf_json_writer * writer,
void * data);
#ifdef __cplusplus
}
#endif

@ -0,0 +1,44 @@
#include "webfuse/impl/json/doc.h"
#include "webfuse/impl/json/node_intern.h"
#include "webfuse/impl/json/reader.h"
#include "webfuse/impl/json/parser.h"
#include <stdlib.h>
struct wf_json_doc
{
struct wf_json root;
};
struct wf_json_doc *
wf_impl_json_doc_loadb(
char * data,
size_t length)
{
struct wf_json_reader reader;
wf_impl_json_reader_init(&reader, data, length);
struct wf_json_doc * doc = malloc(sizeof(struct wf_json_doc));
if (!wf_impl_json_parse_value(&reader, &doc->root))
{
free(doc);
doc = NULL;
}
return doc;
}
void
wf_impl_json_doc_dispose(
struct wf_json_doc * doc)
{
wf_impl_json_cleanup(&doc->root);
free(doc);
}
struct wf_json const *
wf_impl_json_doc_root(
struct wf_json_doc * doc)
{
return &doc->root;
}

@ -0,0 +1,36 @@
#ifndef WF_IMPL_JSON_DOC_H
#define WF_IMPL_JSON_DOC_H
#ifndef __cplusplus
#include <stddef.h>
#else
#include <cstddef>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_json_doc;
struct wf_json;
extern struct wf_json_doc *
wf_impl_json_doc_loadb(
char * data,
size_t length);
extern void
wf_impl_json_doc_dispose(
struct wf_json_doc * doc);
extern struct wf_json const *
wf_impl_json_doc_root(
struct wf_json_doc * doc);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,206 @@
#include "webfuse/impl/json/node_intern.h"
#include <stdlib.h>
#include <string.h>
static struct wf_json const wf_json_undefined =
{
.type = WF_JSON_TYPE_UNDEFINED,
.value = { .b = false }
};
enum wf_json_type
wf_impl_json_type(
struct wf_json const * json)
{
return json->type;
}
bool
wf_impl_json_bool_get(
struct wf_json const * json)
{
return (WF_JSON_TYPE_BOOL == json->type) ? json->value.b : false;
}
bool
wf_impl_json_is_undefined(
struct wf_json const * json)
{
return (WF_JSON_TYPE_UNDEFINED == json->type);
}
bool
wf_impl_json_is_null(
struct wf_json const * json)
{
return (WF_JSON_TYPE_NULL == json->type);
}
bool
wf_impl_json_is_bool(
struct wf_json const * json)
{
return (WF_JSON_TYPE_BOOL == json->type);
}
bool
wf_impl_json_is_int(
struct wf_json const * json)
{
return (WF_JSON_TYPE_INT == json->type);
}
bool
wf_impl_json_is_string(
struct wf_json const * json)
{
return (WF_JSON_TYPE_STRING == json->type);
}
bool
wf_impl_json_is_array(
struct wf_json const * json)
{
return (WF_JSON_TYPE_ARRAY == json->type);
}
bool
wf_impl_json_is_object(
struct wf_json const * json)
{
return (WF_JSON_TYPE_OBJECT == json->type);
}
int
wf_impl_json_int_get(
struct wf_json const * json)
{
return (WF_JSON_TYPE_INT == json->type) ? json->value.i : 0;
}
char const *
wf_impl_json_string_get(
struct wf_json const * json)
{
return (WF_JSON_TYPE_STRING == json->type) ? json->value.s.data : "";
}
size_t
wf_impl_json_string_size(
struct wf_json const * json)
{
return (WF_JSON_TYPE_STRING == json->type) ? json->value.s.size : 0;
}
struct wf_json const *
wf_impl_json_array_get(
struct wf_json const * json,
size_t pos)
{
struct wf_json const * result = &wf_json_undefined;
if ((WF_JSON_TYPE_ARRAY == json->type) && (pos < json->value.a.size))
{
result = &(json->value.a.items[pos]);
}
return result;
}
size_t
wf_impl_json_array_size(
struct wf_json const * json)
{
return (WF_JSON_TYPE_ARRAY == json->type) ? json->value.a.size : 0;
}
struct wf_json const *
wf_impl_json_object_get(
struct wf_json const * json,
char const * key)
{
if (WF_JSON_TYPE_OBJECT == json->type)
{
size_t const count = json->value.o.size;
for(size_t i = 0; i < count; i++)
{
struct wf_json_object_item * actual = &(json->value.o.items[i]);
if (0 == strcmp(key, actual->key))
{
return &(actual->json);
}
}
}
return &wf_json_undefined;
}
size_t
wf_impl_json_object_size(
struct wf_json const * json)
{
return (WF_JSON_TYPE_OBJECT == json->type) ? json->value.o.size : 0;
}
char const *
wf_impl_json_object_key(
struct wf_json const * json,
size_t pos)
{
char const * result = "";
if ((WF_JSON_TYPE_OBJECT == json->type) && (pos < json->value.o.size))
{
result = json->value.o.items[pos].key;
}
return result;
}
struct wf_json const *
wf_impl_json_object_value(
struct wf_json const * json,
size_t pos)
{
struct wf_json const * result = &wf_json_undefined;
if ((WF_JSON_TYPE_OBJECT == json->type) && (pos < json->value.o.size))
{
result = &(json->value.o.items[pos].json);
}
return result;
}
void
wf_impl_json_cleanup(
struct wf_json * json)
{
switch (json->type)
{
case WF_JSON_TYPE_ARRAY:
{
size_t const count = json->value.a.size;
for(size_t i = 0; i < count; i++)
{
struct wf_json * actual = &(json->value.a.items[i]);
wf_impl_json_cleanup(actual);
}
free(json->value.a.items);
}
break;
case WF_JSON_TYPE_OBJECT:
{
size_t const count = json->value.o.size;
for(size_t i = 0; i < count; i++)
{
struct wf_json * actual = &(json->value.o.items[i].json);
wf_impl_json_cleanup(actual);
}
free(json->value.o.items);
}
break;
default:
break;
}
}

@ -0,0 +1,109 @@
#ifndef WF_IMPL_JSON_NODE_H
#define WF_IMPL_JSON_NODE_H
#ifndef __cplusplus
#include <stdbool.h>
#include <stddef.h>
#else
#include <cstddef>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
enum wf_json_type
{
WF_JSON_TYPE_UNDEFINED,
WF_JSON_TYPE_NULL,
WF_JSON_TYPE_BOOL,
WF_JSON_TYPE_INT,
WF_JSON_TYPE_STRING,
WF_JSON_TYPE_ARRAY,
WF_JSON_TYPE_OBJECT
};
struct wf_json;
extern enum wf_json_type
wf_impl_json_type(
struct wf_json const * json);
extern bool
wf_impl_json_is_undefined(
struct wf_json const * json);
extern bool
wf_impl_json_is_null(
struct wf_json const * json);
extern bool
wf_impl_json_is_bool(
struct wf_json const * json);
extern bool
wf_impl_json_is_int(
struct wf_json const * json);
extern bool
wf_impl_json_is_string(
struct wf_json const * json);
extern bool
wf_impl_json_is_array(
struct wf_json const * json);
extern bool
wf_impl_json_is_object(
struct wf_json const * json);
extern bool
wf_impl_json_bool_get(
struct wf_json const * json);
extern int
wf_impl_json_int_get(
struct wf_json const * json);
extern char const *
wf_impl_json_string_get(
struct wf_json const * json);
extern size_t
wf_impl_json_string_size(
struct wf_json const * json);
extern struct wf_json const *
wf_impl_json_array_get(
struct wf_json const * json,
size_t pos);
extern size_t
wf_impl_json_array_size(
struct wf_json const * json);
extern struct wf_json const *
wf_impl_json_object_get(
struct wf_json const * json,
char const * key);
extern size_t
wf_impl_json_object_size(
struct wf_json const * json);
extern char const *
wf_impl_json_object_key(
struct wf_json const * json,
size_t pos);
extern struct wf_json const *
wf_impl_json_object_value(
struct wf_json const * json,
size_t pos);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,60 @@
#ifndef WF_IMPL_JSON_NODE_INTERN_H
#define WF_IMPL_JSON_NODE_INTERN_H
#include "webfuse/impl/json/node.h"
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_json_string
{
char * data;
size_t size;
};
struct wf_json_array
{
struct wf_json * items;
size_t size;
};
struct wf_json_object_item;
struct wf_json_object
{
struct wf_json_object_item * items;
size_t size;
};
union wf_json_value
{
bool b;
int i;
struct wf_json_string s;
struct wf_json_array a;
struct wf_json_object o;
};
struct wf_json
{
enum wf_json_type type;
union wf_json_value value;
};
struct wf_json_object_item
{
struct wf_json json;
char * key;
};
extern void
wf_impl_json_cleanup(
struct wf_json * json);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,291 @@
#include "webfuse/impl/json/parser.h"
#include "webfuse/impl/json/reader.h"
#include "webfuse/impl/json/node_intern.h"
#include <stdlib.h>
#define WF_JSON_PARSER_INITIAL_CAPACITY 4
static bool
wf_impl_json_parse_null(
struct wf_json_reader * reader,
struct wf_json * json);
static bool
wf_impl_json_parse_true(
struct wf_json_reader * reader,
struct wf_json * json);
static bool
wf_impl_json_parse_false(
struct wf_json_reader * reader,
struct wf_json * json);
static bool
wf_impl_json_parse_int(
struct wf_json_reader * reader,
struct wf_json * json);
static bool
wf_impl_json_parse_string(
struct wf_json_reader * reader,
struct wf_json * json);
static bool
wf_impl_json_parse_array(
struct wf_json_reader * reader,
struct wf_json * json);
static bool
wf_impl_json_parse_object(
struct wf_json_reader * reader,
struct wf_json * json);
// --
bool
wf_impl_json_parse_value(
struct wf_json_reader * reader,
struct wf_json * json)
{
bool result = false;
char const c = wf_impl_json_reader_skip_whitespace(reader);
switch (c)
{
case 'n':
result = wf_impl_json_parse_null(reader, json);
break;
case 't':
result = wf_impl_json_parse_true(reader, json);
break;
case 'f':
result = wf_impl_json_parse_false(reader, json);
break;
case '\"':
result = wf_impl_json_parse_string(reader, json);
break;
case '[':
result = wf_impl_json_parse_array(reader, json);
break;
case '{':
result = wf_impl_json_parse_object(reader, json);
break;
case '-': // fall-through
case '0': // fall-through
case '1': // fall-through
case '2': // fall-through
case '3': // fall-through
case '4': // fall-through
case '5': // fall-through
case '6': // fall-through
case '7': // fall-through
case '8': // fall-through
case '9':
result = wf_impl_json_parse_int(reader, json);
break;
default:
result = false;
break;
}
return result;
}
// --
static bool
wf_impl_json_parse_null(
struct wf_json_reader * reader,
struct wf_json * json)
{
bool const result = wf_impl_json_reader_read_const(reader, "null", 4);
if (result)
{
json->type = WF_JSON_TYPE_NULL;
}
return result;
}
static bool
wf_impl_json_parse_true(
struct wf_json_reader * reader,
struct wf_json * json)
{
bool const result = wf_impl_json_reader_read_const(reader, "true", 4);
if (result)
{
json->type = WF_JSON_TYPE_BOOL;
json->value.b = true;
}
return result;
}
static bool
wf_impl_json_parse_false(
struct wf_json_reader * reader,
struct wf_json * json)
{
bool const result = wf_impl_json_reader_read_const(reader, "false", 5);
if (result)
{
json->type = WF_JSON_TYPE_BOOL;
json->value.b = false;
}
return result;
}
static bool
wf_impl_json_parse_int(
struct wf_json_reader * reader,
struct wf_json * json)
{
int value;
bool const result = wf_impl_json_reader_read_int(reader, &value);
if (result)
{
json->type = WF_JSON_TYPE_INT;
json->value.i = value;
}
return result;
}
static bool
wf_impl_json_parse_string(
struct wf_json_reader * reader,
struct wf_json * json)
{
char * value;
size_t size;
bool const result = wf_impl_json_reader_read_string(reader, &value, &size);
if (result)
{
json->type = WF_JSON_TYPE_STRING;
json->value.s.data = value;
json->value.s.size = size;
}
return result;
}
static bool
wf_impl_json_parse_array(
struct wf_json_reader * reader,
struct wf_json * json)
{
wf_impl_json_reader_skip_whitespace(reader);
char c = wf_impl_json_reader_get_char(reader);
if ('[' != c) { return false; }
size_t capacity = WF_JSON_PARSER_INITIAL_CAPACITY;
json->type = WF_JSON_TYPE_ARRAY;
json->value.a.items = malloc(sizeof(struct wf_json) * capacity);
json->value.a.size = 0;
c = wf_impl_json_reader_skip_whitespace(reader);
if (']' == c)
{
wf_impl_json_reader_get_char(reader);
return true;
}
bool result;
do
{
if (json->value.a.size >= capacity)
{
capacity *= 2;
json->value.a.items = realloc(json->value.a.items, sizeof(struct wf_json) * capacity);
}
result = wf_impl_json_parse_value(reader, &(json->value.a.items[json->value.a.size]));
if (result)
{
json->value.a.size++;
wf_impl_json_reader_skip_whitespace(reader);
c = wf_impl_json_reader_get_char(reader);
}
} while ((result) && (',' == c));
if (']' != c)
{
result = false;
}
if (!result)
{
wf_impl_json_cleanup(json);
}
return result;
}
static bool
wf_impl_json_parse_object(
struct wf_json_reader * reader,
struct wf_json * json)
{
wf_impl_json_reader_skip_whitespace(reader);
char c = wf_impl_json_reader_get_char(reader);
if ('{' != c) { return false; }
size_t capacity = WF_JSON_PARSER_INITIAL_CAPACITY;
json->type = WF_JSON_TYPE_OBJECT;
json->value.o.items = malloc(sizeof(struct wf_json_object_item) * capacity);
json->value.o.size = 0;
c = wf_impl_json_reader_skip_whitespace(reader);
if ('}' == c)
{
wf_impl_json_reader_get_char(reader);
return true;
}
bool result;
do
{
if (json->value.o.size >= capacity)
{
capacity *= 2;
json->value.o.items = realloc(json->value.o.items, sizeof(struct wf_json_object_item) * capacity);
}
struct wf_json_object_item * item = &(json->value.o.items[json->value.o.size]);
size_t key_size;
result = wf_impl_json_reader_read_string(reader, &(item->key), &key_size);
if (result)
{
wf_impl_json_reader_skip_whitespace(reader);
result = (':' == wf_impl_json_reader_get_char(reader));
}
if (result)
{
result = wf_impl_json_parse_value(reader, &(item->json));
}
if (result)
{
json->value.o.size++;
wf_impl_json_reader_skip_whitespace(reader);
c = wf_impl_json_reader_get_char(reader);
}
} while ((result) && (',' == c));
if ('}' != c)
{
result = false;
}
if (!result)
{
wf_impl_json_cleanup(json);
}
return result;
}

@ -0,0 +1,25 @@
#ifndef WF_IMPL_JSON_PARSER_H
#define WF_IMPL_JSON_PARSER_H
#ifndef __cplusplus
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_json_reader;
struct wf_json;
extern bool
wf_impl_json_parse_value(
struct wf_json_reader * reader,
struct wf_json * json);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,181 @@
#include "webfuse/impl/json/reader.h"
#include <string.h>
static char
wf_impl_json_unescape(
char c);
void
wf_impl_json_reader_init(
struct wf_json_reader * reader,
char * contents,
size_t length)
{
reader->contents = contents;
reader->length = length;
reader->pos = 0;
}
char
wf_impl_json_reader_skip_whitespace(
struct wf_json_reader * reader)
{
char c = wf_impl_json_reader_peek(reader);
while ((' ' == c) || ('\n' == c) || ('\t' == c) || ('\r' == c))
{
reader->pos++;
c = wf_impl_json_reader_peek(reader);
}
return c;
}
char
wf_impl_json_reader_peek(
struct wf_json_reader * reader)
{
char result = '\0';
if (reader->pos < reader->length)
{
result = reader->contents[reader->pos];
}
return result;
}
char
wf_impl_json_reader_get_char(
struct wf_json_reader * reader)
{
char result = '\0';
if (reader->pos < reader->length)
{
result = reader->contents[reader->pos++];
}
return result;
}
void
wf_impl_json_reader_unget_char(
struct wf_json_reader * reader)
{
if (0 < reader->pos)
{
reader->pos--;
}
}
bool
wf_impl_json_reader_read_const(
struct wf_json_reader * reader,
char const * value,
size_t length)
{
size_t remaining = reader->length - reader->pos;
bool const result = ((remaining >= length) && (0 == strncmp((&reader->contents[reader->pos]), value, length)));
if (result)
{
reader->pos += length;
}
return result;
}
bool
wf_impl_json_reader_read_int(
struct wf_json_reader * reader,
int * value)
{
char c = wf_impl_json_reader_get_char(reader);
bool const is_signed = ('-' == c);
if (is_signed)
{
c = wf_impl_json_reader_get_char(reader);
}
bool const result = (('0' <= c) && (c <= '9'));
if (result)
{
int v = c - '0';
c = wf_impl_json_reader_peek(reader);
while (('0' <= c) && (c <= '9'))
{
v *= 10;
v += c - '0';
reader->pos++;
c = wf_impl_json_reader_peek(reader);
}
*value = (is_signed) ? -v : v;
}
return result;
}
bool
wf_impl_json_reader_read_string(
struct wf_json_reader * reader,
char * * value,
size_t * size)
{
wf_impl_json_reader_skip_whitespace(reader);
char c = wf_impl_json_reader_get_char(reader);
if ('\"' != c) { return false; }
size_t start = reader->pos;
size_t p = reader->pos;
c = wf_impl_json_reader_get_char(reader);
while (('\"' != c) && ('\0' != c))
{
if ('\\' != c)
{
reader->contents[p++] = c;
}
else
{
char unescaped = wf_impl_json_unescape(wf_impl_json_reader_get_char(reader));
if ('\0' != unescaped)
{
reader->contents[p++] = unescaped;
}
else
{
return false;
}
}
c = wf_impl_json_reader_get_char(reader);
}
bool const result = ('\"' == c);
if (result)
{
reader->contents[p] = '\0';
*value = &(reader->contents[start]);
*size = p - start;
}
return result;
}
static char
wf_impl_json_unescape(
char c)
{
switch (c)
{
case '\"': return '\"';
case '\\': return '\\';
case '/': return '/';
case 'b': return '\b';
case 'f': return '\f';
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
default:
return '\0';
}
}

@ -0,0 +1,66 @@
#ifndef WF_IMPL_JSON_READER_H
#define WF_IMPL_JSON_READER_H
#ifndef __cplusplus
#include <stddef.h>
#include <stdbool.h>
#else
#include <cstddef>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_json_reader
{
char * contents;
size_t length;
size_t pos;
};
extern void
wf_impl_json_reader_init(
struct wf_json_reader * reader,
char * contents,
size_t length);
extern char
wf_impl_json_reader_skip_whitespace(
struct wf_json_reader * reader);
extern char
wf_impl_json_reader_peek(
struct wf_json_reader * reader);
extern char
wf_impl_json_reader_get_char(
struct wf_json_reader * reader);
extern void
wf_impl_json_reader_unget_char(
struct wf_json_reader * reader);
extern bool
wf_impl_json_reader_read_const(
struct wf_json_reader * reader,
char const * value,
size_t length);
extern bool
wf_impl_json_reader_read_int(
struct wf_json_reader * reader,
int * value);
extern bool
wf_impl_json_reader_read_string(
struct wf_json_reader * reader,
char * * value,
size_t * size);
#ifdef __cplusplus
}
#endif
#endif

@ -263,12 +263,12 @@ wf_impl_json_write_bytes(
size_t length)
{
size_t encoded_length = wf_impl_base64_encoded_size(length);
wf_impl_json_reserve(writer, length + WF_JSON_WRITER_ADDITIONAL_STRING_SIZE);
wf_impl_json_reserve(writer, encoded_length + WF_JSON_WRITER_ADDITIONAL_STRING_SIZE);
wf_impl_json_begin_value(writer);
wf_impl_json_write_raw_char(writer, '\"');
wf_impl_base64_encode((uint8_t const *) data, length, &(writer->data[writer->offset]), encoded_length);
writer->offset = encoded_length;
writer->offset += encoded_length;
wf_impl_json_write_raw_char(writer, '\"');
wf_impl_json_end_value(writer);
@ -412,7 +412,7 @@ wf_impl_json_write_object_begin_object(
char const * key)
{
wf_impl_json_write_object_key(writer, key);
wf_impl_json_write_array_end(writer);
wf_impl_json_write_object_begin(writer);
}
// --

@ -1,17 +1,51 @@
#include "webfuse/impl/jsonrpc/error.h"
json_t *
#include <stdlib.h>
#include <string.h>
struct wf_jsonrpc_error
{
int code;
char * message;
};
struct wf_jsonrpc_error *
wf_impl_jsonrpc_error(
int code,
char const * message)
{
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(code));
json_object_set_new(error, "message", json_string(message));
struct wf_jsonrpc_error * error = malloc(sizeof(struct wf_jsonrpc_error));
error->code = code;
error->message = strdup(message);
return error;
}
void
wf_impl_jsonrpc_error_dispose(
struct wf_jsonrpc_error * error)
{
if (NULL != error)
{
free(error->message);
free(error);
}
}
int
wf_impl_jsonrpc_error_code(
struct wf_jsonrpc_error const * error)
{
return error->code;
}
char const *
wf_impl_jsonrpc_error_message(
struct wf_jsonrpc_error const * error)
{
return error->message;
}
void
wf_impl_jsonrpc_propate_error(
wf_jsonrpc_proxy_finished_fn * finised,
@ -19,9 +53,12 @@ wf_impl_jsonrpc_propate_error(
int code,
char const * message)
{
json_t * error = wf_impl_jsonrpc_error(code, message);
finised(user_data, NULL, error);
struct wf_jsonrpc_error error =
{
.code = code,
.message = (char*) message
};
json_decref(error);
finised(user_data, NULL, &error);
}

@ -1,7 +1,6 @@
#ifndef WF_IMPL_JSONRPC_ERROR_H
#define WF_IMPL_JSONRPC_ERROR_H
#include <jansson.h>
#include "webfuse/impl/jsonrpc/proxy_finished_fn.h"
#ifdef __cplusplus
@ -9,11 +8,25 @@ extern "C"
{
#endif
extern json_t *
struct wf_jsonrpc_error;
extern struct wf_jsonrpc_error *
wf_impl_jsonrpc_error(
int code,
char const * message);
extern void
wf_impl_jsonrpc_error_dispose(
struct wf_jsonrpc_error * error);
extern int
wf_impl_jsonrpc_error_code(
struct wf_jsonrpc_error const * error);
extern char const *
wf_impl_jsonrpc_error_message(
struct wf_jsonrpc_error const * error);
extern void
wf_impl_jsonrpc_propate_error(
wf_jsonrpc_proxy_finished_fn * finised,

@ -1,19 +1,18 @@
#ifndef WF_IMPL_JSONRPC_METHOD_INVOKE_FN_H
#define WF_IMPL_JSONRPC_METHOD_INVOKE_FN_H
#include <jansson.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_jsonrpc_request;
struct wf_json;
typedef void wf_jsonrpc_method_invoke_fn(
struct wf_jsonrpc_request * request,
char const * method_name,
json_t * params,
struct wf_json const * params,
void * user_data);
#ifdef __cplusplus

@ -2,12 +2,17 @@
#include "webfuse/impl/jsonrpc/proxy_request_manager.h"
#include "webfuse/impl/jsonrpc/response_intern.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/impl/json/writer.h"
#include "webfuse/impl/message.h"
#include "webfuse/status.h"
#include <libwebsockets.h>
#include <stdlib.h>
#include <string.h>
#define WF_JSONRPC_PROXY_DEFAULT_MESSAGE_SIZE 1024
struct wf_jsonrpc_proxy *
wf_impl_jsonrpc_proxy_create(
struct wf_timer_manager * manager,
@ -29,15 +34,17 @@ void wf_impl_jsonrpc_proxy_dispose(
}
static json_t * wf_impl_jsonrpc_request_create(
static struct wf_message *
wf_impl_jsonrpc_request_create(
char const * method,
int id,
char const * param_info,
va_list args)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string(method));
json_t * params = json_array();
struct wf_json_writer * writer = wf_impl_json_writer_create(WF_JSONRPC_PROXY_DEFAULT_MESSAGE_SIZE, LWS_PRE);
wf_impl_json_write_object_begin(writer);
wf_impl_json_write_object_string(writer, "method", method);
wf_impl_json_write_object_begin_array(writer, "params");
for (char const * param_type = param_info; '\0' != *param_type; param_type++)
{
@ -46,37 +53,41 @@ static json_t * wf_impl_jsonrpc_request_create(
case 's':
{
char const * const value = va_arg(args, char const *);
json_array_append_new(params, json_string(value));
wf_impl_json_write_string(writer, value);
}
break;
case 'i':
{
int const value = va_arg(args, int);
json_array_append_new(params, json_integer(value));
wf_impl_json_write_int(writer, value);
}
break;
case 'j':
{
json_t * const value = va_arg(args, json_t *);
json_array_append_new(params, value);
wf_jsonrpc_custom_write_fn * write = va_arg(args, wf_jsonrpc_custom_write_fn *);
void * data = va_arg(args, void *);
write(writer, data);
}
break;
default:
fprintf(stderr, "fatal: unknown param_type '%c'\n", *param_type);
json_decref(params);
json_decref(request);
return NULL;
fprintf(stderr, "fatal: unknown param_type '%c'\n", *param_type);
break;
}
}
wf_impl_json_write_array_end(writer);
json_object_set_new(request, "params", params);
if (0 != id)
{
json_object_set_new(request, "id", json_integer(id));
wf_impl_json_write_object_int(writer, "id", id);
}
wf_impl_json_write_object_end(writer);
return request;
size_t length;
char * message = wf_impl_json_writer_take(writer, &length);
wf_impl_json_writer_dispose(writer);
return wf_impl_message_create(message, length);
}
void wf_impl_jsonrpc_proxy_init(
@ -110,18 +121,13 @@ void wf_impl_jsonrpc_proxy_vinvoke(
int id = wf_impl_jsonrpc_proxy_request_manager_add_request(
proxy->request_manager, finished, user_data);
json_t * request = wf_impl_jsonrpc_request_create(method_name, id, param_info, args);
bool const is_send = ((NULL != request) && (proxy->send(request, proxy->user_data)));
struct wf_message * request = wf_impl_jsonrpc_request_create(method_name, id, param_info, args);
bool const is_send = proxy->send(request, proxy->user_data);
if (!is_send)
{
wf_impl_jsonrpc_proxy_request_manager_cancel_request(
proxy->request_manager, id, WF_BAD, "Bad: failed to send request");
}
if (NULL != request)
{
json_decref(request);
}
}
extern void wf_impl_jsonrpc_proxy_vnotify(
@ -130,19 +136,14 @@ extern void wf_impl_jsonrpc_proxy_vnotify(
char const * param_info,
va_list args)
{
json_t * request = wf_impl_jsonrpc_request_create(method_name, 0, param_info, args);
if (NULL != request)
{
proxy->send(request, proxy->user_data);
json_decref(request);
}
struct wf_message * request = wf_impl_jsonrpc_request_create(method_name, 0, param_info, args);
proxy->send(request, proxy->user_data);
}
void wf_impl_jsonrpc_proxy_onresult(
struct wf_jsonrpc_proxy * proxy,
json_t * message)
struct wf_json const * message)
{
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);

@ -11,7 +11,6 @@
using std::size_t;
#endif
#include <jansson.h>
#include "webfuse/impl/jsonrpc/send_fn.h"
#include "webfuse/impl/jsonrpc/proxy_finished_fn.h"
@ -21,6 +20,13 @@ extern "C" {
struct wf_jsonrpc_proxy;
struct wf_timer_manager;
struct wf_json_writer;
struct wf_json;
typedef void
wf_jsonrpc_custom_write_fn(
struct wf_json_writer * writer,
void * data);
extern struct wf_jsonrpc_proxy *
wf_impl_jsonrpc_proxy_create(
@ -64,7 +70,7 @@ extern void wf_impl_jsonrpc_proxy_notify(
extern void wf_impl_jsonrpc_proxy_onresult(
struct wf_jsonrpc_proxy * proxy,
json_t * message);
struct wf_json const * message);
#ifdef __cplusplus
}

@ -1,17 +1,18 @@
#ifndef WF_IMPL_JSONRPC_PROXY_FINISHED_FN_H
#define WF_IMPL_JSONRPC_PROXY_FINISHED_FN_H
#include <jansson.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_jsonrpc_error;
struct wf_json;
typedef void wf_jsonrpc_proxy_finished_fn(
void * user_data,
json_t const * result,
json_t const * error);
struct wf_json const * result,
struct wf_jsonrpc_error const * error);
#ifdef __cplusplus
}

@ -1,9 +1,16 @@
#include "webfuse/impl/jsonrpc/request.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/impl/json/writer.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/jsonrpc/response_writer.h"
#include "webfuse/impl/message.h"
#include <libwebsockets.h>
#include <stdlib.h>
struct wf_jsonrpc_request
{
struct wf_jsonrpc_response_writer * writer;
int id;
wf_jsonrpc_send_fn * send;
void * user_data;
@ -11,14 +18,16 @@ struct wf_jsonrpc_request
bool
wf_impl_jsonrpc_is_request(
json_t * message)
struct wf_json const * message)
{
json_t * id = json_object_get(message, "id");
json_t * method = json_object_get(message, "method");
json_t * params = json_object_get(message, "params");
if (NULL == message) { return false; }
struct wf_json const * id = wf_impl_json_object_get(message, "id");
struct wf_json const * method = wf_impl_json_object_get(message, "method");
struct wf_json const * params = wf_impl_json_object_get(message, "params");
return (json_is_integer(id) && json_is_string(method) &&
(json_is_array(params) || json_is_object(params)));
return ( (wf_impl_json_is_int(id)) && (wf_impl_json_is_string(method)) &&
( (wf_impl_json_is_array(params)) || (wf_impl_json_is_object(params)) ));
}
@ -29,6 +38,7 @@ wf_impl_jsonrpc_request_create(
void * user_data)
{
struct wf_jsonrpc_request * request = malloc(sizeof(struct wf_jsonrpc_request));
request->writer = wf_impl_jsonrpc_response_writer_create(id);
request->id = id;
request->send = send;
request->user_data = user_data;
@ -40,6 +50,7 @@ void
wf_impl_jsonrpc_request_dispose(
struct wf_jsonrpc_request * request)
{
wf_impl_jsonrpc_response_writer_dispose(request->writer);
free(request);
}
@ -50,18 +61,21 @@ wf_impl_jsonrpc_request_get_userdata(
return request->user_data;
}
struct wf_jsonrpc_response_writer *
wf_impl_jsonrpc_request_get_response_writer(
struct wf_jsonrpc_request * request)
{
return request->writer;
}
void
wf_impl_jsonrpc_respond(
struct wf_jsonrpc_request * request,
json_t * result)
struct wf_jsonrpc_request * request)
{
json_t * response = json_object();
json_object_set_new(response, "result", result);
json_object_set_new(response, "id", json_integer(request->id));
struct wf_message * response = wf_impl_jsonrpc_response_writer_take_message(request->writer);
request->send(response, request->user_data);
json_decref(response);
wf_impl_jsonrpc_request_dispose(request);
}
@ -70,11 +84,21 @@ void wf_impl_jsonrpc_respond_error(
int code,
char const * message)
{
json_t * response = json_object();
json_object_set_new(response, "error", wf_impl_jsonrpc_error(code, message));
json_object_set_new(response, "id", json_integer(request->id));
struct wf_json_writer * writer = wf_impl_json_writer_create(128, LWS_PRE);
wf_impl_json_write_object_begin(writer);
wf_impl_json_write_object_begin_object(writer, "error");
wf_impl_json_write_object_int(writer, "code", code);
wf_impl_json_write_object_string(writer, "message", message);
wf_impl_json_write_object_end(writer);
wf_impl_json_write_object_int(writer, "id", request->id);
wf_impl_json_write_object_end(writer);
size_t length;
char * data = wf_impl_json_writer_take(writer, &length);
wf_impl_json_writer_dispose(writer);
struct wf_message * response = wf_impl_message_create(data, length);
request->send(response, request->user_data);
json_decref(response);
wf_impl_jsonrpc_request_dispose(request);
}

@ -11,7 +11,6 @@
using std::size_t;
#endif
#include <jansson.h>
#include "webfuse/impl/jsonrpc/send_fn.h"
#ifdef __cplusplus
@ -20,9 +19,11 @@ extern "C"
#endif
struct wf_jsonrpc_request;
struct wf_jsonrpc_response_writer;
struct wf_json;
extern bool wf_impl_jsonrpc_is_request(
json_t * message);
struct wf_json const * message);
extern struct wf_jsonrpc_request *
wf_impl_jsonrpc_request_create(
@ -36,9 +37,12 @@ extern void wf_impl_jsonrpc_request_dispose(
extern void * wf_impl_jsonrpc_request_get_userdata(
struct wf_jsonrpc_request * request);
extern struct wf_jsonrpc_response_writer *
wf_impl_jsonrpc_request_get_response_writer(
struct wf_jsonrpc_request * request);
extern void wf_impl_jsonrpc_respond(
struct wf_jsonrpc_request * request,
json_t * result);
struct wf_jsonrpc_request * request);
extern void wf_impl_jsonrpc_respond_error(
struct wf_jsonrpc_request * request,

@ -1,54 +1,57 @@
#include "webfuse/impl/jsonrpc/response_intern.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/status.h"
bool
wf_impl_jsonrpc_is_response(
json_t * message)
struct wf_json const * message)
{
json_t * id = json_object_get(message, "id");
json_t * err = json_object_get(message, "error");
json_t * result = json_object_get(message, "result");
if (NULL == message) { return false; }
return (json_is_integer(id) &&
(json_is_object(err) || (NULL != result)));
struct wf_json const * id = wf_impl_json_object_get(message, "id");
struct wf_json const * err = wf_impl_json_object_get(message, "error");
struct wf_json const * result = wf_impl_json_object_get(message, "result");
return ((wf_impl_json_is_int(id)) &&
((wf_impl_json_is_object(err)) || (!wf_impl_json_is_undefined(result))));
}
void
wf_impl_jsonrpc_response_init(
struct wf_jsonrpc_response * result,
json_t * response)
struct wf_json const * response)
{
result->id = -1;
result->result = NULL;
result->error = NULL;
json_t * id_holder = json_object_get(response, "id");
if (!json_is_integer(id_holder))
struct wf_json const * id_holder = wf_impl_json_object_get(response, "id");
if (!wf_impl_json_is_int(id_holder))
{
result->error = wf_impl_jsonrpc_error(WF_BAD_FORMAT, "invalid format: missing id");
return;
}
result->id = json_integer_value(id_holder);
result->result = json_object_get(response, "result");
if (NULL != result->result)
{
json_incref(result->result);
}
else
result->id = wf_impl_json_int_get(id_holder);
result->result = wf_impl_json_object_get(response, "result");
if (wf_impl_json_is_undefined(result->result))
{
json_t * error = json_object_get(response, "error");
if ((json_is_object(error)) && (json_is_integer(json_object_get(error, "code"))))
{
result->error = error;
json_incref(result->error);
}
else
int code = WF_BAD_FORMAT;
char const * message = "invalid format: invalid error object";
struct wf_json const * error = wf_impl_json_object_get(response, "error");
struct wf_json const * code_holder = wf_impl_json_object_get(error, "code");
if (wf_impl_json_is_int(code_holder))
{
result->error = wf_impl_jsonrpc_error(WF_BAD_FORMAT, "invalid format: invalid error object");
code = wf_impl_json_int_get(code_holder);
struct wf_json const * message_holder = wf_impl_json_object_get(error, "message");
message = wf_impl_json_string_get(message_holder);
}
result->error = wf_impl_jsonrpc_error(code, message);
result->result = NULL;
}
}
@ -56,13 +59,5 @@ void
wf_impl_jsonrpc_response_cleanup(
struct wf_jsonrpc_response * response)
{
if (NULL != response->result)
{
json_decref(response->result);
}
if (NULL != response->error)
{
json_decref(response->error);
}
wf_impl_jsonrpc_error_dispose(response->error);
}

@ -5,15 +5,15 @@
#include <stdbool.h>
#endif
#include <jansson.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_json;
extern bool wf_impl_jsonrpc_is_response(
json_t * message);
struct wf_json const * message);
#ifdef __cplusplus
}

@ -14,16 +14,19 @@ using std::size_t;
extern "C" {
#endif
struct wf_jsonrpc_error;
struct wf_json;
struct wf_jsonrpc_response
{
json_t * result;
json_t * error;
struct wf_json const * result;
struct wf_jsonrpc_error * error;
int id;
};
extern void wf_impl_jsonrpc_response_init(
struct wf_jsonrpc_response * response,
json_t * message);
struct wf_json const * message);
extern void wf_impl_jsonrpc_response_cleanup(
struct wf_jsonrpc_response * response);

@ -0,0 +1,67 @@
#include "webfuse/impl/jsonrpc/response_writer.h"
#include "webfuse/impl/message.h"
#include "webfuse/impl/json/writer.h"
#include <libwebsockets.h>
#include <stdlib.h>
#define WF_RESPONSE_WRITER_DEFAULT_MESSAGE_SIZE 1024
struct wf_jsonrpc_response_writer
{
struct wf_json_writer * json_writer;
int id;
};
struct wf_jsonrpc_response_writer *
wf_impl_jsonrpc_response_writer_create(int id)
{
struct wf_jsonrpc_response_writer * writer = malloc(sizeof(struct wf_jsonrpc_response_writer));
writer->json_writer = wf_impl_json_writer_create(WF_RESPONSE_WRITER_DEFAULT_MESSAGE_SIZE, LWS_PRE);
writer->id = id;
wf_impl_json_write_object_begin(writer->json_writer);
wf_impl_json_write_object_begin_object(writer->json_writer, "result");
return writer;
}
void
wf_impl_jsonrpc_response_writer_dispose(
struct wf_jsonrpc_response_writer * writer)
{
wf_impl_json_writer_dispose(writer->json_writer);
free(writer);
}
struct wf_message *
wf_impl_jsonrpc_response_writer_take_message(
struct wf_jsonrpc_response_writer * writer)
{
wf_impl_json_write_object_end(writer->json_writer);
wf_impl_json_write_object_int(writer->json_writer, "id", writer->id);
wf_impl_json_write_object_end(writer->json_writer);
size_t length;
char * data = wf_impl_json_writer_take(writer->json_writer, &length);
return wf_impl_message_create(data, length);
}
void
wf_impl_jsonrpc_response_add_int(
struct wf_jsonrpc_response_writer * writer,
char const * key,
int value)
{
wf_impl_json_write_object_int(writer->json_writer, key, value);
}
void
wf_impl_jsonrpc_response_add_string(
struct wf_jsonrpc_response_writer * writer,
char const * key,
char const * value)
{
wf_impl_json_write_object_string(writer->json_writer, key, value);
}

@ -0,0 +1,40 @@
#ifndef WF_IMPL_JSONRPC_RESPONSE_WRITER_H
#define WF_IMPL_JSONRPC_RESPONSE_WRITER_H
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_jsonrpc_response_writer;
struct wf_messge;
extern struct wf_jsonrpc_response_writer *
wf_impl_jsonrpc_response_writer_create(int id);
extern void
wf_impl_jsonrpc_response_writer_dispose(
struct wf_jsonrpc_response_writer * writer);
extern struct wf_message *
wf_impl_jsonrpc_response_writer_take_message(
struct wf_jsonrpc_response_writer * writer);
extern void
wf_impl_jsonrpc_response_add_int(
struct wf_jsonrpc_response_writer * writer,
char const * key,
int value);
extern void
wf_impl_jsonrpc_response_add_string(
struct wf_jsonrpc_response_writer * writer,
char const * key,
char const * value);
#ifdef __cplusplus
}
#endif
#endif

@ -5,15 +5,16 @@
#include <stdbool.h>
#endif
#include <jansson.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_message;
typedef bool wf_jsonrpc_send_fn(
json_t * request,
struct wf_message * request,
void * user_data);
#ifdef __cplusplus

@ -1,6 +1,7 @@
#include "webfuse/impl/jsonrpc/server.h"
#include "webfuse/impl/jsonrpc/method.h"
#include "webfuse/impl/jsonrpc/request.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/status.h"
#include "webfuse/impl/util/util.h"
@ -70,7 +71,7 @@ void wf_impl_jsonrpc_server_add(
static void wf_impl_jsonrpc_server_invalid_method_invoke(
struct wf_jsonrpc_request * request,
char const * WF_UNUSED_PARAM(method_name),
json_t * WF_UNUSED_PARAM(params),
struct wf_json const * WF_UNUSED_PARAM(params),
void * WF_UNUSED_PARAM(user_data))
{
wf_impl_jsonrpc_respond_error(request, WF_BAD_NOTIMPLEMENTED, "not implemented");
@ -105,20 +106,20 @@ wf_impl_jsonrpc_server_get_method(
void wf_impl_jsonrpc_server_process(
struct wf_jsonrpc_server * server,
json_t * request_data,
struct wf_json const * request_data,
wf_jsonrpc_send_fn * send,
void * user_data)
{
json_t * method_holder = json_object_get(request_data, "method");
json_t * params = json_object_get(request_data, "params");
json_t * id_holder = json_object_get(request_data, "id");
struct wf_json const * method_holder = wf_impl_json_object_get(request_data, "method");
struct wf_json const * params = wf_impl_json_object_get(request_data, "params");
struct wf_json const * id_holder = wf_impl_json_object_get(request_data, "id");
if (json_is_string(method_holder) &&
(json_is_array(params) || (json_is_object(params))) &&
json_is_integer(id_holder))
if ((wf_impl_json_is_string(method_holder)) &&
((wf_impl_json_is_array(params)) || (wf_impl_json_is_object(params))) &&
(wf_impl_json_is_int(id_holder)))
{
char const * method_name = json_string_value(method_holder);
int id = json_integer_value(id_holder);
char const * method_name = wf_impl_json_string_get(method_holder);
int id = wf_impl_json_int_get(id_holder);
struct wf_jsonrpc_request * request = wf_impl_jsonrpc_request_create(id, send, user_data);
struct wf_jsonrpc_method const * method = wf_impl_jsonrpc_server_get_method(server, method_name);

@ -8,7 +8,6 @@
#include <cstdarg>
#endif
#include <jansson.h>
#include "webfuse/impl/jsonrpc/method_invoke_fn.h"
#include "webfuse/impl/jsonrpc/send_fn.h"
@ -18,6 +17,7 @@ extern "C"
#endif
struct wf_jsonrpc_server;
struct wf_json;
extern struct wf_jsonrpc_server *
wf_impl_jsonrpc_server_create(void);
@ -34,7 +34,7 @@ extern void wf_impl_jsonrpc_server_add(
extern void wf_impl_jsonrpc_server_process(
struct wf_jsonrpc_server * server,
json_t * request,
struct wf_json const * request,
wf_jsonrpc_send_fn * send,
void * user_data);

@ -3,26 +3,23 @@
#include <stdlib.h>
#include <libwebsockets.h>
extern struct wf_message * wf_impl_message_create(json_t const * value)
extern struct wf_message *
wf_impl_message_create(
char * data,
size_t length)
{
struct wf_message * message = NULL;
size_t const length = json_dumpb(value, NULL, 0, JSON_COMPACT);
if (0 < length)
{
char * data = malloc(sizeof(struct wf_message) + LWS_PRE + length);
message = (struct wf_message *) data;
message->data = &data[sizeof(struct wf_message) + LWS_PRE];
message->length = length;
json_dumpb(value, message->data, length, JSON_COMPACT);
}
struct wf_message * message = malloc(sizeof(struct wf_message));
message->data = data;
message->length = length;
return message;
}
void wf_impl_message_dispose(
void
wf_impl_message_dispose(
struct wf_message * message)
{
char * raw_data = message->data - LWS_PRE;
free(raw_data);
free(message);
}

@ -8,7 +8,6 @@
using std::size_t;
#endif
#include <jansson.h>
#include "webfuse/impl/util/slist.h"
struct wf_message
@ -23,10 +22,13 @@ extern "C"
{
#endif
extern struct wf_message * wf_impl_message_create(
json_t const * value);
extern struct wf_message *
wf_impl_message_create(
char * value,
size_t length);
extern void wf_impl_message_dispose(
extern void
wf_impl_message_dispose(
struct wf_message * message);
#ifdef __cplusplus

@ -3,7 +3,6 @@
#include <limits.h>
#include <errno.h>
#include <jansson.h>
#include "webfuse/impl/jsonrpc/proxy.h"

@ -3,6 +3,7 @@
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -11,11 +12,12 @@
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/util/json_util.h"
#include "webfuse/impl/util/util.h"
#include "webfuse/impl/json/node.h"
void wf_impl_operation_getattr_finished(
void * user_data,
json_t const * result,
json_t const * error)
struct wf_json const * result,
struct wf_jsonrpc_error const * error)
{
wf_status status = wf_impl_jsonrpc_get_status(error);
struct wf_impl_operation_getattr_context * context = user_data;
@ -23,15 +25,15 @@ void wf_impl_operation_getattr_finished(
struct stat buffer;
if (NULL != result)
{
json_t * mode_holder = json_object_get(result, "mode");
json_t * type_holder = json_object_get(result, "type");
if ((json_is_integer(mode_holder)) && (json_is_string(type_holder)))
struct wf_json const * mode_holder = wf_impl_json_object_get(result, "mode");
struct wf_json const * type_holder = wf_impl_json_object_get(result, "type");
if ((wf_impl_json_is_int(mode_holder)) && (wf_impl_json_is_string(type_holder)))
{
memset(&buffer, 0, sizeof(struct stat));
buffer.st_ino = context->inode;
buffer.st_mode = json_integer_value(mode_holder) & 0555;
char const * type = json_string_value(type_holder);
buffer.st_mode = wf_impl_json_int_get(mode_holder) & 0555;
char const * type = wf_impl_json_string_get(type_holder);
if (0 == strcmp("file", type))
{
buffer.st_mode |= S_IFREG;

@ -3,7 +3,6 @@
#include "webfuse/impl/fuse_wrapper.h"
#include <jansson.h>
#include <sys/types.h>
#ifdef __cplusplus
@ -11,6 +10,9 @@ extern "C"
{
#endif
struct wf_jsonrpc_error;
struct wf_json;
struct wf_impl_operation_getattr_context
{
fuse_req_t request;
@ -22,8 +24,8 @@ struct wf_impl_operation_getattr_context
extern void wf_impl_operation_getattr_finished(
void * user_data,
json_t const * result,
json_t const * error);
struct wf_json const * result,
struct wf_jsonrpc_error const * error);
extern void wf_impl_operation_getattr (
fuse_req_t request,

@ -12,13 +12,14 @@
#include <stdlib.h>
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/util/json_util.h"
#include "webfuse/impl/util/util.h"
void wf_impl_operation_lookup_finished(
void * user_data,
json_t const * result,
json_t const * error
struct wf_json const * result,
struct wf_jsonrpc_error const * error
)
{
wf_status status = wf_impl_jsonrpc_get_status(error);
@ -27,19 +28,19 @@ void wf_impl_operation_lookup_finished(
if (NULL != result)
{
json_t * inode_holder = json_object_get(result, "inode");
json_t * mode_holder = json_object_get(result, "mode");
json_t * type_holder = json_object_get(result, "type");
if ((json_is_integer(inode_holder)) &&
(json_is_integer(mode_holder)) &&
(json_is_string(type_holder)))
struct wf_json const * inode_holder = wf_impl_json_object_get(result, "inode");
struct wf_json const * mode_holder = wf_impl_json_object_get(result, "mode");
struct wf_json const * type_holder = wf_impl_json_object_get(result, "type");
if ((wf_impl_json_is_int(inode_holder)) &&
(wf_impl_json_is_int(mode_holder)) &&
(wf_impl_json_is_string(type_holder)))
{
memset(&buffer, 0, sizeof(struct stat));
buffer.ino = json_integer_value(inode_holder);
buffer.ino = wf_impl_json_int_get(inode_holder);
buffer.attr.st_ino = buffer.ino;
buffer.attr.st_mode = json_integer_value(mode_holder) & 0555;
char const * type = json_string_value(type_holder);
buffer.attr.st_mode = wf_impl_json_int_get(mode_holder) & 0555;
char const * type = wf_impl_json_string_get(type_holder);
if (0 == strcmp("file", type))
{
buffer.attr.st_mode |= S_IFREG;

@ -3,7 +3,6 @@
#include "webfuse/impl/fuse_wrapper.h"
#include <jansson.h>
#include <sys/types.h>
#ifdef __cplusplus
@ -11,6 +10,9 @@ extern "C"
{
#endif
struct wf_jsonrpc_error;
struct wf_json;
struct wf_impl_operation_lookup_context
{
fuse_req_t request;
@ -21,8 +23,8 @@ struct wf_impl_operation_lookup_context
extern void wf_impl_operation_lookup_finished(
void * user_data,
json_t const * result,
json_t const * error);
struct wf_json const * result,
struct wf_jsonrpc_error const * error);
extern void wf_impl_operation_lookup (
fuse_req_t req,

@ -2,6 +2,7 @@
#include "webfuse/impl/operation/context.h"
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/util/util.h"
#include "webfuse/status.h"
#include "webfuse/impl/util/json_util.h"
@ -11,8 +12,8 @@
void wf_impl_operation_open_finished(
void * user_data,
json_t const * result,
json_t const * error)
struct wf_json const * result,
struct wf_jsonrpc_error const * error)
{
wf_status status = wf_impl_jsonrpc_get_status(error);
fuse_req_t request = user_data;
@ -21,10 +22,10 @@ void wf_impl_operation_open_finished(
if (NULL != result)
{
json_t * handle_holder = json_object_get(result, "handle");
if (json_is_integer(handle_holder))
struct wf_json const * handle_holder = wf_impl_json_object_get(result, "handle");
if (wf_impl_json_is_int(handle_holder))
{
file_info.fh = json_integer_value(handle_holder);
file_info.fh = wf_impl_json_int_get(handle_holder);
}
else
{

@ -2,13 +2,15 @@
#define WF_ADAPTER_IMPL_OPERATION_OPEN_H
#include "webfuse/impl/fuse_wrapper.h"
#include <jansson.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_jsonrpc_error;
struct wf_json;
extern void wf_impl_operation_open(
fuse_req_t request,
fuse_ino_t inode,
@ -16,8 +18,8 @@ extern void wf_impl_operation_open(
extern void wf_impl_operation_open_finished(
void * user_data,
json_t const * result,
json_t const * error);
struct wf_json const * result,
struct wf_jsonrpc_error const * error);
#ifdef __cplusplus
}

@ -2,43 +2,40 @@
#include "webfuse/impl/operation/context.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <jansson.h>
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/util/base64.h"
#include "webfuse/impl/util/json_util.h"
// do not read chunks larger than 1 MByte
#define WF_MAX_READ_LENGTH (1024 * 1024)
char * wf_impl_fill_buffer(
char const * data,
char * wf_impl_operation_read_transform(
char * data,
size_t data_size,
char const * format,
size_t count,
wf_status * status)
{
*status = WF_GOOD;
char * buffer = malloc(count);
char * buffer = data;
if (0 < count)
{
if (0 == strcmp("identity", format))
{
if (count == data_size)
{
memcpy(buffer, data, count);
}
else
if (count != data_size)
{
*status = WF_BAD;
}
}
else if (0 == strcmp("base64", format))
{
size_t result = wf_impl_base64_decode(data, data_size, (uint8_t *) buffer, count);
size_t result = wf_impl_base64_decode(data, data_size, (uint8_t *) data, count);
if (result != count)
{
*status = WF_BAD;
@ -50,19 +47,13 @@ char * wf_impl_fill_buffer(
}
}
if (WF_GOOD != *status)
{
free(buffer);
buffer = NULL;
}
return buffer;
}
void wf_impl_operation_read_finished(
void * user_data,
json_t const * result,
json_t const * error)
struct wf_json const * result,
struct wf_jsonrpc_error const * error)
{
wf_status status = wf_impl_jsonrpc_get_status(error);
fuse_req_t request = user_data;
@ -71,20 +62,20 @@ void wf_impl_operation_read_finished(
size_t length = 0;
if (NULL != result)
{
json_t * data_holder = json_object_get(result, "data");
json_t * format_holder = json_object_get(result, "format");
json_t * count_holder = json_object_get(result, "count");
struct wf_json const * data_holder = wf_impl_json_object_get(result, "data");
struct wf_json const * format_holder = wf_impl_json_object_get(result, "format");
struct wf_json const * count_holder = wf_impl_json_object_get(result, "count");
if (json_is_string(data_holder) &&
json_is_string(format_holder) &&
json_is_integer(count_holder))
if ((wf_impl_json_is_string(data_holder)) &&
(wf_impl_json_is_string(format_holder)) &&
(wf_impl_json_is_int(count_holder)))
{
char const * const data = json_string_value(data_holder);
size_t const data_size = json_string_length(data_holder);
char const * const format = json_string_value(format_holder);
length = (size_t) json_integer_value(count_holder);
char * const data = (char*) wf_impl_json_string_get(data_holder);
size_t const data_size = wf_impl_json_string_size(data_holder);
char const * const format = wf_impl_json_string_get(format_holder);
length = (size_t) wf_impl_json_int_get(count_holder);
buffer = wf_impl_fill_buffer(data, data_size, format, length, &status);
buffer = wf_impl_operation_read_transform(data, data_size, format, length, &status);
}
else
{
@ -100,9 +91,6 @@ void wf_impl_operation_read_finished(
{
fuse_reply_err(request, ENOENT);
}
free(buffer);
}
void wf_impl_operation_read(

@ -4,20 +4,21 @@
#include "webfuse/impl/fuse_wrapper.h"
#include "webfuse/status.h"
#include <jansson.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_jsonrpc_error;
struct wf_json;
extern void wf_impl_operation_read(
fuse_req_t request,
fuse_ino_t ino, size_t size, off_t off,
struct fuse_file_info *fi);
extern char * wf_impl_fill_buffer(
char const * data,
extern char * wf_impl_operation_read_transform(
char * data,
size_t data_size,
char const * format,
size_t count,
@ -25,8 +26,8 @@ extern char * wf_impl_fill_buffer(
extern void wf_impl_operation_read_finished(
void * user_data,
json_t const * result,
json_t const * error);
struct wf_json const * result,
struct wf_jsonrpc_error const * error);
#ifdef __cplusplus

@ -10,6 +10,7 @@
#include <unistd.h>
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/util/util.h"
#include "webfuse/impl/util/json_util.h"
@ -68,8 +69,8 @@ static size_t wf_impl_min(size_t a, size_t b)
void wf_impl_operation_readdir_finished(
void * user_data,
json_t const * result,
json_t const * error)
struct wf_json const * result,
struct wf_jsonrpc_error const * error)
{
wf_status status = wf_impl_jsonrpc_get_status(error);
struct wf_impl_operation_readdir_context * context = user_data;
@ -77,21 +78,21 @@ void wf_impl_operation_readdir_finished(
struct wf_impl_dirbuffer buffer;
wf_impl_dirbuffer_init(&buffer);
if (json_is_array(result))
if ((NULL != result) && (wf_impl_json_is_array(result)))
{
size_t const count = json_array_size(result);
size_t const count = wf_impl_json_array_size(result);
for(size_t i = 0; i < count; i++)
{
json_t * entry =json_array_get(result, i);
if (json_is_object(entry))
struct wf_json const * entry = wf_impl_json_array_get(result, i);
if (wf_impl_json_is_object(entry))
{
json_t * name_holder = json_object_get(entry, "name");
json_t * inode_holder = json_object_get(entry, "inode");
struct wf_json const * name_holder = wf_impl_json_object_get(entry, "name");
struct wf_json const * inode_holder = wf_impl_json_object_get(entry, "inode");
if ((json_is_string(name_holder)) && (json_is_integer(inode_holder)))
if ((wf_impl_json_is_string(name_holder)) && (wf_impl_json_is_int(inode_holder)))
{
char const * name = json_string_value(name_holder);
fuse_ino_t entry_inode = (fuse_ino_t) json_integer_value(inode_holder);
char const * name = wf_impl_json_string_get(name_holder);
fuse_ino_t entry_inode = (fuse_ino_t) wf_impl_json_int_get(inode_holder);
wf_impl_dirbuffer_add(context->request, &buffer, name, entry_inode);
}
else

@ -2,13 +2,15 @@
#define WF_ADAPTER_IMPL_OPERATION_READDIR_H
#include "webfuse/impl/fuse_wrapper.h"
#include <jansson.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_jsonrpc_error;
struct wf_json;
struct wf_impl_operation_readdir_context
{
fuse_req_t request;
@ -25,8 +27,8 @@ extern void wf_impl_operation_readdir (
extern void wf_impl_operation_readdir_finished(
void * user_data,
json_t const * result,
json_t const * error);
struct wf_json const * result,
struct wf_jsonrpc_error const * error);
#ifdef __cplusplus
}

@ -12,6 +12,8 @@
#include "webfuse/impl/status.h"
#include "webfuse/impl/jsonrpc/request.h"
#include "webfuse/impl/jsonrpc/response_writer.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/timer/manager.h"
#include "webfuse/impl/timer/timer.h"
@ -113,17 +115,17 @@ void wf_impl_server_protocol_init_lws(
static void wf_impl_server_protocol_authenticate(
struct wf_jsonrpc_request * request,
char const * WF_UNUSED_PARAM(method_name),
json_t * params,
struct wf_json const * params,
void * WF_UNUSED_PARAM(user_data))
{
bool result = false;
json_t * type_holder = json_array_get(params, 0);
json_t * creds_holder = json_array_get(params, 1);
struct wf_json const * type_holder = wf_impl_json_array_get(params, 0);
struct wf_json const * creds_holder = wf_impl_json_array_get(params, 1);
if (json_is_string(type_holder) && json_is_object(creds_holder))
if ((wf_impl_json_is_string(type_holder)) && (wf_impl_json_is_object(creds_holder)))
{
char const * type = json_string_value(type_holder);
char const * type = wf_impl_json_string_get(type_holder);
struct wf_credentials creds;
wf_impl_credentials_init(&creds, type, creds_holder);
@ -136,8 +138,7 @@ static void wf_impl_server_protocol_authenticate(
if (result)
{
json_t * result = json_object();
wf_impl_jsonrpc_respond(request, result);
wf_impl_jsonrpc_respond(request);
}
else
{
@ -163,7 +164,7 @@ static bool wf_impl_server_protocol_check_name(char const * value)
static void wf_impl_server_protocol_add_filesystem(
struct wf_jsonrpc_request * request,
char const * WF_UNUSED_PARAM(method_name),
json_t * params,
struct wf_json const * params,
void * WF_UNUSED_PARAM(user_data))
{
struct wf_impl_session * session = wf_impl_jsonrpc_request_get_userdata(request);
@ -172,10 +173,10 @@ static void wf_impl_server_protocol_add_filesystem(
char const * name = NULL;
if (WF_GOOD == status)
{
json_t * name_holder = json_array_get(params, 0);
if (json_is_string(name_holder))
struct wf_json const * name_holder = wf_impl_json_array_get(params, 0);
if (wf_impl_json_is_string(name_holder))
{
name = json_string_value(name_holder);
name = wf_impl_json_string_get(name_holder);
if (wf_impl_server_protocol_check_name(name))
{
bool const success = wf_impl_session_add_filesystem(session, name);
@ -198,16 +199,14 @@ static void wf_impl_server_protocol_add_filesystem(
if (WF_GOOD == status)
{
json_t * result = json_object();
json_object_set_new(result, "id", json_string(name));
wf_impl_jsonrpc_respond(request, result);
struct wf_jsonrpc_response_writer * writer = wf_impl_jsonrpc_request_get_response_writer(request);
wf_impl_jsonrpc_response_add_string(writer, "id", name);
wf_impl_jsonrpc_respond(request);
}
else
{
wf_impl_jsonrpc_respond_error(request, status, wf_impl_status_tostring(status));
}
}
void wf_impl_server_protocol_init(

@ -11,6 +11,7 @@
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/jsonrpc/request.h"
#include "webfuse/impl/jsonrpc/response.h"
#include "webfuse/impl/json/doc.h"
#include <libwebsockets.h>
#include <stddef.h>
@ -20,15 +21,13 @@
#define WF_DEFAULT_MESSAGE_SIZE (8 * 1024)
static bool wf_impl_session_send(
json_t * request,
struct wf_message * message,
void * user_data)
{
struct wf_impl_session * session = user_data;
struct wf_message * message = wf_impl_message_create(request);
bool result = false;
bool result = (session->is_authenticated || wf_impl_jsonrpc_is_response(request)) && (NULL != session->wsi);
if (result)
if (NULL != session->wsi)
{
wf_impl_slist_append(&session->messages, &message->item);
lws_callback_on_writable(session->wsi);
@ -151,12 +150,13 @@ void wf_impl_session_onwritable(
static void wf_impl_session_process(
struct wf_impl_session * session,
char const * data,
char * data,
size_t length)
{
json_t * message = json_loadb(data, length, 0, NULL);
if (NULL != message)
struct wf_json_doc * doc = wf_impl_json_doc_loadb(data, length);
if (NULL != doc)
{
struct wf_json const * message = wf_impl_json_doc_root(doc);
if (wf_impl_jsonrpc_is_response(message))
{
wf_impl_jsonrpc_proxy_onresult(session->rpc, message);
@ -166,13 +166,13 @@ static void wf_impl_session_process(
wf_impl_jsonrpc_server_process(session->server, message, &wf_impl_session_send, session);
}
json_decref(message);
wf_impl_json_doc_dispose(doc);
}
}
void wf_impl_session_receive(
struct wf_impl_session * session,
char const * data,
char * data,
size_t length,
bool is_final_fragment)
{

@ -62,7 +62,7 @@ extern bool wf_impl_session_add_filesystem(
extern void wf_impl_session_receive(
struct wf_impl_session * session,
char const * data,
char * data,
size_t length,
bool is_final_fragment);

@ -1,13 +1,20 @@
#include "webfuse/impl/util/json_util.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/impl/json/node.h"
int wf_impl_json_get_int(json_t const * object, char const * key, int default_value)
int
wf_impl_json_get_int(
struct wf_json const * object,
char const * key,
int default_value)
{
if (NULL == object) { return default_value; }
int result = default_value;
json_t * holder = json_object_get(object, key);
if (json_is_integer(holder))
struct wf_json const * holder = wf_impl_json_object_get(object, key);
if (wf_impl_json_is_int(holder))
{
result = json_integer_value(holder);
result = wf_impl_json_int_get(holder);
}
return result;
@ -15,12 +22,12 @@ int wf_impl_json_get_int(json_t const * object, char const * key, int default_va
wf_status
wf_impl_jsonrpc_get_status(
json_t const * error)
struct wf_jsonrpc_error const * error)
{
wf_status status = WF_GOOD;
if (NULL != error)
{
status = wf_impl_json_get_int(error, "code", WF_BAD_FORMAT);
status = wf_impl_jsonrpc_error_code(error);
}
return status;

@ -1,7 +1,6 @@
#ifndef WF_IMPL_UTIL_JSON_UTIL_H
#define WF_IMPL_UTIL_JSON_UTIL_H
#include <jansson.h>
#include "webfuse/status.h"
#ifdef __cplusplus
@ -9,15 +8,18 @@ extern "C"
{
#endif
struct wf_jsonrpc_error;
struct wf_json;
extern int
wf_impl_json_get_int(
json_t const * object,
struct wf_json const * object,
char const * key,
int default_value);
extern wf_status
wf_impl_jsonrpc_get_status(
json_t const * error);
struct wf_jsonrpc_error const * error);
#ifdef __cplusplus
}

@ -9,7 +9,6 @@ if not libwebsockets_dep.found()
libwebsockets_dep = libwebsockets.dependency('websockets_shared')
endif
jansson_dep = dependency('jansson', version: '>=2.11', fallback: ['jansson', 'jansson_dep'])
libfuse_dep = dependency('fuse3', version: '>=3.8.0', fallback: ['fuse3', 'libfuse_dep'])
pkg_config = import('pkgconfig')
@ -29,6 +28,10 @@ webfuse_static = static_library('webfuse',
'lib/webfuse/impl/timer/timepoint.c',
'lib/webfuse/impl/timer/timer.c',
'lib/webfuse/impl/json/writer.c',
'lib/webfuse/impl/json/node.c',
'lib/webfuse/impl/json/doc.c',
'lib/webfuse/impl/json/reader.c',
'lib/webfuse/impl/json/parser.c',
'lib/webfuse/impl/jsonrpc/proxy.c',
'lib/webfuse/impl/jsonrpc/proxy_request_manager.c',
'lib/webfuse/impl/jsonrpc/proxy_variadic.c',
@ -36,6 +39,7 @@ webfuse_static = static_library('webfuse',
'lib/webfuse/impl/jsonrpc/method.c',
'lib/webfuse/impl/jsonrpc/request.c',
'lib/webfuse/impl/jsonrpc/response.c',
'lib/webfuse/impl/jsonrpc/response_writer.c',
'lib/webfuse/impl/jsonrpc/error.c',
'lib/webfuse/impl/message.c',
'lib/webfuse/impl/message_queue.c',
@ -63,31 +67,31 @@ webfuse_static = static_library('webfuse',
'lib/webfuse/impl/client_tlsconfig.c',
c_args: ['-fvisibility=hidden'],
include_directories: private_inc_dir,
dependencies: [libfuse_dep, libwebsockets_dep, jansson_dep])
dependencies: [libfuse_dep, libwebsockets_dep])
webfuse_static_dep = declare_dependency(
include_directories: inc_dir,
link_with: [webfuse_static],
dependencies: [libfuse_dep, libwebsockets_dep, jansson_dep])
dependencies: [libfuse_dep, libwebsockets_dep])
webfuse = shared_library('webfuse',
'lib/webfuse/api.c',
version: meson.project_version(),
c_args: ['-fvisibility=hidden', '-DWF_API=WF_EXPORT'],
include_directories: private_inc_dir,
dependencies: [webfuse_static_dep, libfuse_dep, libwebsockets_dep, jansson_dep],
dependencies: [webfuse_static_dep, libfuse_dep, libwebsockets_dep],
install: true)
webfuse_dep = declare_dependency(
include_directories: inc_dir,
link_with: [webfuse],
dependencies: [libfuse_dep, libwebsockets_dep, jansson_dep])
dependencies: [libfuse_dep, libwebsockets_dep])
install_subdir('include/webfuse', install_dir: 'include')
pkg_config.generate(
libraries: [webfuse],
requires: ['fuse3', 'libwebsockets', 'jansson'],
requires: ['fuse3', 'libwebsockets'],
subdirs: '.',
version: meson.project_version(),
name: 'libwebfuse',
@ -117,6 +121,10 @@ test_certs_dep = declare_dependency(
alltests = executable('alltests',
'test/webfuse/json/test_writer.cc',
'test/webfuse/json/test_doc.cc',
'test/webfuse/json/test_node.cc',
'test/webfuse/json/test_reader.cc',
'test/webfuse/json/test_parser.cc',
'test/webfuse/jsonrpc/mock_timer_callback.cc',
'test/webfuse/jsonrpc/mock_timer.cc',
'test/webfuse/jsonrpc/test_is_request.cc',
@ -136,8 +144,8 @@ alltests = executable('alltests',
'test/webfuse/test_util/ws_client.cc',
'test/webfuse/test_util/adapter_client.cc',
'test/webfuse/test_util/file.cc',
'test/webfuse/test_util/jansson_test_environment.cc',
'test/webfuse/test_util/lws_test_environment.cc',
'test/webfuse/test_util/json_doc.cc',
'test/webfuse/mocks/mock_authenticator.cc',
'test/webfuse/mocks/mock_fuse.cc',
'test/webfuse/mocks/mock_operation_context.cc',
@ -193,7 +201,6 @@ alltests = executable('alltests',
webfuse_static_dep,
libwebsockets_dep,
libfuse_dep,
jansson_dep,
gtest_dep,
gmock_main_dep,
test_certs_dep

@ -1,10 +0,0 @@
[wrap-file]
directory = jansson-2.11
source_url = http://www.digip.org/jansson/releases/jansson-2.11.tar.bz2
source_filename = jansson-2.11.tar.bz2
source_hash = 783132e2fc970feefc2fa54199ef65ee020bd8e0e991a78ea44b8586353a0947
patch_url = https://wrapdb.mesonbuild.com/v1/projects/jansson/2.11/3/get_zip
patch_filename = jansson-2.11-3-wrap.zip
patch_hash = 0bcac510994890048d42658c674e33dd7d88715fc1e3bf49d10012f57b0e0020

@ -0,0 +1,23 @@
#include "webfuse/impl/json/doc.h"
#include "webfuse/impl/json/node.h"
#include <gtest/gtest.h>
TEST(json_doc, loadb)
{
char text[] = "true";
wf_json_doc * doc = wf_impl_json_doc_loadb(text, 4);
ASSERT_NE(nullptr, doc);
wf_json const * root = wf_impl_json_doc_root(doc);
ASSERT_EQ(WF_JSON_TYPE_BOOL, wf_impl_json_type(root));
ASSERT_TRUE(wf_impl_json_bool_get(root));
wf_impl_json_doc_dispose(doc);
}
TEST(json_doc, loadb_fail_invalid_json)
{
char text[] = "true";
wf_json_doc * doc = wf_impl_json_doc_loadb(text, 3);
ASSERT_EQ(nullptr, doc);
}

@ -0,0 +1,89 @@
#include "webfuse/impl/json/node.h"
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
TEST(json_node, null)
{
JsonDoc doc("null");
ASSERT_EQ(WF_JSON_TYPE_NULL, wf_impl_json_type(doc.root()));
ASSERT_TRUE(wf_impl_json_is_null(doc.root()));
}
TEST(json_node, true)
{
JsonDoc doc("true");
ASSERT_EQ(WF_JSON_TYPE_BOOL, wf_impl_json_type(doc.root()));
ASSERT_TRUE(wf_impl_json_is_bool(doc.root()));
ASSERT_TRUE(wf_impl_json_bool_get(doc.root()));
}
TEST(json_node, false)
{
JsonDoc doc("false");
ASSERT_EQ(WF_JSON_TYPE_BOOL, wf_impl_json_type(doc.root()));
ASSERT_TRUE(wf_impl_json_is_bool(doc.root()));
ASSERT_FALSE(wf_impl_json_bool_get(doc.root()));
}
TEST(json_node, int)
{
JsonDoc doc("42");
ASSERT_EQ(WF_JSON_TYPE_INT, wf_impl_json_type(doc.root()));
ASSERT_TRUE(wf_impl_json_is_int(doc.root()));
ASSERT_EQ(42, wf_impl_json_int_get(doc.root()));
}
TEST(json_node, string)
{
JsonDoc doc("\"brummni\"");
ASSERT_EQ(WF_JSON_TYPE_STRING, wf_impl_json_type(doc.root()));
ASSERT_TRUE(wf_impl_json_is_string(doc.root()));
ASSERT_STREQ("brummni", wf_impl_json_string_get(doc.root()));
}
TEST(json_node, array)
{
JsonDoc doc("[1,2,3]");
ASSERT_EQ(WF_JSON_TYPE_ARRAY, wf_impl_json_type(doc.root()));
ASSERT_TRUE(wf_impl_json_is_array(doc.root()));
ASSERT_EQ(3, wf_impl_json_array_size(doc.root()));
ASSERT_EQ(WF_JSON_TYPE_INT, wf_impl_json_type(wf_impl_json_array_get(doc.root(), 0)));
ASSERT_EQ(WF_JSON_TYPE_UNDEFINED, wf_impl_json_type(wf_impl_json_array_get(doc.root(), 4)));
}
TEST(json_node, object)
{
JsonDoc doc("{\"answer\": 42}");
ASSERT_EQ(WF_JSON_TYPE_OBJECT, wf_impl_json_type(doc.root()));
ASSERT_TRUE(wf_impl_json_is_object(doc.root()));
ASSERT_EQ(1, wf_impl_json_object_size(doc.root()));
ASSERT_EQ(WF_JSON_TYPE_INT, wf_impl_json_type(wf_impl_json_object_get(doc.root(), "answer")));
ASSERT_STREQ("answer", wf_impl_json_object_key(doc.root(), 0));
ASSERT_EQ(WF_JSON_TYPE_INT, wf_impl_json_type(wf_impl_json_object_value(doc.root(), 0)));
ASSERT_EQ(WF_JSON_TYPE_UNDEFINED, wf_impl_json_type(wf_impl_json_object_get(doc.root(), "unknown")));
ASSERT_STREQ("", wf_impl_json_object_key(doc.root(), 1));
ASSERT_EQ(WF_JSON_TYPE_UNDEFINED, wf_impl_json_type(wf_impl_json_object_value(doc.root(), 1)));
}
TEST(json_node, default_values)
{
JsonDoc doc("null");
ASSERT_EQ (false, wf_impl_json_bool_get(doc.root()));
ASSERT_EQ (0 , wf_impl_json_int_get(doc.root()));
ASSERT_STREQ("" , wf_impl_json_string_get(doc.root()));
ASSERT_EQ (0 , wf_impl_json_array_size(doc.root()));
ASSERT_EQ (WF_JSON_TYPE_UNDEFINED, wf_impl_json_type(wf_impl_json_array_get(doc.root(), 0)));
ASSERT_EQ (0 , wf_impl_json_object_size(doc.root()));
ASSERT_STREQ("" , wf_impl_json_object_key(doc.root(), 0));
ASSERT_EQ (WF_JSON_TYPE_UNDEFINED, wf_impl_json_type(wf_impl_json_object_get(doc.root(), 0)));
ASSERT_EQ (WF_JSON_TYPE_UNDEFINED, wf_impl_json_type(wf_impl_json_object_value(doc.root(), 0)));
}

@ -0,0 +1,123 @@
#include "webfuse/impl/json/parser.h"
#include "webfuse/impl/json/reader.h"
#include "webfuse/impl/json/node_intern.h"
#include <gtest/gtest.h>
#include <string>
namespace
{
bool try_parse(std::string const & value)
{
std::string contents = value;
struct wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(contents.data()), contents.size());
wf_json json;
bool const result = wf_impl_json_parse_value(&reader, &json);
if (result)
{
wf_impl_json_cleanup(&json);
}
return result;
}
}
TEST(json_parser, fail_no_contents)
{
ASSERT_FALSE(try_parse(""));
}
TEST(json_parser, fail_invalid_null)
{
ASSERT_FALSE(try_parse("none"));
}
TEST(json_parser, fail_invalid_true)
{
ASSERT_FALSE(try_parse("tru"));
}
TEST(json_parser, fail_invalid_false)
{
ASSERT_FALSE(try_parse("fals"));
}
TEST(json_parser, fail_invalid_int)
{
ASSERT_FALSE(try_parse("-"));
}
TEST(json_parser, fail_invalid_string)
{
ASSERT_FALSE(try_parse("\"invalid"));
}
TEST(json_parser, empty_array)
{
ASSERT_TRUE(try_parse("[]"));
}
TEST(json_parser, large_array)
{
ASSERT_TRUE(try_parse("[1,2,3,4,5,6,7,8,9]"));
}
TEST(json_parser, fail_unterminated_array)
{
ASSERT_FALSE(try_parse("[1"));
}
TEST(json_parser, fail_missing_array_separator)
{
ASSERT_FALSE(try_parse("[1 2]"));
}
TEST(json_parser, fail_missing_array_value)
{
ASSERT_FALSE(try_parse("[1,]"));
}
TEST(json_parser, empty_object)
{
ASSERT_TRUE(try_parse("{}"));
}
TEST(json_parser, large_object)
{
ASSERT_TRUE(try_parse("{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}"));
}
TEST(json_parser, fail_unterminated_object)
{
ASSERT_FALSE(try_parse("{\"a\":1"));
}
TEST(json_parser, fail_invalid_object_key)
{
ASSERT_FALSE(try_parse("{a:1}"));
}
TEST(json_parser, fail_missing_object_terminator)
{
ASSERT_FALSE(try_parse("{\"a\"1}"));
}
TEST(json_parser, fail_missing_object_value)
{
ASSERT_FALSE(try_parse("{\"a\":}"));
}
TEST(json_parser, fail_missing_object_separator)
{
ASSERT_FALSE(try_parse("{\"a\":1 \"b\":2}"));
}
TEST(json_parser, fail_missing_object_item)
{
ASSERT_FALSE(try_parse("{\"a\":1,}"));
}

@ -0,0 +1,214 @@
#include "webfuse/impl/json/reader.h"
#include <gtest/gtest.h>
#include <climits>
TEST(json_reader, skip_whitespace)
{
char text[] = " \t\r\n*";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 5);
char c = wf_impl_json_reader_skip_whitespace(&reader);
ASSERT_EQ('*', c);
ASSERT_STREQ("*", &reader.contents[reader.pos]);
}
TEST(json_reader, skip_whitespace_eof)
{
char text[] = " ";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 1);
char c = wf_impl_json_reader_skip_whitespace(&reader);
ASSERT_EQ('\0', c);
}
TEST(json_reader, peek)
{
char text[] = "*";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 1);
char c = wf_impl_json_reader_peek(&reader);
ASSERT_EQ('*', c);
}
TEST(json_reader, peek_eof)
{
wf_json_reader reader;
wf_impl_json_reader_init(&reader, nullptr, 0);
char c = wf_impl_json_reader_peek(&reader);
ASSERT_EQ('\0', c);
}
TEST(json_reader, get_char)
{
char text[] = "*";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 1);
ASSERT_EQ('*', wf_impl_json_reader_get_char(&reader));
ASSERT_EQ('\0', wf_impl_json_reader_get_char(&reader));
ASSERT_EQ('\0', wf_impl_json_reader_get_char(&reader));
}
TEST(json_reader, unget_char)
{
char text[] = "*";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 1);
ASSERT_EQ('*', wf_impl_json_reader_get_char(&reader));
wf_impl_json_reader_unget_char(&reader);
ASSERT_EQ('*', wf_impl_json_reader_get_char(&reader));
wf_impl_json_reader_unget_char(&reader);
wf_impl_json_reader_unget_char(&reader);
ASSERT_EQ('*', wf_impl_json_reader_get_char(&reader));
}
TEST(json_reader, read_const)
{
char text[] = "value";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 5);
ASSERT_TRUE(wf_impl_json_reader_read_const(&reader, "value", 5));
}
TEST(json_reader, read_const_fail_out_of_bounds)
{
char text[] = "value";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 2);
ASSERT_FALSE(wf_impl_json_reader_read_const(&reader, "value", 5));
}
TEST(json_reader, read_const_fail_no_match)
{
char text[] = "hello";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 5);
ASSERT_FALSE(wf_impl_json_reader_read_const(&reader, "value", 5));
}
TEST(json_reader, read_positive_int)
{
char text[] = "42";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 5);
int value;
ASSERT_TRUE(wf_impl_json_reader_read_int(&reader, &value));
ASSERT_EQ(42, value);
}
TEST(json_reader, read_negative_int)
{
char text[] = "-1234";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, text, 5);
int value;
ASSERT_TRUE(wf_impl_json_reader_read_int(&reader, &value));
ASSERT_EQ(-1234, value);
}
TEST(json_reader, read_int_max)
{
std::string text = std::to_string(INT_MAX);
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
int value;
ASSERT_TRUE(wf_impl_json_reader_read_int(&reader, &value));
ASSERT_EQ(INT_MAX, value);
}
TEST(json_reader, read_int_min)
{
std::string text = std::to_string(INT_MIN);
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
int value;
ASSERT_TRUE(wf_impl_json_reader_read_int(&reader, &value));
ASSERT_EQ(INT_MIN, value);
}
TEST(json_reader, read_int_fail_invalid)
{
std::string text = "brummni";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
int value;
ASSERT_FALSE(wf_impl_json_reader_read_int(&reader, &value));
}
TEST(json_reader, read_int_fail_sign_only)
{
std::string text = "-";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
int value;
ASSERT_FALSE(wf_impl_json_reader_read_int(&reader, &value));
}
TEST(json_reader, read_string)
{
std::string text = "\"brummni\"";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
char * value;
size_t size;
ASSERT_TRUE(wf_impl_json_reader_read_string(&reader, &value, &size));
ASSERT_STREQ("brummni", value);
ASSERT_EQ(7, size);
}
TEST(json_reader, read_string_escaped)
{
std::string text = "\"_\\\"_\\\\_\\/_\\b_\\f_\\n_\\r_\\t_\"";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
char * value;
size_t size;
ASSERT_TRUE(wf_impl_json_reader_read_string(&reader, &value, &size));
ASSERT_STREQ("_\"_\\_/_\b_\f_\n_\r_\t_", value);
ASSERT_EQ(17, size);
}
TEST(json_reader, read_string_fail_missig_start_quot)
{
std::string text = "brummni\"";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
char * value;
size_t size;
ASSERT_FALSE(wf_impl_json_reader_read_string(&reader, &value, &size));
}
TEST(json_reader, read_string_fail_missig_end_quot)
{
std::string text = "\"brummni";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
char * value;
size_t size;
ASSERT_FALSE(wf_impl_json_reader_read_string(&reader, &value, &size));
}
TEST(json_reader, read_string_fail_invalid_escape_seq)
{
std::string text = "\"\\i\"";
wf_json_reader reader;
wf_impl_json_reader_init(&reader, const_cast<char*>(text.data()), text.size());
char * value;
size_t size;
ASSERT_FALSE(wf_impl_json_reader_read_string(&reader, &value, &size));
}

@ -194,3 +194,77 @@ TEST(json_writer, write_deep_nested_array)
ASSERT_EQ(expected, writer.take());
}
TEST(json_writer, write_bytes)
{
writer writer;
wf_impl_json_write_bytes(writer, "\0\0", 2);
ASSERT_EQ("\"AAA=\"", writer.take());
}
TEST(json_writer, reset)
{
writer writer;
wf_impl_json_write_string(writer, "some value");
wf_impl_json_writer_reset(writer);
wf_impl_json_write_int(writer,42);
ASSERT_EQ("42", writer.take());
}
TEST(json_writer, write_object_null)
{
writer writer;
wf_impl_json_write_object_begin(writer);
wf_impl_json_write_object_null(writer, "error");
wf_impl_json_write_object_end(writer);
ASSERT_EQ("{\"error\":null}", writer.take());
}
TEST(json_writer, write_object_bool)
{
writer writer;
wf_impl_json_write_object_begin(writer);
wf_impl_json_write_object_bool(writer, "result", true);
wf_impl_json_write_object_end(writer);
ASSERT_EQ("{\"result\":true}", writer.take());
}
TEST(json_writer, write_object_string_nocheck)
{
writer writer;
wf_impl_json_write_object_begin(writer);
wf_impl_json_write_object_string_nocheck(writer, "result", "Hello,\tWorld!");
wf_impl_json_write_object_end(writer);
ASSERT_EQ("{\"result\":\"Hello,\tWorld!\"}", writer.take());
}
TEST(json_writer, write_object_bytes)
{
writer writer;
wf_impl_json_write_object_begin(writer);
wf_impl_json_write_object_bytes(writer, "result", "\0\0", 2);
wf_impl_json_write_object_end(writer);
ASSERT_EQ("{\"result\":\"AAA=\"}", writer.take());
}
TEST(json_writer, realloc_buffer)
{
writer writer(1);
wf_impl_json_write_string(writer, "very large contents");
ASSERT_EQ("\"very large contents\"", writer.take());
}
TEST(json_writer, unexpected_end)
{
writer writer;
wf_impl_json_write_array_end(writer);
}

@ -1,28 +1,21 @@
#include <gtest/gtest.h>
#include "webfuse/impl/jsonrpc/request.h"
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
TEST(wf_jsonrpc_is_request, request_with_object_params)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("method"));
json_object_set_new(request, "params", json_object());
json_object_set_new(request, "id", json_integer(42));
JsonDoc doc("{\"method\": \"method\", \"params\": {}, \"id\": 42}");
ASSERT_TRUE(wf_impl_jsonrpc_is_request(request));
json_decref(request);
ASSERT_TRUE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, request_with_array_params)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("method"));
json_object_set_new(request, "params", json_array());
json_object_set_new(request, "id", json_integer(42));
ASSERT_TRUE(wf_impl_jsonrpc_is_request(request));
JsonDoc doc("{\"method\": \"method\", \"params\": [], \"id\": 42}");
json_decref(request);
ASSERT_TRUE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, null_request)
@ -32,81 +25,49 @@ TEST(wf_jsonrpc_is_request, null_request)
TEST(wf_jsonrpc_is_request, invalid_request)
{
json_t * request = json_array();
json_array_append_new(request, json_string("method"));
json_array_append_new(request, json_object());
json_array_append_new(request, json_integer(42));
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
JsonDoc doc("[\"method\", {}, 42]");
json_decref(request);
ASSERT_FALSE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, invalid_request_without_id)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("method"));
json_object_set_new(request, "params", json_object());
JsonDoc doc("{\"method\": \"method\", \"params\": {}}");
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
json_decref(request);
ASSERT_FALSE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, invalid_request_due_to_invalid_id)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("method"));
json_object_set_new(request, "params", json_object());
json_object_set_new(request, "id", json_string("42"));
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
JsonDoc doc("{\"method\": \"method\", \"params\": [], \"id\": \"42\"}");
json_decref(request);
ASSERT_FALSE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, invalid_request_without_method)
{
json_t * request = json_object();
json_object_set_new(request, "params", json_object());
json_object_set_new(request, "id", json_integer(42));
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
JsonDoc doc("{\"params\": [], \"id\": 42}");
json_decref(request);
ASSERT_FALSE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, invalid_request_due_to_invalid_method)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_integer(42));
json_object_set_new(request, "params", json_object());
json_object_set_new(request, "id", json_integer(42));
JsonDoc doc("{\"method\": 42, \"params\": [], \"id\": 42}");
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
json_decref(request);
ASSERT_FALSE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, invalid_request_without_params)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("method"));
json_object_set_new(request, "id", json_integer(42));
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
JsonDoc doc("{\"method\": \"method\", \"id\": 42}");
json_decref(request);
ASSERT_FALSE(wf_impl_jsonrpc_is_request(doc.root()));
}
TEST(wf_jsonrpc_is_request, invalid_request_due_to_invalid_params)
{
json_t * request = json_object();
json_object_set_new(request, "methdo", json_string("method"));
json_object_set_new(request, "params", json_string("params"));
json_object_set_new(request, "id", json_integer(42));
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
JsonDoc doc("{\"method\": \"method\", \"params\": \"params\", \"id\": 42}");
json_decref(request);
ASSERT_FALSE(wf_impl_jsonrpc_is_request(doc.root()));
}

@ -1,37 +1,28 @@
#include <gtest/gtest.h>
#include "webfuse/impl/jsonrpc/response.h"
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
TEST(wf_jsonrpc_is_response, valid_result)
{
json_t * message = json_object();
json_object_set_new(message, "result", json_object());
json_object_set_new(message, "id", json_integer(42));
JsonDoc doc("{\"result\": {}, \"id\": 42}");
ASSERT_TRUE(wf_impl_jsonrpc_is_response(message));
json_decref(message);
ASSERT_TRUE(wf_impl_jsonrpc_is_response(doc.root()));
}
TEST(wf_jsonrpc_is_response, valid_result_string)
{
json_t * message = json_object();
json_object_set_new(message, "result", json_string("also valid"));
json_object_set_new(message, "id", json_integer(42));
ASSERT_TRUE(wf_impl_jsonrpc_is_response(message));
JsonDoc doc("{\"result\": \"also valid\", \"id\": 42}");
json_decref(message);
ASSERT_TRUE(wf_impl_jsonrpc_is_response(doc.root()));
}
TEST(wf_jsonrpc_is_response, valid_error)
{
json_t * message = json_object();
json_object_set_new(message, "error", json_object());
json_object_set_new(message, "id", json_integer(42));
ASSERT_TRUE(wf_impl_jsonrpc_is_response(message));
JsonDoc doc("{\"error\": {}, \"id\": 42}");
json_decref(message);
ASSERT_TRUE(wf_impl_jsonrpc_is_response(doc.root()));
}
TEST(wf_jsonrpc_is_response, invalid_null)
@ -41,54 +32,36 @@ TEST(wf_jsonrpc_is_response, invalid_null)
TEST(wf_jsonrpc_is_response, invalid_message)
{
json_t * message = json_array();
json_array_append_new(message, json_object());
json_array_append_new(message, json_integer(42));
JsonDoc doc("[{}, 42]");
ASSERT_FALSE(wf_impl_jsonrpc_is_response(message));
json_decref(message);
ASSERT_FALSE(wf_impl_jsonrpc_is_response(doc.root()));
}
TEST(wf_jsonrpc_is_response, invalid_missing_id)
{
json_t * message = json_object();
json_object_set_new(message, "result", json_object());
ASSERT_FALSE(wf_impl_jsonrpc_is_response(message));
JsonDoc doc("{\"result\": {}}");
json_decref(message);
ASSERT_FALSE(wf_impl_jsonrpc_is_response(doc.root()));
}
TEST(wf_jsonrpc_is_response, invalid_id_wrong_type)
{
json_t * message = json_object();
json_object_set_new(message, "result", json_object());
json_object_set_new(message, "id", json_string("42"));
ASSERT_FALSE(wf_impl_jsonrpc_is_response(message));
JsonDoc doc("{\"result\": {}, \"id\": \"42\"}");
json_decref(message);
ASSERT_FALSE(wf_impl_jsonrpc_is_response(doc.root()));
}
TEST(wf_jsonrpc_is_response, invalid_missing_result_and_error)
{
json_t * message = json_object();
json_object_set_new(message, "id", json_integer(42));
JsonDoc doc("{\"id\": 42}");
ASSERT_FALSE(wf_impl_jsonrpc_is_response(message));
json_decref(message);
ASSERT_FALSE(wf_impl_jsonrpc_is_response(doc.root()));
}
TEST(wf_jsonrpc_is_response, invalid_error_wrong_type)
{
json_t * message = json_object();
json_object_set_new(message, "error", json_array());
json_object_set_new(message, "id", json_integer(42));
ASSERT_FALSE(wf_impl_jsonrpc_is_response(message));
JsonDoc doc("{\"error\": [], \"id\": 42}");
json_decref(message);
ASSERT_FALSE(wf_impl_jsonrpc_is_response(doc.root()));
}

@ -1,15 +1,20 @@
#include <gtest/gtest.h>
#include "webfuse/impl/jsonrpc/proxy.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/message.h"
#include "webfuse/status.h"
#include "webfuse/impl/timer/manager.h"
#include "webfuse/jsonrpc/mock_timer.hpp"
#include "webfuse/test_util/json_doc.hpp"
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
using wf_jsonrpc_test::MockTimer;
using webfuse_test::JsonDoc;
using testing::Return;
using testing::_;
using testing::DoAll;
@ -19,55 +24,42 @@ using testing::SaveArg;
namespace
{
int jsonrpc_get_status(json_t * error)
{
json_t * code = json_object_get(error, "code");
return (json_is_integer(code)) ? json_integer_value(code) : WF_BAD_FORMAT;
}
struct SendContext
{
json_t * response;
JsonDoc doc;
wf_json const * response;
bool result;
bool is_called;
explicit SendContext(bool result_ = true)
: response(nullptr)
: doc("null")
, response(nullptr)
, result(result_)
, is_called(false)
{
}
~SendContext()
{
if (nullptr != response)
{
json_decref(response);
}
}
};
bool jsonrpc_send(
json_t * request,
wf_message * request,
void * user_data)
{
SendContext * context = reinterpret_cast<SendContext*>(user_data);
context->is_called = true;
context->response = request;
json_incref(request);
context->doc = std::move(JsonDoc(std::string(request->data, request->length)));
context->response = context->doc.root();
wf_impl_message_dispose(request);
return context->result;
}
struct FinishedContext
{
bool is_called;
json_t * result;
json_t * error;
wf_jsonrpc_error * error;
FinishedContext()
: is_called(false)
, result(nullptr)
, error(nullptr)
{
@ -75,27 +67,23 @@ namespace
~FinishedContext()
{
if (nullptr != result)
{
json_decref(result);
}
if (nullptr != error)
{
json_decref(error);
}
wf_impl_jsonrpc_error_dispose(error);
}
};
void jsonrpc_finished(
void * user_data,
json_t const * result,
json_t const * error)
wf_json const *,
wf_jsonrpc_error const * error)
{
FinishedContext * context = reinterpret_cast<FinishedContext*>(user_data);
context->is_called = true;
context->result = json_deep_copy(result);
context->error = json_deep_copy(error);
if (nullptr != error)
{
context->error = wf_impl_jsonrpc_error(wf_impl_jsonrpc_error_code(error),
wf_impl_jsonrpc_error_message(error));
}
}
}
@ -126,22 +114,22 @@ TEST(wf_jsonrpc_proxy, invoke)
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
json_t * method = json_object_get(send_context.response, "method");
ASSERT_TRUE(json_is_string(method));
ASSERT_STREQ("foo", json_string_value(method));
wf_json const * method = wf_impl_json_object_get(send_context.response, "method");
ASSERT_TRUE(wf_impl_json_is_string(method));
ASSERT_STREQ("foo", wf_impl_json_string_get(method));
json_t * params = json_object_get(send_context.response, "params");
ASSERT_TRUE(json_is_array(params));
ASSERT_EQ(2, json_array_size(params));
ASSERT_TRUE(json_is_string(json_array_get(params, 0)));
ASSERT_STREQ("bar", json_string_value(json_array_get(params, 0)));
ASSERT_TRUE(json_is_integer(json_array_get(params, 1)));
ASSERT_EQ(42, json_integer_value(json_array_get(params, 1)));
wf_json const * params = wf_impl_json_object_get(send_context.response, "params");
ASSERT_TRUE(wf_impl_json_is_array(params));
ASSERT_EQ(2, wf_impl_json_array_size(params));
ASSERT_TRUE(wf_impl_json_is_string(wf_impl_json_array_get(params, 0)));
ASSERT_STREQ("bar", wf_impl_json_string_get(wf_impl_json_array_get(params, 0)));
ASSERT_TRUE(wf_impl_json_is_int(wf_impl_json_array_get(params, 1)));
ASSERT_EQ(42, wf_impl_json_int_get(wf_impl_json_array_get(params, 1)));
json_t * id = json_object_get(send_context.response, "id");
ASSERT_TRUE(json_is_integer(id));
wf_json const * id = wf_impl_json_object_get(send_context.response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
ASSERT_FALSE(finished_context.is_called);
@ -165,7 +153,7 @@ TEST(wf_jsonrpc_proxy, invoke_calls_finish_if_send_fails)
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
ASSERT_TRUE(finished_context.is_called);
ASSERT_FALSE(nullptr == finished_context.error);
@ -191,7 +179,7 @@ TEST(wf_jsonrpc_proxy, invoke_if_another_request_is_pending)
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data2, "foo", "");
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
ASSERT_FALSE(finished_context.is_called);
@ -199,7 +187,7 @@ TEST(wf_jsonrpc_proxy, invoke_if_another_request_is_pending)
wf_impl_timer_manager_dispose(timer_manager);
}
TEST(wf_jsonrpc_proxy, invoke_fails_if_request_is_invalid)
TEST(wf_jsonrpc_proxy, invoke_invalid_request)
{
struct wf_timer_manager * timer_manager = wf_impl_timer_manager_create();
@ -211,10 +199,9 @@ TEST(wf_jsonrpc_proxy, invoke_fails_if_request_is_invalid)
void * finished_data = reinterpret_cast<void*>(&finished_context);
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "?", "error");
ASSERT_FALSE(send_context.is_called);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(finished_context.is_called);
ASSERT_EQ(WF_BAD, jsonrpc_get_status(finished_context.error));
ASSERT_FALSE(finished_context.is_called);
wf_impl_jsonrpc_proxy_dispose(proxy);
wf_impl_timer_manager_dispose(timer_manager);
@ -233,22 +220,16 @@ TEST(wf_jsonrpc_proxy, on_result)
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
json_t * id = json_object_get(send_context.response, "id");
ASSERT_TRUE(json_is_number(id));
wf_json const * id = wf_impl_json_object_get(send_context.response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
json_t * response = json_object();
json_object_set_new(response, "result", json_string("okay"));
json_object_set(response, "id", id);
wf_impl_jsonrpc_proxy_onresult(proxy, response);
json_decref(response);
JsonDoc response("{\"result\": \"okay\", \"id\": " + std::to_string(wf_impl_json_int_get(id)) + "}");
wf_impl_jsonrpc_proxy_onresult(proxy, response.root());
ASSERT_TRUE(finished_context.is_called);
ASSERT_EQ(nullptr, finished_context.error);
ASSERT_TRUE(json_is_string(finished_context.result));
ASSERT_STREQ("okay", json_string_value(finished_context.result));
wf_impl_jsonrpc_proxy_dispose(proxy);
wf_impl_timer_manager_dispose(timer_manager);
@ -267,17 +248,13 @@ TEST(wf_jsonrpc_proxy, on_result_reject_response_with_unknown_id)
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
json_t * id = json_object_get(send_context.response, "id");
ASSERT_TRUE(json_is_number(id));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
json_t * response = json_object();
json_object_set_new(response, "result", json_string("okay"));
json_object_set_new(response, "id", json_integer(1 + json_integer_value(id)));
wf_json const * id = wf_impl_json_object_get(send_context.response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
wf_impl_jsonrpc_proxy_onresult(proxy, response);
json_decref(response);
JsonDoc response("{\"result\": \"okay\", \"id\": " + std::to_string(wf_impl_json_int_get(id) + 1) + "}");
wf_impl_jsonrpc_proxy_onresult(proxy, response.root());
ASSERT_FALSE(finished_context.is_called);
@ -298,13 +275,13 @@ TEST(wf_jsonrpc_proxy, timeout)
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
std::this_thread::sleep_for(10ms);
wf_impl_timer_manager_check(timer_manager);
ASSERT_TRUE(finished_context.is_called);
ASSERT_EQ(WF_BAD_TIMEOUT, jsonrpc_get_status(finished_context.error));
ASSERT_EQ(WF_BAD_TIMEOUT, wf_impl_jsonrpc_error_code(finished_context.error));
wf_impl_jsonrpc_proxy_dispose(proxy);
wf_impl_timer_manager_dispose(timer_manager);
@ -323,7 +300,7 @@ TEST(wf_jsonrpc_proxy, cleanup_pending_request)
wf_impl_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
ASSERT_FALSE(finished_context.is_called);
@ -347,28 +324,28 @@ TEST(wf_jsonrpc_proxy, notify)
wf_impl_jsonrpc_proxy_notify(proxy, "foo", "si", "bar", 42);
ASSERT_TRUE(send_context.is_called);
ASSERT_TRUE(json_is_object(send_context.response));
ASSERT_TRUE(wf_impl_json_is_object(send_context.response));
json_t * method = json_object_get(send_context.response, "method");
ASSERT_TRUE(json_is_string(method));
ASSERT_STREQ("foo", json_string_value(method));
wf_json const * method = wf_impl_json_object_get(send_context.response, "method");
ASSERT_TRUE(wf_impl_json_is_string(method));
ASSERT_STREQ("foo", wf_impl_json_string_get(method));
json_t * params = json_object_get(send_context.response, "params");
ASSERT_TRUE(json_is_array(params));
ASSERT_EQ(2, json_array_size(params));
ASSERT_TRUE(json_is_string(json_array_get(params, 0)));
ASSERT_STREQ("bar", json_string_value(json_array_get(params, 0)));
ASSERT_TRUE(json_is_integer(json_array_get(params, 1)));
ASSERT_EQ(42, json_integer_value(json_array_get(params, 1)));
wf_json const * params = wf_impl_json_object_get(send_context.response, "params");
ASSERT_TRUE(wf_impl_json_is_array(params));
ASSERT_EQ(2, wf_impl_json_array_size(params));
ASSERT_TRUE(wf_impl_json_is_string(wf_impl_json_array_get(params, 0)));
ASSERT_STREQ("bar", wf_impl_json_string_get(wf_impl_json_array_get(params, 0)));
ASSERT_TRUE(wf_impl_json_is_int(wf_impl_json_array_get(params, 1)));
ASSERT_EQ(42, wf_impl_json_int_get(wf_impl_json_array_get(params, 1)));
json_t * id = json_object_get(send_context.response, "id");
ASSERT_EQ(nullptr, id);
wf_json const * id = wf_impl_json_object_get(send_context.response, "id");
ASSERT_TRUE(wf_impl_json_is_undefined(id));
wf_impl_jsonrpc_proxy_dispose(proxy);
wf_impl_timer_manager_dispose(timer_manager);
}
TEST(wf_jsonrpc_proxy, notify_dont_send_invalid_request)
TEST(wf_jsonrpc_proxy, notify_send_invalid_request)
{
struct wf_timer_manager * timer_manager = wf_impl_timer_manager_create();
@ -378,7 +355,7 @@ TEST(wf_jsonrpc_proxy, notify_dont_send_invalid_request)
wf_impl_jsonrpc_proxy_notify(proxy, "foo", "?");
ASSERT_FALSE(send_context.is_called);
ASSERT_TRUE(send_context.is_called);
wf_impl_jsonrpc_proxy_dispose(proxy);
wf_impl_timer_manager_dispose(timer_manager);
@ -392,12 +369,8 @@ TEST(wf_jsonrpc_proxy, on_result_swallow_if_no_request_pending)
void * send_data = reinterpret_cast<void*>(&send_context);
struct wf_jsonrpc_proxy * proxy = wf_impl_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data);
json_t * response = json_object();
json_object_set_new(response, "result", json_string("okay"));
json_object_set_new(response, "id", json_integer(42));
wf_impl_jsonrpc_proxy_onresult(proxy, response);
json_decref(response);
JsonDoc response("{\"result\": \"okay\", \"id\": 42}");
wf_impl_jsonrpc_proxy_onresult(proxy, response.root());
wf_impl_jsonrpc_proxy_dispose(proxy);
wf_impl_timer_manager_dispose(timer_manager);

@ -1,23 +1,29 @@
#include <gtest/gtest.h>
#include "webfuse/impl/jsonrpc/request.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/message.h"
#include "webfuse/status.h"
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
namespace
{
struct Context
{
json_t * response;
std::string response;
};
bool jsonrpc_send(
json_t * request,
wf_message * request,
void * user_data)
{
Context * context = reinterpret_cast<Context*>(user_data);
context->response = request;
json_incref(request);
context->response = std::string(request->data, request->length);
wf_impl_message_dispose(request);
return true;
}
@ -25,7 +31,7 @@ bool jsonrpc_send(
TEST(wf_jsonrpc_request, create_dispose)
{
Context context{nullptr};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
struct wf_jsonrpc_request * request =
@ -39,36 +45,31 @@ TEST(wf_jsonrpc_request, create_dispose)
TEST(wf_jsonrpc_request, respond)
{
Context context{nullptr};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
struct wf_jsonrpc_request * request =
wf_impl_jsonrpc_request_create(42, &jsonrpc_send, user_data);
wf_impl_jsonrpc_respond(request, json_string("okay"));
wf_impl_jsonrpc_respond(request);
ASSERT_NE(nullptr, context.response);
json_t * response = reinterpret_cast<json_t*>(context.response);
ASSERT_TRUE(json_is_object(response));
JsonDoc doc(context.response);
struct wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
json_t * id = json_object_get(response, "id");
ASSERT_TRUE(json_is_integer(id));
ASSERT_EQ(42, json_integer_value(id));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_string(result));
ASSERT_STREQ("okay", json_string_value(result));
struct wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
ASSERT_EQ(42, wf_impl_json_int_get(id));
ASSERT_EQ(nullptr, json_object_get(response, "error"));
struct wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
json_decref(response);
ASSERT_TRUE(wf_impl_json_is_undefined(wf_impl_json_object_get(response, "error")));
}
TEST(wf_jsonrpc_request, respond_error)
{
Context context{nullptr};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
struct wf_jsonrpc_request * request =
@ -76,63 +77,24 @@ TEST(wf_jsonrpc_request, respond_error)
wf_impl_jsonrpc_respond_error(request, WF_BAD, "Bad");
ASSERT_NE(nullptr, context.response);
json_t * response = reinterpret_cast<json_t*>(context.response);
ASSERT_TRUE(json_is_object(response));
JsonDoc doc(context.response);
struct wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
json_t * id = json_object_get(response, "id");
ASSERT_TRUE(json_is_integer(id));
ASSERT_EQ(42, json_integer_value(id));
ASSERT_EQ(nullptr, json_object_get(response, "result"));
struct wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
ASSERT_EQ(42, wf_impl_json_int_get(id));
json_t * err = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(err));
ASSERT_TRUE(wf_impl_json_is_undefined(wf_impl_json_object_get(response, "result")));
json_t * err_code = json_object_get(err, "code");
ASSERT_TRUE(json_is_integer(err_code));
ASSERT_EQ(WF_BAD, json_integer_value(err_code));
json_t * err_message = json_object_get(err, "message");
ASSERT_TRUE(json_is_string(err_message));
ASSERT_STREQ("Bad", json_string_value(err_message));
json_decref(response);
}
TEST(wf_jsonrpc_request, is_request_object_params)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("some_method"));
json_object_set_new(request, "params", json_object());
json_object_set_new(request, "id", json_integer(42));
ASSERT_TRUE(wf_impl_jsonrpc_is_request(request));
json_decref(request);
}
TEST(wf_jsonrpc_request, is_request_fail_missing_params)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("some_method"));
json_object_set_new(request, "id", json_integer(42));
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
json_decref(request);
}
TEST(wf_jsonrpc_request, is_request_fail_params_wrong_type)
{
json_t * request = json_object();
json_object_set_new(request, "method", json_string("some_method"));
json_object_set_new(request, "params", json_string("invalid_params"));
json_object_set_new(request, "id", json_integer(42));
struct wf_json const * err = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(err));
ASSERT_FALSE(wf_impl_jsonrpc_is_request(request));
struct wf_json const * err_code = wf_impl_json_object_get(err, "code");
ASSERT_TRUE(wf_impl_json_is_int(err_code));
ASSERT_EQ(WF_BAD, wf_impl_json_int_get(err_code));
json_decref(request);
struct wf_json const * err_message = wf_impl_json_object_get(err, "message");
ASSERT_TRUE(wf_impl_json_is_string(err_message));
ASSERT_STREQ("Bad", wf_impl_json_string_get(err_message));
}

@ -1,147 +1,123 @@
#include <gtest/gtest.h>
#include "webfuse/impl/jsonrpc/response_intern.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/status.h"
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
TEST(wf_json_response, init_result)
{
json_t * message = json_object();
json_object_set_new(message, "result", json_integer(47));
json_object_set_new(message, "id", json_integer(11));
JsonDoc doc("{\"result\": 47, \"id\": 11}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(nullptr, response.error);
ASSERT_TRUE(json_is_integer(response.result));
ASSERT_EQ(47, json_integer_value(response.result));
ASSERT_TRUE(wf_impl_json_is_int(response.result));
ASSERT_EQ(47, wf_impl_json_int_get(response.result));
ASSERT_EQ(11, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}
TEST(wf_json_response, init_error)
{
json_t * message = json_object();
json_t * err = json_object();
json_object_set_new(err, "code", json_integer(42));
json_object_set_new(err, "message", json_string("Don't Panic!"));
json_object_set_new(message, "error", err);
json_object_set_new(message, "id", json_integer(23));
JsonDoc doc("{\"error\": {\"code\": 42, \"message\": \"Don't Panic!\"}, \"id\": 23}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(42, json_integer_value(json_object_get(response.error, "code")));
ASSERT_STREQ("Don't Panic!", json_string_value(json_object_get(response.error, "message")));
ASSERT_EQ(42, wf_impl_jsonrpc_error_code(response.error));
ASSERT_STREQ("Don't Panic!", wf_impl_jsonrpc_error_message(response.error));
ASSERT_EQ(nullptr, response.result);
ASSERT_EQ(23, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}
TEST(wf_json_response, init_fail_missing_result_and_error)
{
json_t * message = json_object();
json_object_set_new(message, "id", json_integer(12));
JsonDoc doc("{\"id\": 12}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(WF_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code")));
ASSERT_EQ(WF_BAD_FORMAT, wf_impl_jsonrpc_error_code(response.error));
ASSERT_EQ(nullptr, response.result);
ASSERT_EQ(12, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}
TEST(wf_json_response, init_fail_missing_id)
{
json_t * message = json_object();
json_object_set_new(message, "result", json_integer(47));
JsonDoc doc("{\"result\": 47}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(WF_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code")));
ASSERT_EQ(WF_BAD_FORMAT, wf_impl_jsonrpc_error_code(response.error));
ASSERT_EQ(nullptr, response.result);
ASSERT_EQ(-1, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}
TEST(wf_json_response, init_fail_wrong_id_type)
{
json_t * message = json_object();
json_object_set_new(message, "result", json_integer(47));
json_object_set_new(message, "id", json_string("42"));
JsonDoc doc("{\"result\": 47, \"id\": \"42\"}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(WF_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code")));
ASSERT_EQ(WF_BAD_FORMAT, wf_impl_jsonrpc_error_code(response.error));
ASSERT_EQ(nullptr, response.result);
ASSERT_EQ(-1, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}
TEST(wf_json_response, init_fail_error_missing_code)
{
json_t * message = json_object();
json_t * err = json_object();
json_object_set_new(err, "message", json_string("Don't Panic!"));
json_object_set_new(message, "error", err);
json_object_set_new(message, "id", json_integer(23));
JsonDoc doc("{\"error\": {\"message\": \"Don't Panic!\"}, \"id\": 23}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(WF_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code")));
ASSERT_EQ(WF_BAD_FORMAT, wf_impl_jsonrpc_error_code(response.error));
ASSERT_EQ(nullptr, response.result);
ASSERT_EQ(23, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}
TEST(wf_json_response, init_fail_error_wrong_code_type)
{
json_t * message = json_object();
json_t * err = json_object();
json_object_set_new(err, "code", json_string("42"));
json_object_set_new(err, "message", json_string("Don't Panic!"));
json_object_set_new(message, "error", err);
json_object_set_new(message, "id", json_integer(23));
JsonDoc doc("{\"error\": {\"code\": \"42\", \"message\": \"Don't Panic!\"}, \"id\": 23}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(WF_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code")));
ASSERT_EQ(WF_BAD_FORMAT, wf_impl_jsonrpc_error_code(response.error));
ASSERT_EQ(nullptr, response.result);
ASSERT_EQ(23, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}
TEST(wf_json_response, init_fail_error_wrong_type)
{
json_t * message = json_object();
json_object_set_new(message, "error", json_string("invalid error type"));
json_object_set_new(message, "id", json_integer(23));
JsonDoc doc("{\"error\": \"invalid error type\", \"id\": 23}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, message);
wf_impl_jsonrpc_response_init(&response, doc.root());
ASSERT_EQ(WF_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code")));
ASSERT_EQ(WF_BAD_FORMAT, wf_impl_jsonrpc_error_code(response.error));
ASSERT_EQ(nullptr, response.result);
ASSERT_EQ(23, response.id);
wf_impl_jsonrpc_response_cleanup(&response);
json_decref(message);
}

@ -1,56 +1,68 @@
#include <string>
#include <gtest/gtest.h>
#include "webfuse/impl/jsonrpc/response_intern.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
#include <string>
static void response_parse_str(
std::string const & buffer,
struct wf_jsonrpc_response * response)
{
json_t * message = json_loadb(buffer.c_str(), buffer.size(), 0, nullptr);
if (nullptr != message)
{
wf_impl_jsonrpc_response_init(response, message);
json_decref(message);
}
}
using webfuse_test::JsonDoc;
TEST(response_parser, test)
TEST(response_parser, invalid_no_object)
{
JsonDoc doc("[]");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, doc.root());
// no object
response_parse_str("[]", &response);
ASSERT_NE(nullptr, response.error);
ASSERT_EQ(-1, response.id);
ASSERT_EQ(nullptr, response.result);
wf_impl_jsonrpc_response_cleanup(&response);
}
TEST(response_parser, invalid_empty_object)
{
JsonDoc doc("{}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, doc.root());
// empty
response_parse_str("{}", &response);
ASSERT_NE(nullptr, response.error);
ASSERT_EQ(-1, response.id);
ASSERT_EQ(nullptr, response.result);
wf_impl_jsonrpc_response_cleanup(&response);
}
TEST(response_parser, invalid_missin_result_and_error)
{
JsonDoc doc("{\"id\":42}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, doc.root());
// no data
response_parse_str("{\"id\":42}", &response);
ASSERT_NE(nullptr, response.error);
ASSERT_EQ(42, response.id);
ASSERT_EQ(nullptr, response.result);
wf_impl_jsonrpc_response_cleanup(&response);
}
TEST(response_parser, custom_error_code)
{
JsonDoc doc("{\"error\":{\"code\": 42}, \"id\": 42}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, doc.root());
// custom error code
response_parse_str("{\"error\":{\"code\": 42}, \"id\": 42}", &response);
ASSERT_NE(nullptr, response.error);
ASSERT_EQ(42, json_integer_value(json_object_get(response.error, "code")));
ASSERT_EQ(42, wf_impl_jsonrpc_error_code(response.error));
ASSERT_EQ(42, response.id);
ASSERT_EQ(nullptr, response.result);
wf_impl_jsonrpc_response_cleanup(&response);
}
TEST(response_parser, valid_response)
{
JsonDoc doc("{\"result\": true, \"id\": 42}");
struct wf_jsonrpc_response response;
wf_impl_jsonrpc_response_init(&response, doc.root());
// valid response
response_parse_str("{\"result\": true, \"id\": 42}", &response);
ASSERT_EQ(nullptr, response.error);
ASSERT_EQ(42, response.id);
ASSERT_NE(nullptr, response.result);

@ -1,40 +1,56 @@
#include <gtest/gtest.h>
#include "webfuse/impl/jsonrpc/server.h"
#include "webfuse/impl/jsonrpc/request.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/impl/message.h"
#include "webfuse/status.h"
#include "webfuse/test_util/json_doc.hpp"
using webfuse_test::JsonDoc;
namespace
{
struct Context
class Context
{
json_t * response;
public:
Context()
: doc("{}")
, response(nullptr)
, is_called(false)
{
}
JsonDoc doc;
wf_json const * response;
bool is_called;
};
bool jsonrpc_send(
json_t * request,
wf_message * request,
void * user_data)
{
Context * context = reinterpret_cast<Context*>(user_data);
context->is_called = true;
context->response = request;
json_incref(request);
context->doc = std::move(JsonDoc(std::string(request->data, request->length)));
context->response = context->doc.root();
wf_impl_message_dispose(request);
return true;
}
void sayHello(
struct wf_jsonrpc_request * request,
char const * method_name,
json_t * params,
wf_json const * params,
void * user_data)
{
(void) method_name;
(void) params;
(void) user_data;
json_t * result = json_string("Hello");
wf_impl_jsonrpc_respond(request, result);
wf_impl_jsonrpc_respond(request);
}
}
@ -44,58 +60,47 @@ TEST(wf_jsonrpc_server, process_request)
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
wf_impl_jsonrpc_server_add(server, "sayHello", &sayHello, nullptr);
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_string("sayHello"));
json_object_set_new(request, "params", json_array());
json_object_set_new(request, "id", json_integer(23));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": \"sayHello\", \"params\": [], \"id\": 23}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_TRUE(context.is_called);
ASSERT_NE(nullptr, context.response);
ASSERT_TRUE(json_is_object(context.response));
ASSERT_TRUE(wf_impl_json_is_object(context.response));
json_t * id = json_object_get(context.response, "id");
ASSERT_TRUE(json_is_integer(id));
ASSERT_EQ(23, json_integer_value(id));
struct wf_json const * id = wf_impl_json_object_get(context.response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
ASSERT_EQ(23, wf_impl_json_int_get(id));
json_t * result = json_object_get(context.response, "result");
ASSERT_TRUE(json_is_string(result));
ASSERT_STREQ("Hello", json_string_value(result));
struct wf_json const * result = wf_impl_json_object_get(context.response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
json_decref(context.response);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
TEST(wf_jsonrpc_server, process_request_with_oject_params)
TEST(wf_jsonrpc_server, process_request_with_object_params)
{
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
wf_impl_jsonrpc_server_add(server, "sayHello", &sayHello, nullptr);
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_string("sayHello"));
json_object_set_new(request, "params", json_object());
json_object_set_new(request, "id", json_integer(23));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": \"sayHello\", \"params\": {}, \"id\": 23}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_TRUE(context.is_called);
ASSERT_NE(nullptr, context.response);
ASSERT_TRUE(json_is_object(context.response));
ASSERT_TRUE(wf_impl_json_is_object(context.response));
json_t * id = json_object_get(context.response, "id");
ASSERT_TRUE(json_is_integer(id));
ASSERT_EQ(23, json_integer_value(id));
struct wf_json const * id = wf_impl_json_object_get(context.response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
ASSERT_EQ(23, wf_impl_json_int_get(id));
json_t * result = json_object_get(context.response, "result");
ASSERT_TRUE(json_is_string(result));
ASSERT_STREQ("Hello", json_string_value(result));
struct wf_json const * result = wf_impl_json_object_get(context.response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
json_decref(context.response);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
@ -104,34 +109,29 @@ TEST(wf_jsonrpc_server, invoke_unknown_method)
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
wf_impl_jsonrpc_server_add(server, "sayHello", &sayHello, nullptr);
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_string("greet"));
json_object_set_new(request, "params", json_array());
json_object_set_new(request, "id", json_integer(42));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": \"greet\", \"params\": [], \"id\": 42}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_TRUE(context.is_called);
ASSERT_NE(nullptr, context.response);
ASSERT_TRUE(json_is_object(context.response));
ASSERT_TRUE(wf_impl_json_is_object(context.response));
json_t * id = json_object_get(context.response, "id");
ASSERT_TRUE(json_is_integer(id));
ASSERT_EQ(42, json_integer_value(id));
struct wf_json const * id = wf_impl_json_object_get(context.response, "id");
ASSERT_TRUE(wf_impl_json_is_int(id));
ASSERT_EQ(42, wf_impl_json_int_get(id));
json_t * err = json_object_get(context.response, "error");
ASSERT_TRUE(json_is_object(err));
struct wf_json const * err = wf_impl_json_object_get(context.response, "error");
ASSERT_TRUE(wf_impl_json_is_object(err));
json_t * err_code = json_object_get(err, "code");
ASSERT_TRUE(json_is_integer(err_code));
ASSERT_EQ(WF_BAD_NOTIMPLEMENTED, json_integer_value(err_code));
struct wf_json const * err_code = wf_impl_json_object_get(err, "code");
ASSERT_TRUE(wf_impl_json_is_int(err_code));
ASSERT_EQ(WF_BAD_NOTIMPLEMENTED, wf_impl_json_int_get(err_code));
json_t * err_message = json_object_get(err, "message");
ASSERT_TRUE(json_is_string(err_message));
struct wf_json const * err_message = wf_impl_json_object_get(err, "message");
ASSERT_TRUE(wf_impl_json_is_string(err_message));
json_decref(context.response);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
@ -139,16 +139,13 @@ TEST(wf_jsonrpc_server, skip_invalid_request_missing_id)
{
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_string("sayHello"));
json_object_set_new(request, "params", json_array());
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": \"sayHello\", \"params\": []}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_FALSE(context.is_called);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
@ -156,17 +153,13 @@ TEST(wf_jsonrpc_server, skip_invalid_request_wrong_id_type)
{
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_string("sayHello"));
json_object_set_new(request, "params", json_array());
json_object_set_new(request, "id", json_string("42"));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": \"sayHello\", \"params\": [], \"id\": \"42\"}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_FALSE(context.is_called);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
@ -174,16 +167,13 @@ TEST(wf_jsonrpc_server, skip_invalid_request_missing_params)
{
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_string("sayHello"));
json_object_set_new(request, "id", json_integer(42));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": \"sayHello\", \"id\": 23}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_FALSE(context.is_called);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
@ -191,17 +181,13 @@ TEST(wf_jsonrpc_server, skip_invalid_request_wrong_params_type)
{
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_string("sayHello"));
json_object_set_new(request, "params", json_string("invalid"));
json_object_set_new(request, "id", json_integer(42));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": \"sayHello\", \"params\": \"invalid\", \"id\": 42}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_FALSE(context.is_called);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
@ -209,16 +195,13 @@ TEST(wf_jsonrpc_server, skip_invalid_request_missing_method)
{
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "params", json_array());
json_object_set_new(request, "id", json_integer(42));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"params\": [], \"id\": 23}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_FALSE(context.is_called);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}
@ -226,16 +209,12 @@ TEST(wf_jsonrpc_server, skip_invalid_request_wront_method_type)
{
struct wf_jsonrpc_server * server = wf_impl_jsonrpc_server_create();
Context context{nullptr, false};
Context context;
void * user_data = reinterpret_cast<void*>(&context);
json_t * request = json_object();
json_object_set_new(request, "method", json_integer(42));
json_object_set_new(request, "params", json_array());
json_object_set_new(request, "id", json_integer(42));
wf_impl_jsonrpc_server_process(server, request, &jsonrpc_send, user_data);
JsonDoc request("{\"method\": 42, \"params\": [], \"id\": 23}");
wf_impl_jsonrpc_server_process(server, request.root(), &jsonrpc_send, user_data);
ASSERT_FALSE(context.is_called);
json_decref(request);
wf_impl_jsonrpc_server_dispose(server);
}

@ -1,31 +1,31 @@
#ifndef WF_GETATTR_MATCHER_HPP
#define WF_GETATTR_MATCHER_HPP
#include "webfuse/impl/json/node.h"
#include <gmock/gmock.h>
#include <jansson.h>
namespace webfuse_test
{
MATCHER_P(GetAttr, inode, "")
{
if (!json_is_array(arg))
if (!wf_impl_json_is_array(arg))
{
*result_listener << "json array expected";
return false;
}
json_t * inode_ = json_array_get(arg, 1);
if (!json_is_integer(inode_))
wf_json const * inode_ = wf_impl_json_array_get(arg, 1);
if (!wf_impl_json_is_int(inode_))
{
*result_listener << "inode is expectoed to an integer";
return false;
}
if (inode != json_integer_value(inode_))
if (inode != wf_impl_json_int_get(inode_))
{
*result_listener << "inode mismatch: expected" << inode
<< " but was " << json_integer_value(inode_);
<< " but was " << wf_impl_json_int_get(inode_);
return false;
}

@ -1,8 +1,8 @@
#ifndef WF_LOOKUP_MATCHER_HPP
#define WF_LOOKUP_MATCHER_HPP
#include "webfuse/impl/json/node.h"
#include <gmock/gmock.h>
#include <jansson.h>
#include <cstring>
namespace webfuse_test
@ -10,35 +10,35 @@ namespace webfuse_test
MATCHER_P2(Lookup, parent, name, "")
{
if (!json_is_array(arg))
if (!wf_impl_json_is_array(arg))
{
*result_listener << "json array expected";
return false;
}
json_t * parent_ = json_array_get(arg, 1);
if (!json_is_integer(parent_))
wf_json const * parent_ = wf_impl_json_array_get(arg, 1);
if (!wf_impl_json_is_int(parent_))
{
*result_listener << "parent is expected to be an integer";
return false;
}
if (parent != json_integer_value(parent_))
if (parent != wf_impl_json_int_get(parent_))
{
*result_listener << "parent mismatch: expected " << parent
<< " but was " << json_integer_value(parent_);
<< " but was " << wf_impl_json_int_get(parent_);
return false;
}
json_t * name_ = json_array_get(arg, 2);
if (!json_is_string(name_))
wf_json const * name_ = wf_impl_json_array_get(arg, 2);
if (!wf_impl_json_is_string(name_))
{
*result_listener << "name is expected to be a string";
return false;
}
if (0 != strcmp(name, json_string_value(name_)))
if (0 != strcmp(name, wf_impl_json_string_get(name_)))
{
*result_listener << "name mismatch: expected \"" << name
<< "\" but was \"" << json_string_value(name_) << "\"";
<< "\" but was \"" << wf_impl_json_string_get(name_) << "\"";
return false;
}

@ -10,7 +10,7 @@ namespace webfuse_test
class MockInvokationHander: public InvokationHandler
{
public:
MOCK_METHOD2(Invoke, std::string(char const * method, json_t * params));
MOCK_METHOD2(Invoke, std::string(char const * method, wf_json const * params));
};
}

@ -1,31 +1,31 @@
#ifndef WF_OPEN_MATCHER_HPP
#define WF_OPEN_MATCHER_HPP
#include "webfuse/impl/json/node.h"
#include <gmock/gmock.h>
#include <jansson.h>
namespace webfuse_test
{
MATCHER_P(Open, inode, "")
{
if (!json_is_array(arg))
if (!wf_impl_json_is_array(arg))
{
*result_listener << "json array expected";
return false;
}
json_t * inode_ = json_array_get(arg, 1);
if (!json_is_integer(inode_))
wf_json const * inode_ = wf_impl_json_array_get(arg, 1);
if (!wf_impl_json_is_int(inode_))
{
*result_listener << "inode is expectoed to an integer";
return false;
}
if (inode != json_integer_value(inode_))
if (inode != wf_impl_json_int_get(inode_))
{
*result_listener << "inode mismatch: expected" << inode
<< " but was " << json_integer_value(inode_);
<< " but was " << wf_impl_json_int_get(inode_);
return false;
}

@ -2,30 +2,30 @@
#define WF_READDIR_MATCHER_HPP
#include <gmock/gmock.h>
#include <jansson.h>
#include "webfuse/impl/json/node.h"
namespace webfuse_test
{
MATCHER_P(ReadDir, inode, "")
{
if (!json_is_array(arg))
if (!wf_impl_json_is_array(arg))
{
*result_listener << "json array expected";
return false;
}
json_t * inode_ = json_array_get(arg, 1);
if (!json_is_integer(inode_))
wf_json const * inode_ = wf_impl_json_array_get(arg, 1);
if (!wf_impl_json_is_int(inode_))
{
*result_listener << "inode is expectoed to an integer";
return false;
}
if (inode != json_integer_value(inode_))
if (inode != wf_impl_json_int_get(inode_))
{
*result_listener << "inode mismatch: expected" << inode
<< " but was " << json_integer_value(inode_);
<< " but was " << wf_impl_json_int_get(inode_);
return false;
}

@ -1,13 +1,16 @@
#include "webfuse/impl/operation/getattr.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/status.h"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/mocks/mock_fuse.hpp"
#include "webfuse/mocks/mock_operation_context.hpp"
#include "webfuse/mocks/mock_jsonrpc_proxy.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
using webfuse_test::MockJsonRpcProxy;
using webfuse_test::MockOperationContext;
using webfuse_test::FuseMock;
@ -79,16 +82,13 @@ TEST(wf_impl_operation_getattr, finished_file)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_attr(_,_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"mode\": 493, \"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_getattr_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_getattr, finished_dir)
@ -96,16 +96,13 @@ TEST(wf_impl_operation_getattr, finished_dir)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_attr(_,_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_string("dir"));
JsonDoc result("{\"mode\": 493, \"type\": \"dir\"}");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_getattr_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_getattr, finished_unknown_type)
@ -113,16 +110,13 @@ TEST(wf_impl_operation_getattr, finished_unknown_type)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_attr(_,_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_string("unknown"));
JsonDoc result("{\"mode\": 493, \"type\": \"unknown\"}");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_getattr_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_getattr, finished_fail_missing_mode)
@ -131,15 +125,13 @@ TEST(wf_impl_operation_getattr, finished_fail_missing_mode)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_getattr_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_getattr, finished_fail_invalid_mode_type)
@ -148,33 +140,28 @@ TEST(wf_impl_operation_getattr, finished_fail_invalid_mode_type)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "mode", json_string("0755"));
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"mode\": \"0755\", \"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_getattr_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_getattr, finished_fail_type_mode)
TEST(wf_impl_operation_getattr, finished_fail_missing_type)
{
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "mode", json_integer(0755));
JsonDoc result("{\"mode\": 493}");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_getattr_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_getattr, finished_fail_invalid_type_type)
@ -183,16 +170,13 @@ TEST(wf_impl_operation_getattr, finished_fail_invalid_type_type)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_integer(42));
JsonDoc result("{\"mode\": 493, \"type\": 42}");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_getattr_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_getattr, finished_error)
@ -201,13 +185,12 @@ TEST(wf_impl_operation_getattr, finished_error)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(WF_BAD));
wf_jsonrpc_error * error = wf_impl_jsonrpc_error(WF_BAD, "");
auto * context = reinterpret_cast<wf_impl_operation_getattr_context*>(malloc(sizeof(wf_impl_operation_getattr_context)));
context->inode = 1;
context->gid = 0;
context->uid = 0;
wf_impl_operation_getattr_finished(context, nullptr, error);
json_decref(error);
wf_impl_jsonrpc_error_dispose(error);
}

@ -1,13 +1,16 @@
#include "webfuse/impl/operation/lookup.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/status.h"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/mocks/mock_fuse.hpp"
#include "webfuse/mocks/mock_operation_context.hpp"
#include "webfuse/mocks/mock_jsonrpc_proxy.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
using webfuse_test::MockJsonRpcProxy;
using webfuse_test::MockOperationContext;
using webfuse_test::FuseMock;
@ -77,17 +80,12 @@ TEST(wf_impl_operation_lookup, finished_file)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_entry(_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_integer(42));
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"inode\": 42, \"mode\": 493, \"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_dir)
@ -95,17 +93,12 @@ TEST(wf_impl_operation_lookup, finished_dir)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_entry(_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_integer(42));
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_string("dir"));
JsonDoc result("{\"inode\": 42, \"mode\": 493, \"type\": \"dir\"}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_unknown_type)
@ -113,17 +106,12 @@ TEST(wf_impl_operation_lookup, finished_unknown_type)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_entry(_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_integer(42));
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_string("unknown"));
JsonDoc result("{\"inode\": 42, \"mode\": 493, \"type\": \"unknown\"}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_fail_missing_inode)
@ -132,16 +120,12 @@ TEST(wf_impl_operation_lookup, finished_fail_missing_inode)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"mode\": 493, \"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_fail_invalid_inode_type)
@ -150,17 +134,12 @@ TEST(wf_impl_operation_lookup, finished_fail_invalid_inode_type)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_string("42"));
json_object_set_new(result, "mode", json_string("0755"));
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"inode\": \"42\", \"mode\": 493, \"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_fail_missing_mode)
@ -169,16 +148,12 @@ TEST(wf_impl_operation_lookup, finished_fail_missing_mode)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_integer(42));
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"inode\": 42, \"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_fail_invalid_mode_type)
@ -187,35 +162,26 @@ TEST(wf_impl_operation_lookup, finished_fail_invalid_mode_type)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_integer(42));
json_object_set_new(result, "mode", json_string("0755"));
json_object_set_new(result, "type", json_string("file"));
JsonDoc result("{\"inode\": 42, \"mode\": \"0755\", \"type\": \"file\"}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_fail_type_mode)
TEST(wf_impl_operation_lookup, finished_fail_missing_type)
{
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_integer(42));
json_object_set_new(result, "mode", json_integer(0755));
JsonDoc result("{\"inode\": 42, \"mode\": 493}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_fail_invalid_type_type)
@ -224,17 +190,12 @@ TEST(wf_impl_operation_lookup, finished_fail_invalid_type_type)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "inode", json_integer(42));
json_object_set_new(result, "mode", json_integer(0755));
json_object_set_new(result, "type", json_integer(42));
JsonDoc result("{\"inode\": 42, \"mode\": 493, \"type\": 42}");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, result, nullptr);
json_decref(result);
wf_impl_operation_lookup_finished(context, result.root(), nullptr);
}
TEST(wf_impl_operation_lookup, finished_error)
@ -243,13 +204,12 @@ TEST(wf_impl_operation_lookup, finished_error)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(WF_BAD));
struct wf_jsonrpc_error * error = wf_impl_jsonrpc_error(WF_BAD, "");
auto * context = reinterpret_cast<wf_impl_operation_lookup_context*>(malloc(sizeof(wf_impl_operation_lookup_context)));
context->timeout = 1.0;
context->gid = 0;
context->uid = 0;
wf_impl_operation_lookup_finished(context, nullptr, error);
json_decref(error);
wf_impl_jsonrpc_error_dispose(error);
}

@ -1,13 +1,16 @@
#include "webfuse/impl/operation/open.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/status.h"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/mocks/mock_fuse.hpp"
#include "webfuse/mocks/mock_operation_context.hpp"
#include "webfuse/mocks/mock_jsonrpc_proxy.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
using webfuse_test::MockJsonRpcProxy;
using webfuse_test::MockOperationContext;
using webfuse_test::FuseMock;
@ -58,10 +61,8 @@ TEST(wf_impl_operation_open, finished)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "handle", json_integer(42));
wf_impl_operation_open_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"handle\": 42}");
wf_impl_operation_open_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_open, finished_fail_error)
@ -70,10 +71,9 @@ TEST(wf_impl_operation_open, finished_fail_error)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(WF_BAD));
struct wf_jsonrpc_error * error = wf_impl_jsonrpc_error(WF_BAD, "");
wf_impl_operation_open_finished(nullptr, nullptr, error);
json_decref(error);
wf_impl_jsonrpc_error_dispose(error);
}
TEST(wf_impl_operation_open, finished_fail_no_handle)
@ -82,9 +82,8 @@ TEST(wf_impl_operation_open, finished_fail_no_handle)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
wf_impl_operation_open_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{}");
wf_impl_operation_open_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_open, finished_fail_invalid_handle_type)
@ -93,8 +92,6 @@ TEST(wf_impl_operation_open, finished_fail_invalid_handle_type)
EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "handle", json_string("42"));
wf_impl_operation_open_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"handle\": \"42\"}");
wf_impl_operation_open_finished(nullptr, result.root(), nullptr);
}

@ -1,11 +1,14 @@
#include "webfuse/impl/operation/read.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/mocks/mock_fuse.hpp"
#include "webfuse/mocks/mock_operation_context.hpp"
#include "webfuse/mocks/mock_jsonrpc_proxy.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
using webfuse_test::MockJsonRpcProxy;
using webfuse_test::MockOperationContext;
using webfuse_test::FuseMock;
@ -81,53 +84,52 @@ TEST(wf_impl_operation_read, fail_rpc_null)
TEST(wf_impl_operation_read, fill_buffer_identity)
{
wf_status status;
char * buffer = wf_impl_fill_buffer("brummni", 8, "identity", 8, &status);
char text[] = "brummni";
char * buffer = wf_impl_operation_read_transform(text, 8, "identity", 8, &status);
ASSERT_EQ(WF_GOOD, status);
ASSERT_STREQ("brummni", buffer);
free(buffer);
}
TEST(wf_impl_operation_read, fill_buffer_identity_fail_inconsistent_size)
{
wf_status status;
char * buffer = wf_impl_fill_buffer("brummni", 8, "identity", 7, &status);
char text[] = "brummni";
wf_impl_operation_read_transform(text, 8, "identity", 7, &status);
ASSERT_NE(WF_GOOD, status);
ASSERT_EQ(nullptr, buffer);
}
TEST(wf_impl_operation_read, fill_buffer_base64)
{
wf_status status;
char * buffer = wf_impl_fill_buffer("YnJ1bW1uaQ==", 12, "base64", 7, &status);
char text[] = "YnJ1bW1uaQ==";
char * buffer = wf_impl_operation_read_transform(text, 12, "base64", 7, &status);
ASSERT_EQ(WF_GOOD, status);
ASSERT_EQ(0, strncmp("brummni", buffer, 7));
free(buffer);
}
TEST(wf_impl_operation_read, fill_buffer_base64_fail_invalid_data)
{
wf_status status;
char * buffer = wf_impl_fill_buffer("YnJ1bW1uaQ=A", 12, "base64", 8, &status);
char text[] = "YnJ1bW1uaQ=A";
wf_impl_operation_read_transform(text, 12, "base64", 8, &status);
ASSERT_NE(WF_GOOD, status);
ASSERT_EQ(nullptr, buffer);
}
TEST(wf_impl_operation_read, fill_buffer_empty)
{
wf_status status;
char * buffer = wf_impl_fill_buffer(nullptr, 0, "identity", 0, &status);
wf_impl_operation_read_transform(nullptr, 0, "identity", 0, &status);
ASSERT_EQ(WF_GOOD, status);
free(buffer);
}
TEST(wf_impl_operation_read, fill_buffer_fail_invalid_format)
{
wf_status status;
char * buffer = wf_impl_fill_buffer("some data", 9, "unknown", 9, &status);
char text[] = "some data";
wf_impl_operation_read_transform(text, 9, "unknown", 9, &status);
ASSERT_NE(WF_GOOD, status);
ASSERT_EQ(nullptr, buffer);
}
TEST(wf_impl_operation_read, finished)
@ -135,12 +137,8 @@ TEST(wf_impl_operation_read, finished)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_buf(_,_,7)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "data", json_string("brummni"));
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_integer(7));
wf_impl_operation_read_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"data\": \"brummni\", \"format\": \"identity\", \"count\": 7}");
wf_impl_operation_read_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_read, finished_fail_no_data)
@ -149,11 +147,8 @@ TEST(wf_impl_operation_read, finished_fail_no_data)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, _)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_integer(7));
wf_impl_operation_read_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"format\": \"identity\", \"count\": 7}");
wf_impl_operation_read_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_read, finished_fail_invalid_data_type)
@ -162,12 +157,8 @@ TEST(wf_impl_operation_read, finished_fail_invalid_data_type)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, _)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "data", json_integer(42));
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_integer(7));
wf_impl_operation_read_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"data\": 42, \"format\": \"identity\", \"count\": 7}");
wf_impl_operation_read_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_read, finished_fail_no_format)
@ -176,11 +167,8 @@ TEST(wf_impl_operation_read, finished_fail_no_format)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, _)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "data", json_string("brummni"));
json_object_set_new(result, "count", json_integer(7));
wf_impl_operation_read_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"data\": \"brummni\", \"count\": 7}");
wf_impl_operation_read_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_read, finished_fail_invalid_format_type)
@ -189,12 +177,8 @@ TEST(wf_impl_operation_read, finished_fail_invalid_format_type)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, _)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "data", json_string("brummni"));
json_object_set_new(result, "format", json_integer(42));
json_object_set_new(result, "count", json_integer(7));
wf_impl_operation_read_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"data\": \"brummni\", \"format\": 42, \"count\": 7}");
wf_impl_operation_read_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_read, finished_fail_no_count)
@ -203,11 +187,8 @@ TEST(wf_impl_operation_read, finished_fail_no_count)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, _)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "data", json_string("brummni"));
json_object_set_new(result, "format", json_string("identity"));
wf_impl_operation_read_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"data\": \"brummni\", \"format\": \"identity\"}");
wf_impl_operation_read_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_read, finished_fail_invalid_count_type)
@ -216,12 +197,8 @@ TEST(wf_impl_operation_read, finished_fail_invalid_count_type)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, _)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
json_object_set_new(result, "data", json_string("brummni"));
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_string("7"));
wf_impl_operation_read_finished(nullptr, result, nullptr);
json_decref(result);
JsonDoc result("{\"data\": \"brummni\", \"format\": \"identity\", \"count\": \"7\"}");
wf_impl_operation_read_finished(nullptr, result.root(), nullptr);
}
TEST(wf_impl_operation_read, finished_fail_error)
@ -230,8 +207,7 @@ TEST(wf_impl_operation_read, finished_fail_error)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, _)).Times(1).WillOnce(Return(0));
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(WF_BAD));
struct wf_jsonrpc_error * error = wf_impl_jsonrpc_error(WF_BAD, "");
wf_impl_operation_read_finished(nullptr, nullptr, error);
json_decref(error);
wf_impl_jsonrpc_error_dispose(error);
}

@ -1,13 +1,17 @@
#include "webfuse/impl/operation/readdir.h"
#include "webfuse/impl/jsonrpc/error.h"
#include "webfuse/status.h"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/mocks/mock_fuse.hpp"
#include "webfuse/mocks/mock_operation_context.hpp"
#include "webfuse/mocks/mock_jsonrpc_proxy.hpp"
#include <gtest/gtest.h>
#include <sstream>
using webfuse_test::JsonDoc;
using webfuse_test::MockJsonRpcProxy;
using webfuse_test::MockOperationContext;
using webfuse_test::FuseMock;
@ -80,18 +84,12 @@ TEST(wf_impl_operation_readdir, finished)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
json_t * item = json_object();
json_object_set_new(item, "name", json_string("a.file"));
json_object_set_new(item, "inode", json_integer(42));
json_array_append_new(result, item);
JsonDoc result("[{\"name\": \"a.file\", \"inode\": 42}]");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_many_items)
@ -99,22 +97,20 @@ TEST(wf_impl_operation_readdir, finished_many_items)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
for(int i = 0; i < 100; i++)
std::ostringstream stream;
stream << "[" << "{\"name\": \"file_0.txt\", \"inode\": 1}";
for(int i = 1; i < 100; i++)
{
json_t * item = json_object();
json_object_set_new(item, "name", json_sprintf("file_%d.txt", i));
json_object_set_new(item, "inode", json_integer(1 + i));
json_array_append_new(result, item);
stream << ",{\"name\": \"file_" << i << ".txt\", \"inode\": " << (i+1) << "}";
}
stream << "]";
JsonDoc result(stream.str());
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 100;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_read_after_end)
@ -122,18 +118,12 @@ TEST(wf_impl_operation_readdir, finished_read_after_end)
FuseMock fuse;
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
json_t * item = json_object();
json_object_set_new(item, "name", json_string("a.file"));
json_object_set_new(item, "inode", json_integer(42));
json_array_append_new(result, item);
JsonDoc result("[{\"name\": \"a.file\", \"inode\": 42}]");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 10;
context->offset = 2;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_fail_error)
@ -142,15 +132,14 @@ TEST(wf_impl_operation_readdir, finished_fail_error)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * error = json_array();
json_object_set_new(error, "code", json_integer(WF_BAD));
struct wf_jsonrpc_error * error = wf_impl_jsonrpc_error(WF_BAD, "");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), nullptr, error);
json_decref(error);
wf_impl_jsonrpc_error_dispose(error);
}
TEST(wf_impl_operation_readdir, finished_fail_invalid_result_type)
@ -159,14 +148,12 @@ TEST(wf_impl_operation_readdir, finished_fail_invalid_result_type)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_object();
JsonDoc result("{}");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_fail_missing_name)
@ -175,17 +162,12 @@ TEST(wf_impl_operation_readdir, finished_fail_missing_name)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
json_t * item = json_object();
json_object_set_new(item, "inode", json_integer(42));
json_array_append_new(result, item);
JsonDoc result("[{\"inode\": 42}]");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_fail_invalid_name_type)
@ -194,18 +176,12 @@ TEST(wf_impl_operation_readdir, finished_fail_invalid_name_type)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
json_t * item = json_object();
json_object_set_new(item, "name", json_integer(42));
json_object_set_new(item, "inode", json_integer(42));
json_array_append_new(result, item);
JsonDoc result("[{\"name\": 42, \"inode\": 42}]");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_fail_missing_inode)
@ -214,17 +190,12 @@ TEST(wf_impl_operation_readdir, finished_fail_missing_inode)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
json_t * item = json_object();
json_object_set_new(item, "name", json_string("a.file"));
json_array_append_new(result, item);
JsonDoc result("[{\"name\": \"a.file\"}]");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_fail_invalid_inode_type)
@ -233,18 +204,12 @@ TEST(wf_impl_operation_readdir, finished_fail_invalid_inode_type)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
json_t * item = json_object();
json_object_set_new(item, "name", json_string("a.file"));
json_object_set_new(item, "inode", json_string("42"));
json_array_append_new(result, item);
JsonDoc result("[{\"name\": \"a.file\", \"inode\": \"42\"}]");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}
TEST(wf_impl_operation_readdir, finished_fail_invalid_item_type)
@ -253,13 +218,10 @@ TEST(wf_impl_operation_readdir, finished_fail_invalid_item_type)
EXPECT_CALL(fuse, fuse_reply_buf(_,_,_)).Times(0);
EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0));
json_t * result = json_array();
json_array_append_new(result, json_string("item"));
JsonDoc result("[\"item\"]");
auto * context = reinterpret_cast<wf_impl_operation_readdir_context*>(malloc(sizeof(wf_impl_operation_readdir_context)));
context->request = nullptr;
context->size = 1;
context->offset = 0;
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result, nullptr);
json_decref(result);
wf_impl_operation_readdir_finished(reinterpret_cast<void*>(context), result.root(), nullptr);
}

@ -1,6 +1,3 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "webfuse/test_util/adapter_client.hpp"
#include "webfuse/client_tlsconfig.h"
#include "webfuse/credentials.h"
@ -13,8 +10,12 @@
#include "webfuse/mocks/open_matcher.hpp"
#include "webfuse/mocks/getattr_matcher.hpp"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <future>
#include <chrono>
#include <sstream>
using webfuse_test::AdapterClient;
using webfuse_test::WsServer;
@ -148,8 +149,7 @@ TEST(AdapterClient, IgnoreInvalidJsonMessage)
client.Connect();
ASSERT_EQ(std::future_status::ready, connected.get_future().wait_for(TIMEOUT));
json_t * invalid_request = json_object();
server.SendMessage(invalid_request);
server.SendMessage("{}");
client.Disconnect();
ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT));
@ -566,26 +566,21 @@ TEST(AdapterClient, ReadFile)
EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1)
.WillOnce(Return("{\"handle\": 42}"));
EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber())
.WillRepeatedly(Invoke([](char const *, json_t * params) {
int offset = json_integer_value(json_array_get(params, 3));
int length = json_integer_value(json_array_get(params, 4));
.WillRepeatedly(Invoke([](char const *, wf_json const * params) {
int offset = wf_impl_json_int_get(wf_impl_json_array_get(params, 3));
int length = wf_impl_json_int_get(wf_impl_json_array_get(params, 4));
int remaining = (offset < 4096) ? 4096 - offset : 0;
int count = (length < remaining) ? length : remaining;
std::string data = std::string(count, '*');
json_t * result = json_object();
json_object_set_new(result, "data", json_string(data.c_str()));
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_integer(count));
char * result_text = json_dumps(result, 0);
std::string result_str = result_text;
free(result_text);
json_decref(result);
std::ostringstream result;
result << "{"
<< "\"data\": \"" << std::string(count, '*') << "\","
<< "\"format\": \"identity\","
<< "\"count\": " << count
<< "}";
return result_str;
return result.str();
}));
EXPECT_CALL(handler, Invoke(StrEq("close"), _)).Times(AtMost(1));
@ -641,26 +636,21 @@ TEST(AdapterClient, ReadLargeFile)
EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1)
.WillOnce(Return("{\"handle\": 42}"));
EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber())
.WillRepeatedly(Invoke([](char const *, json_t * params) {
int offset = json_integer_value(json_array_get(params, 3));
int length = json_integer_value(json_array_get(params, 4));
.WillRepeatedly(Invoke([](char const *, wf_json const * params) {
int offset = wf_impl_json_int_get(wf_impl_json_array_get(params, 3));
int length = wf_impl_json_int_get(wf_impl_json_array_get(params, 4));
int remaining = (offset < 102400) ? 102400 - offset : 0;
int count = (length < remaining) ? length : remaining;
std::string data = std::string(count, '*');
json_t * result = json_object();
json_object_set_new(result, "data", json_string(data.c_str()));
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_integer(count));
char * result_text = json_dumps(result, 0);
std::string result_str = result_text;
free(result_text);
json_decref(result);
std::ostringstream result;
result << "{"
<< "\"data\": \"" << std::string(count, '*') << "\","
<< "\"format\": \"identity\","
<< "\"count\": " << count
<< "}";
return result_str;
return result.str();
}));
EXPECT_CALL(handler, Invoke(StrEq("close"), _)).Times(AtMost(1));

@ -1,8 +1,10 @@
#include <gtest/gtest.h>
#include "webfuse/credentials.h"
#include "webfuse/impl/credentials.h"
#include <jansson.h>
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
TEST(Credentials, Type)
{
@ -16,31 +18,27 @@ TEST(Credentials, Type)
TEST(Credentials, Get)
{
struct wf_credentials creds;
json_t * data = json_object();
json_object_set_new(data, "username", json_string("bob"));
json_object_set_new(data, "password", json_string("<secret>"));
JsonDoc doc("{\"username\": \"bob\", \"password\": \"<secret>\"}");
wf_impl_credentials_init(&creds, "username", data);
wf_impl_credentials_init(&creds, "username", doc.root());
ASSERT_STREQ("username", wf_credentials_type(&creds));
ASSERT_STREQ("bob", wf_credentials_get(&creds, "username"));
ASSERT_STREQ("<secret>", wf_credentials_get(&creds, "password"));
wf_impl_credentials_cleanup(&creds);
json_decref(data);
}
TEST(Credentials, FailedToGetNonexistingValue)
{
struct wf_credentials creds;
json_t * data = json_object();
JsonDoc doc("{}");
wf_impl_credentials_init(&creds, "username", data);
wf_impl_credentials_init(&creds, "username", doc.root());
ASSERT_STREQ("username", wf_credentials_type(&creds));
ASSERT_STREQ(nullptr, wf_credentials_get(&creds, "username"));
ASSERT_STREQ(nullptr, wf_credentials_get(&creds, "password"));
wf_impl_credentials_cleanup(&creds);
json_decref(data);
}
TEST(Credentials, FailedToGetWithoutData)
@ -58,30 +56,27 @@ TEST(Credentials, FailedToGetWithoutData)
TEST(Credentials, FailedToGetWrongDataType)
{
struct wf_credentials creds;
json_t * data = json_string("invalid_creds");
JsonDoc doc("invalid_creds");
wf_impl_credentials_init(&creds, "username", data);
wf_impl_credentials_init(&creds, "username", doc.root());
ASSERT_STREQ("username", wf_credentials_type(&creds));
ASSERT_STREQ(nullptr, wf_credentials_get(&creds, "username"));
ASSERT_STREQ(nullptr, wf_credentials_get(&creds, "password"));
wf_impl_credentials_cleanup(&creds);
json_decref(data);
}
TEST(Credentials, FailedToGetWrongElementDataType)
{
struct wf_credentials creds;
json_t * data = json_object();
json_object_set_new(data, "username", json_integer(42));
JsonDoc doc("{\"username\": 42}");
wf_impl_credentials_init(&creds, "username", data);
wf_impl_credentials_init(&creds, "username", doc.root());
ASSERT_STREQ("username", wf_credentials_type(&creds));
ASSERT_STREQ(nullptr, wf_credentials_get(&creds, "username"));
ASSERT_STREQ(nullptr, wf_credentials_get(&creds, "password"));
wf_impl_credentials_cleanup(&creds);
json_decref(data);
}
TEST(Credentials, SetType)

@ -1,22 +1,22 @@
#include <gtest/gtest.h>
#include <cstring>
#include "webfuse/impl/message.h"
#include <cstring>
#include <cstdlib>
#include <libwebsockets.h>
#include <gtest/gtest.h>
TEST(wf_message, create)
{
json_t * value = json_object();
char * data = (char*) malloc(LWS_PRE + 2);
data[LWS_PRE ] = '{';
data[LWS_PRE + 1] = '}';
struct wf_message * message = wf_impl_message_create(value);
struct wf_message * message = wf_impl_message_create(&(data[LWS_PRE]), 2);
ASSERT_NE(nullptr, message);
ASSERT_EQ(2, message->length);
ASSERT_TRUE(0 == strncmp("{}", message->data, 2));
wf_impl_message_dispose(message);
json_decref(value);
}
TEST(wf_message, fail_to_create)
{
struct wf_message * message = wf_impl_message_create(nullptr);
ASSERT_EQ(nullptr, message);
}

@ -1,18 +1,23 @@
#include <gtest/gtest.h>
#include "webfuse/impl/message_queue.h"
#include "webfuse/impl/message.h"
#include "webfuse/impl/util/slist.h"
#include <gtest/gtest.h>
#include <libwebsockets.h>
#include <cstring>
#include <cstdlib>
namespace
{
struct wf_slist_item * create_message(char const * content)
{
json_t * value = json_object();
json_object_set_new(value, "content", json_string(content));
struct wf_message * message = wf_impl_message_create(value);
std::string json = std::string("{\"content\": \"") + content + "\"}";
char * data = (char*) malloc(LWS_PRE + json.size());
memcpy(&(data[LWS_PRE]), json.c_str(), json.size());
struct wf_message * message = wf_impl_message_create(&(data[LWS_PRE]), json.size());
json_decref(value);
return &message->item;
}

@ -1,19 +1,20 @@
#include <gtest/gtest.h>
#include <jansson.h>
#include "webfuse/server.h"
#include "webfuse/server_config.h"
#include "webfuse/test_util/server.hpp"
#include "webfuse/test_util/ws_client.hpp"
#include "webfuse/test_util/file.hpp"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/mocks/mock_invokation_handler.hpp"
#include "webfuse/protocol_names.h"
#include "webfuse/mocks/open_matcher.hpp"
#include "webfuse/mocks/getattr_matcher.hpp"
#include "webfuse/mocks/lookup_matcher.hpp"
#include "webfuse/mocks/readdir_matcher.hpp"
#include "webfuse/impl/json/node.h"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
using webfuse_test::MockInvokationHander;
using webfuse_test::WsClient;
using webfuse_test::Server;
@ -85,13 +86,13 @@ TEST(server, add_filesystem)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
std::string base_dir = server.GetBaseDir();
ASSERT_TRUE(File(base_dir).isDirectory());
@ -112,13 +113,13 @@ TEST(server, add_filesystem_fail_missing_param)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -134,13 +135,13 @@ TEST(server, add_filesystem_fail_invalid_name_type)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [42], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -156,13 +157,13 @@ TEST(server, add_filesystem_fail_invalid_name)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"invalid_1/name\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -179,13 +180,13 @@ TEST(server, authenticate)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [\"username\", {\"username\": \"bob\", \"password\": \"secret\"}], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -201,13 +202,13 @@ TEST(server, authenticate_fail_missing_params)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -223,13 +224,13 @@ TEST(server, authenticate_fail_invalid_type)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [42, {\"username\": \"bob\", \"password\": \"secret\"}], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -245,13 +246,13 @@ TEST(server, authenticate_fail_invalid_credentials)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [\"username\", 42], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -267,13 +268,13 @@ TEST(server, authenticate_fail_missing_credentials)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [\"username\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
@ -299,13 +300,13 @@ TEST(server, read)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
std::string base_dir = server.GetBaseDir();
ASSERT_TRUE(File(base_dir).isDirectory());
@ -330,26 +331,21 @@ TEST(server, read_large_file_contents)
EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1)
.WillOnce(Return("{\"handle\": 42}"));
EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber())
.WillRepeatedly(Invoke([](char const *, json_t * params) {
int offset = json_integer_value(json_array_get(params, 3));
int length = json_integer_value(json_array_get(params, 4));
.WillRepeatedly(Invoke([](char const *, wf_json const * params) {
int offset = wf_impl_json_int_get(wf_impl_json_array_get(params, 3));
int length = wf_impl_json_int_get(wf_impl_json_array_get(params, 4));
int remaining = (offset < 4096) ? 4096 - offset : 0;
int count = (length < remaining) ? length : remaining;
std::string data = std::string(count, '*');
std::ostringstream result;
result << "{"
<< "\"data\": \"" << std::string(count, '*') << "\","
<< "\"format\": \"identity\","
<< "\"count\": " << count
<< "}";
json_t * result = json_object();
json_object_set_new(result, "data", json_string(data.c_str()));
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_integer(count));
char * result_text = json_dumps(result, 0);
std::string result_str = result_text;
free(result_text);
json_decref(result);
return result_str;
return result.str();
}));
EXPECT_CALL(handler, Invoke(StrEq("close"), _)).Times(AtMost(1));
WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT);
@ -358,13 +354,13 @@ TEST(server, read_large_file_contents)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
std::string base_dir = server.GetBaseDir();
ASSERT_TRUE(File(base_dir).isDirectory());
@ -390,26 +386,21 @@ TEST(server, read_large_file)
EXPECT_CALL(handler, Invoke(StrEq("open"), Open(2))).Times(1)
.WillOnce(Return("{\"handle\": 42}"));
EXPECT_CALL(handler, Invoke(StrEq("read"), _)).Times(AnyNumber())
.WillRepeatedly(Invoke([](char const *, json_t * params) {
int offset = json_integer_value(json_array_get(params, 3));
int length = json_integer_value(json_array_get(params, 4));
.WillRepeatedly(Invoke([](char const *, wf_json const * params) {
int offset = wf_impl_json_int_get(wf_impl_json_array_get(params, 3));
int length = wf_impl_json_int_get(wf_impl_json_array_get(params, 4));
int remaining = (offset < 1024000) ? 1024000 - offset : 0;
int count = (length < remaining) ? length : remaining;
std::string data = std::string(count, '*');
json_t * result = json_object();
json_object_set_new(result, "data", json_string(data.c_str()));
json_object_set_new(result, "format", json_string("identity"));
json_object_set_new(result, "count", json_integer(count));
char * result_text = json_dumps(result, 0);
std::string result_str = result_text;
free(result_text);
json_decref(result);
std::ostringstream result;
result << "{"
<< "\"data\": \"" << std::string(count, '*') << "\","
<< "\"format\": \"identity\","
<< "\"count\": " << count
<< "}";
return result_str;
return result.str();
}));
EXPECT_CALL(handler, Invoke(StrEq("close"), _)).Times(AtMost(1));
WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT);
@ -418,13 +409,13 @@ TEST(server, read_large_file)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
std::string base_dir = server.GetBaseDir();
ASSERT_TRUE(File(base_dir).isDirectory());
@ -450,13 +441,13 @@ TEST(server, readdir)
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
std::string base_dir = server.GetBaseDir();
ASSERT_TRUE(File(base_dir).isDirectory());

@ -1,6 +1,8 @@
#include "webfuse/test_util/server_protocol.hpp"
#include "webfuse/test_util/ws_client.hpp"
#include "webfuse/test_util/file.hpp"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/impl/json/node.h"
#include "webfuse/mocks/mock_invokation_handler.hpp"
#include "webfuse/mocks/getattr_matcher.hpp"
#include "webfuse/protocol_names.h"
@ -8,6 +10,7 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using webfuse_test::JsonDoc;
using webfuse_test::MockInvokationHander;
using webfuse_test::WsClient;
using webfuse_test::ServerProtocol;
@ -33,24 +36,24 @@ TEST(server_protocol, add_filesystem)
{
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [\"username\", {\"username\": \"bob\", \"password\": \"secret\"}], \"id\": 23}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(23, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(23, wf_impl_json_int_get(id));
}
{
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * result = wf_impl_json_object_get(response, "result");
ASSERT_TRUE(wf_impl_json_is_object(result));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
}
std::string base_dir = server.GetBaseDir();
@ -76,13 +79,13 @@ TEST(server_protocol, add_filesystem_fail_without_authentication)
{
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(42, wf_impl_json_int_get(id));
}
auto disconnected = client.Disconnect();
@ -103,13 +106,13 @@ TEST(server_protocol, authenticate_fail_wrong_credentials)
{
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [\"username\", {\"username\": \"alice\", \"password\": \"cheshire\"}], \"id\": 23}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(23, json_integer_value(id));
json_decref(response);
JsonDoc doc(response_text);
wf_json const * response = doc.root();
ASSERT_TRUE(wf_impl_json_is_object(response));
wf_json const * error = wf_impl_json_object_get(response, "error");
ASSERT_TRUE(wf_impl_json_is_object(error));
wf_json const * id = wf_impl_json_object_get(response, "id");
ASSERT_EQ(23, wf_impl_json_int_get(id));
}
auto disconnected = client.Disconnect();

@ -1,9 +1,10 @@
#ifndef WF_TEST_UTIL_INVOKATION_HANDLER_HPP
#define WF_TEST_UTIL_INVOKATION_HANDLER_HPP
#include <jansson.h>
#include <string>
struct wf_json;
namespace webfuse_test
{
@ -11,7 +12,7 @@ class InvokationHandler
{
public:
virtual ~InvokationHandler() = default;
virtual std::string Invoke(char const * method, json_t * params) = 0;
virtual std::string Invoke(char const * method, wf_json const * params) = 0;
};
}

@ -1,20 +0,0 @@
#include <gtest/gtest.h>
#include <jansson.h>
namespace webfuse_test
{
class JanssonTestEnvironment: public ::testing::Environment
{
public:
~JanssonTestEnvironment() override { }
void SetUp() override
{
json_object_seed(0);
}
};
::testing::Environment * const jansson_env = ::testing::AddGlobalTestEnvironment(new JanssonTestEnvironment());
}

@ -0,0 +1,45 @@
#include "webfuse/test_util/json_doc.hpp"
namespace webfuse_test
{
JsonDoc::JsonDoc(std::string const & text)
: contents(text)
{
doc = wf_impl_json_doc_loadb(const_cast<char*>(contents.data()), contents.size());
}
JsonDoc::JsonDoc(JsonDoc && other)
{
contents = std::move(other.contents);
doc = other.doc;
other.doc = nullptr;
}
JsonDoc& JsonDoc::operator=(JsonDoc && other)
{
if (this != &other)
{
wf_impl_json_doc_dispose(doc);
contents = std::move(other.contents);
doc = other.doc;
other.doc = nullptr;
}
return *this;
}
JsonDoc::~JsonDoc()
{
if (nullptr != doc)
{
wf_impl_json_doc_dispose(doc);
}
}
wf_json const * JsonDoc::root()
{
return wf_impl_json_doc_root(doc);
}
}

@ -0,0 +1,27 @@
#ifndef WF_TEST_UTIL_JSON_DOC_HPP
#define WF_TEST_UTIL_JSON_DOC_HPP
#include "webfuse/impl/json/doc.h"
#include <string>
namespace webfuse_test
{
class JsonDoc
{
JsonDoc(JsonDoc const&) = delete;
JsonDoc& operator=(JsonDoc const&) = delete;
public:
explicit JsonDoc(std::string const & text);
JsonDoc(JsonDoc && other);
JsonDoc& operator=(JsonDoc && other);
~JsonDoc();
wf_json const * root();
private:
std::string contents;
wf_json_doc * doc;
};
}
#endif

@ -1,9 +1,10 @@
#include "webfuse/test_util/ws_client.hpp"
#include "webfuse/test_util/invokation_handler.hpp"
#include "webfuse/test_util/json_doc.hpp"
#include "webfuse/impl/json/node.h"
#include "webfuse/status.h"
#include <libwebsockets.h>
#include <jansson.h>
#include <cstring>
#include <thread>
@ -11,6 +12,7 @@
#include <queue>
#include <condition_variable>
#include <chrono>
#include <sstream>
#define TIMEOUT (std::chrono::seconds(10))
@ -225,52 +227,33 @@ public:
{
lock.unlock();
json_t * request = json_loadb(data, length, 0, nullptr);
if (nullptr != request)
{
json_t * method = json_object_get(request, "method");
json_t * params = json_object_get(request, "params");
json_t * id = json_object_get(request, "id");
json_t * response = json_object();
try
{
std::string result_text = handler_.Invoke(json_string_value(method), params);
json_t * result = json_loads(result_text.c_str(), 0, nullptr);
if (nullptr != result)
{
json_object_set_new(response, "result", result);
}
else
{
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(WF_BAD));
json_object_set_new(response, "error",error);
}
}
catch (...)
{
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(WF_BAD));
json_object_set_new(response, "error",error);
}
json_object_set(response, "id", id);
JsonDoc doc(std::string(data, length));
wf_json const * request = doc.root();
wf_json const * method = wf_impl_json_object_get(request, "method");
wf_json const * params = wf_impl_json_object_get(request, "params");
wf_json const * id = wf_impl_json_object_get(request, "id");
char * response_text = json_dumps(response, 0);
lock.lock();
send_queue.push(response_text);
commands.push(command::send);
lock.unlock();
std::ostringstream response;
response << "{";
try
{
std::string result_text = handler_.Invoke(wf_impl_json_string_get(method), params);
if (result_text.empty()) { throw std::runtime_error("empty"); }
response << "\"result\": " << result_text;
}
catch (...)
{
response << "\"error\": {\"code\": 1}";
}
lws_cancel_service(context);
response << ", \"id\": " << wf_impl_json_int_get(id) << "}";
free(response_text);
lock.lock();
send_queue.push(response.str());
commands.push(command::send);
lock.unlock();
json_decref(response);
json_decref(request);
}
lws_cancel_service(context);
}
}

@ -1,6 +1,8 @@
#include "webfuse/test_util/ws_server.hpp"
#include "webfuse/test_util/invokation_handler.hpp"
#include "webfuse/impl/util/lws_log.h"
#include "webfuse/impl/json/node.h"
#include "webfuse/test_util/json_doc.hpp"
#include <libwebsockets.h>
#include <thread>
@ -9,6 +11,8 @@
#include <sstream>
#include <queue>
using webfuse_test::JsonDoc;
namespace
{
@ -85,7 +89,6 @@ public:
void OnWritable(struct lws * wsi) override;
void SendMessage(char const * message);
void SendMessage(json_t * message);
private:
static void Run(Private * self);
@ -127,12 +130,6 @@ void WsServer::SendMessage(char const * message)
d->SendMessage(message);
}
void WsServer::SendMessage(json_t * message)
{
d->SendMessage(message);
}
WsServer::Private::Private(
InvokationHandler & handler,
std::string const & protocol,
@ -264,45 +261,34 @@ void WsServer::Private::SendMessage(char const * message)
}
}
void WsServer::Private::SendMessage(json_t * message)
{
char* message_text = json_dumps(message, JSON_COMPACT);
SendMessage(message_text);
json_decref(message);
free(message_text);
}
void WsServer::Private::OnMessageReceived(struct lws * wsi, char const * data, size_t length)
{
(void) wsi;
json_t * request = json_loadb(data, length, JSON_DECODE_ANY, nullptr);
json_t * method = json_object_get(request, "method");
json_t * params = json_object_get(request, "params");
json_t * id = json_object_get(request, "id");
JsonDoc doc(std::string(data, length));
wf_json const * request = doc.root();
wf_json const * method = wf_impl_json_object_get(request, "method");
wf_json const * params = wf_impl_json_object_get(request, "params");
wf_json const * id = wf_impl_json_object_get(request, "id");
if (json_is_string(method) && json_is_array(params) && json_is_integer(id))
if (wf_impl_json_is_string(method) && wf_impl_json_is_array(params) && wf_impl_json_is_int(id))
{
json_t * response = json_object();
std::ostringstream response;
response << "{";
try
{
std::string result_text = handler_.Invoke(json_string_value(method), params);
json_t * result = json_loads(result_text.c_str(), JSON_DECODE_ANY, nullptr);
json_object_set_new(response, "result", result);
std::string result_text = handler_.Invoke(wf_impl_json_string_get(method), params);
response << "\"result\": " << result_text;
}
catch (...)
{
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(1));
json_object_set_new(response, "error", error);
response << "\"error\": {\"code\": 1}";
}
response << ", \"id\": " << wf_impl_json_int_get(id) << "}";
json_object_set(response, "id", id);
SendMessage(response);
SendMessage(response.str().c_str());
}
json_decref(request);
}
std::string const & WsServer::Private::GetUrl() const

@ -1,7 +1,6 @@
#ifndef WF_TEST_UTIL_WS_SERVER2_HPP
#define WF_TEST_UTIL_WS_SERVER2_HPP
#include <jansson.h>
#include <string>
namespace webfuse_test
@ -22,7 +21,6 @@ public:
virtual ~WsServer();
std::string const & GetUrl() const;
void SendMessage(char const * message);
void SendMessage(json_t * message);
private:
class Private;
Private * d;

@ -1,14 +1,15 @@
#include <gtest/gtest.h>
#include "webfuse/impl/util/json_util.h"
#include "webfuse/test_util/json_doc.hpp"
#include <gtest/gtest.h>
using webfuse_test::JsonDoc;
TEST(jsonrpc_util, get_int)
{
json_t * object = json_object();
json_object_set_new(object, "key", json_integer(23));
int value = wf_impl_json_get_int(object, "key", 42);
JsonDoc doc("{\"key\": 23}");
int value = wf_impl_json_get_int(doc.root(), "key", 42);
ASSERT_EQ(23, value);
json_decref(object);
}
TEST(jsonrpc_util, failed_to_get_null_object)
@ -20,28 +21,21 @@ TEST(jsonrpc_util, failed_to_get_null_object)
TEST(jsonrpc_util, failed_to_get_not_object)
{
json_t * object = json_array();
int value = wf_impl_json_get_int(nullptr, "key", 42);
JsonDoc doc("[]");
int value = wf_impl_json_get_int(doc.root(), "key", 42);
ASSERT_EQ(42, value);
json_decref(object);
}
TEST(jsonrpc_util, failed_to_get_invalid_key)
{
json_t * object = json_object();
int value = wf_impl_json_get_int(object, "key", 42);
JsonDoc doc("{}");
int value = wf_impl_json_get_int(doc.root(), "key", 42);
ASSERT_EQ(42, value);
json_decref(object);
}
TEST(jsonrpc_util, failed_to_get_invalid_value_type)
{
json_t * object = json_object();
json_object_set_new(object, "key", json_string("42"));
int value = wf_impl_json_get_int(object, "key", 42);
JsonDoc doc("{\"key\": \"42\"}");
int value = wf_impl_json_get_int(doc.root(), "key", 42);
ASSERT_EQ(42, value);
json_decref(object);
}
Loading…
Cancel
Save