Integrate method callback handling

This commit is contained in:
Aaron Cook 2026-05-20 09:46:23 -05:00
commit 64db0526ad

View file

@ -12,7 +12,6 @@
#include "json_rpc.h"
static void _service_request(json_rpc_t *jrpc);
static void _generic_error_response(json_rpc_t *jrpc, json_rpc_request_t *req);
static size_t _read_bytes(int fd, void *buf, size_t sz, int timeout_ms);
static size_t _read_until(int fd, void *buf, size_t sz, char c, int timeout_ms);
@ -186,8 +185,28 @@ _service_request(json_rpc_t *jrpc)
}
{
cJSON *response = cJSON_CreateObject();
cJSON *val = NULL;
cJSON *body = NULL;
const char *resp_token = "error";
json_rpc_method_t *method = NULL;
if (response == NULL) {
cJSON_Delete(request.request);
return;
}
if (cJSON_IsNumber(request.id)) {
val = cJSON_AddNumberToObject(response, "id", request.id->valuedouble);
} else {
val = cJSON_AddStringToObject(response, "id", request.id->valuestring);
}
if (val == NULL) {
cJSON_Delete(response);
cJSON_Delete(request.request);
return;
}
for (size_t i = 0; i < jrpc->method_cnt; i++) {
if (!strcmp(jrpc->methods[i].method, request.method->valuestring)) {
method = &jrpc->methods[i];
@ -197,75 +216,64 @@ _service_request(json_rpc_t *jrpc)
if (!method) {
log_warn("No handler for method \"%s\"\r\n", request.method->valuestring);
_generic_error_response(jrpc, &request);
} else {
/* TODO */
}
}
} else if (method->callback(&request, &body, method->arg) == 0) {
resp_token = "response";
if (body == NULL) {
log_error("No response body given for successful callback\r\n");
cJSON_Delete(response);
cJSON_Delete(request.request);
}
static void
_generic_error_response(json_rpc_t *jrpc, json_rpc_request_t *req)
{
cJSON *resp = cJSON_CreateObject();
cJSON *err_obj;
cJSON *val;
if (!resp) {
return;
}
}
if (cJSON_IsNumber(req->id)) {
val = cJSON_AddNumberToObject(resp, "id", req->id->valuedouble);
if (body) {
cJSON_AddItemToObject(response, resp_token, body);
} else {
val = cJSON_AddStringToObject(resp, "id", req->id->valuestring);
}
if (!val) {
cJSON_Delete(resp);
/* Generic method not found error */
body = cJSON_CreateObject();
if (body == NULL) {
cJSON_Delete(response);
cJSON_Delete(request.request);
return;
}
err_obj = cJSON_AddObjectToObject(resp, "error");
if (!err_obj) {
cJSON_Delete(resp);
if ((cJSON_AddNumberToObject(body, "code", -32601) == NULL) ||
(cJSON_AddStringToObject(body, "message", "Not implemented.") == NULL)) {
cJSON_Delete(body);
cJSON_Delete(response);
cJSON_Delete(request.request);
return;
}
val = cJSON_AddNumberToObject(err_obj, "code", -32803);
if (!val) {
cJSON_Delete(resp);
return;
}
val = cJSON_AddStringToObject(err_obj, "message", "Not implemented");
if (!val) {
cJSON_Delete(resp);
return;
cJSON_AddItemToObject(response, resp_token, body);
}
{
char *resp_str = cJSON_PrintUnformatted(resp);
char *resp_str = cJSON_PrintUnformatted(response);
size_t resp_str_len;
if (!resp_str) {
cJSON_Delete(resp);
if (resp_str == NULL) {
cJSON_Delete(response);
cJSON_Delete(request.request);
return;
}
resp_str_len = strlen(resp_str);
dprintf(jrpc->outfd, "Content-Length: %ld\r\n", resp_str_len);
write(jrpc->outfd, resp_str, resp_str_len);
dprintf(jrpc->outfd, "Content-Length: %ld\r\n\r\n", resp_str_len);
write(jrpc->outfd, resp_str, strlen(resp_str));
free(resp_str);
resp_str = cJSON_Print(resp);
if (resp_str) {
resp_str = cJSON_Print(response);
log_info(">> %s\r\n", resp_str);
free(resp_str);
}
cJSON_Delete(body);
cJSON_Delete(response);
}
cJSON_Delete(resp);
cJSON_Delete(request.request);
}