2022-11-16 20:36:24 -05:00
|
|
|
#include "ssb.rpc.h"
|
|
|
|
|
|
|
|
#include "mem.h"
|
|
|
|
#include "ssb.h"
|
|
|
|
#include "ssb.db.h"
|
|
|
|
#include "util.js.h"
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
static void _tf_ssb_rpc_gossip_ping(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
|
|
|
{
|
|
|
|
char buffer[256];
|
|
|
|
snprintf(buffer, sizeof(buffer), "%" PRId64, (int64_t)time(NULL));
|
|
|
|
tf_ssb_connection_rpc_send(
|
|
|
|
connection,
|
|
|
|
flags,
|
|
|
|
-request_number,
|
|
|
|
(const uint8_t*)buffer,
|
|
|
|
strlen(buffer),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _tf_ssb_rpc_blobs_get(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
|
|
|
{
|
|
|
|
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
|
|
|
|
JSContext* context = tf_ssb_connection_get_context(connection);
|
|
|
|
JSValue ids = JS_GetPropertyStr(context, args, "args");
|
|
|
|
int length = tf_util_get_length(context, ids);
|
|
|
|
bool success = false;
|
|
|
|
for (int i = 0; i < length; i++)
|
|
|
|
{
|
|
|
|
JSValue arg = JS_GetPropertyUint32(context, ids, i);
|
|
|
|
if (!JS_IsString(arg)) {
|
|
|
|
JSValue key = JS_GetPropertyStr(context, arg, "key");
|
|
|
|
JS_FreeValue(context, arg);
|
|
|
|
arg = key;
|
|
|
|
}
|
|
|
|
const char* id = JS_ToCString(context, arg);
|
|
|
|
uint8_t* blob = NULL;
|
|
|
|
size_t size = 0;
|
|
|
|
const int k_send_max = 8192;
|
|
|
|
if (tf_ssb_db_blob_get(ssb, id, &blob, &size))
|
|
|
|
{
|
|
|
|
for (size_t offset = 0; offset < size; offset += k_send_max)
|
|
|
|
{
|
|
|
|
tf_ssb_connection_rpc_send(
|
|
|
|
connection,
|
|
|
|
k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream,
|
|
|
|
-request_number,
|
|
|
|
blob + offset,
|
|
|
|
offset + k_send_max <= size ? k_send_max : (size - offset),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
success = true;
|
|
|
|
tf_free(blob);
|
|
|
|
}
|
|
|
|
JS_FreeCString(context, id);
|
|
|
|
JS_FreeValue(context, arg);
|
|
|
|
}
|
|
|
|
JS_FreeValue(context, ids);
|
|
|
|
tf_ssb_connection_rpc_send(
|
|
|
|
connection,
|
|
|
|
k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error,
|
|
|
|
-request_number,
|
|
|
|
(const uint8_t*)(success ? "true" : "false"),
|
|
|
|
strlen(success ? "true" : "false"),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
2022-11-16 20:49:34 -05:00
|
|
|
static void _tf_ssb_rpc_blobs_has(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
|
|
|
{
|
|
|
|
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
|
|
|
|
JSContext* context = tf_ssb_connection_get_context(connection);
|
|
|
|
JSValue ids = JS_GetPropertyStr(context, args, "args");
|
|
|
|
JSValue id = JS_GetPropertyUint32(context, ids, 0);
|
|
|
|
const char* id_str = JS_ToCString(context, id);
|
|
|
|
bool has = tf_ssb_db_blob_has(ssb, id_str);
|
|
|
|
JS_FreeCString(context, id_str);
|
|
|
|
JS_FreeValue(context, id);
|
|
|
|
JS_FreeValue(context, ids);
|
|
|
|
tf_ssb_connection_rpc_send(
|
|
|
|
connection,
|
|
|
|
k_ssb_rpc_flag_json | k_ssb_rpc_flag_end_error,
|
|
|
|
-request_number,
|
|
|
|
(const uint8_t*)(has ? "true" : "false"),
|
|
|
|
strlen(has ? "true" : "false"),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
2022-11-16 20:36:24 -05:00
|
|
|
void tf_ssb_rpc_register(tf_ssb_t* ssb)
|
|
|
|
{
|
|
|
|
tf_ssb_add_rpc_callback(ssb, (const char*[]) { "gossip", "ping", NULL }, _tf_ssb_rpc_gossip_ping, NULL, NULL);
|
|
|
|
tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "get", NULL }, _tf_ssb_rpc_blobs_get, NULL, NULL);
|
2022-11-16 20:49:34 -05:00
|
|
|
tf_ssb_add_rpc_callback(ssb, (const char*[]) { "blobs", "has", NULL }, _tf_ssb_rpc_blobs_has, NULL, NULL);
|
2022-11-16 20:36:24 -05:00
|
|
|
}
|