Fix some errors I've seen responding to blobs.get. Especially: handle sending large blobs.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3715 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2021-12-28 21:48:03 +00:00
parent 0f7472fa22
commit 5e205ac897
2 changed files with 74 additions and 3 deletions

View File

@ -168,10 +168,25 @@ ssb.addRpc(['blobs', 'has'], function(request) {
});
ssb.addRpc(['blobs', 'get'], function(request) {
for (let id of request.args) {
var blob = ssb.blobGet(id);
request.send_binary(blob);
for (let arg of request.args) {
var blob;
if (arg.key) {
blob = ssb.blobGet(arg.key);
} else {
blob = ssb.blobGet(arg);
}
const k_send_max = 8192;
if (blob.byteLength > k_send_max) {
for (var i = 0; i < blob.byteLength; i += k_send_max) {
var buffer = new Uint8Array(blob, i, Math.min(blob.byteLength - i, k_send_max));
request.send_binary(buffer);
}
} else {
request.send_binary(blob);
}
request.send_json_end(true);
}
request.more(function(request) {});
});
ssb.addRpc(['gossip', 'ping'], function(request) {

View File

@ -375,6 +375,38 @@ static JSValue _tf_ssb_rpc_send_json(JSContext* context, JSValueConst this_val,
return JS_UNDEFINED;
}
static JSValue _tf_ssb_rpc_send_json_end(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
JSValue connection_val = JS_GetPropertyStr(context, this_val, "connection");
tf_ssb_connection_t* connection = JS_GetOpaque(connection_val, tf_ssb_get_connection_class_id());
JSValue request_val = JS_GetPropertyStr(context, this_val, "request_number");
int32_t request_number;
JS_ToInt32(context, &request_number, request_val);
JS_FreeValue(context, request_val);
JSValue flags_val = JS_GetPropertyStr(context, this_val, "flags");
int32_t flags_number;
JS_ToInt32(context, &flags_number, flags_val);
JS_FreeValue(context, flags_val);
JSValue message_val = JS_JSONStringify(context, argv[0], JS_NULL, JS_NULL);
size_t size;
const char* message = JS_ToCStringLen(context, &size, message_val);
tf_ssb_connection_rpc_send(
connection,
k_ssb_rpc_flag_json | (flags_number & ~k_ssb_rpc_mask_type) | k_ssb_rpc_flag_end_error,
-request_number,
(const uint8_t*)message,
size,
NULL,
NULL);
JS_FreeValue(context, connection_val);
JS_FreeCString(context, message);
JS_FreeValue(context, message_val);
return JS_UNDEFINED;
}
static JSValue _tf_ssb_rpc_more(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
JSValue connection_val = JS_GetPropertyStr(context, this_val, "connection");
@ -412,6 +444,29 @@ static JSValue _tf_ssb_rpc_send_binary(JSContext* context, JSValueConst this_val
NULL,
NULL);
}
else
{
size_t offset;
size_t element_size;
JSValue buffer = tf_util_try_get_typed_array_buffer(context, argv[0], &offset, &size, &element_size);
if (!JS_IsException(buffer))
{
size_t total_size;
message = tf_util_try_get_array_buffer(context, &total_size, buffer);
if (message)
{
tf_ssb_connection_rpc_send(
connection,
k_ssb_rpc_flag_binary | k_ssb_rpc_flag_stream,
-request_number,
(const uint8_t*)message + offset,
size,
NULL,
NULL);
}
}
JS_FreeValue(context, buffer);
}
JS_FreeValue(context, connection_val);
return JS_UNDEFINED;
}
@ -430,6 +485,7 @@ void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t requ
JS_SetPropertyStr(context, object, "message", message && size ? JS_NewArrayBufferCopy(context, message, size) : args);
JS_SetPropertyStr(context, object, "send_json", JS_NewCFunction(context, _tf_ssb_rpc_send_json, "send_json", 1));
JS_SetPropertyStr(context, object, "send_binary", JS_NewCFunction(context, _tf_ssb_rpc_send_binary, "send_binary", 1));
JS_SetPropertyStr(context, object, "send_json_end", JS_NewCFunction(context, _tf_ssb_rpc_send_json_end, "send_json_end", 1));
JS_SetPropertyStr(context, object, "more", JS_NewCFunction(context, _tf_ssb_rpc_more, "more", 1));
JSValue result = JS_Call(context, callback, JS_UNDEFINED, 1, &object);