mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-13 17:00:19 +00:00
Let RPC handle responses too
This commit is contained in:
1 parent
f474a31484
commit
b73022096d
4 files changed
+63
-20
No files matched your search
@@ -2979,6 +2979,10 @@ Parameters:
|
|||||||
- `handler` - the RPC function performing the action for this method
|
- `handler` - the RPC function performing the action for this method
|
||||||
- `handler_data` - Arbitrary function data
|
- `handler_data` - Arbitrary function data
|
||||||
|
|
||||||
|
<span class="badge bg-info">NOTE:</span>
|
||||||
|
if `method_pattern` is an empty string, this handler will be called to process
|
||||||
|
JSON-RPC responses. Handling responses might be necessary if the JSON requests
|
||||||
|
are initiated by both sides.
|
||||||
|
|
||||||
Usage example:
|
Usage example:
|
||||||
|
|
||||||
|
|||||||
+17
-10
@@ -3550,20 +3550,27 @@ void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mg_rpc_call(struct mg_rpc_req *r, struct mg_str method) {
|
||||||
|
struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
|
||||||
|
while (h != NULL && !mg_match(method, h->method, NULL)) h = h->next;
|
||||||
|
if (h != NULL) {
|
||||||
|
r->rpc = h;
|
||||||
|
h->fn(r);
|
||||||
|
} else {
|
||||||
|
mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) method.len, method.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mg_rpc_process(struct mg_rpc_req *r) {
|
void mg_rpc_process(struct mg_rpc_req *r) {
|
||||||
int len, off = mg_json_get(r->frame, "$.method", &len);
|
int len, off = mg_json_get(r->frame, "$.method", &len);
|
||||||
if (off > 0 && r->frame.ptr[off] == '"') {
|
if (off > 0 && r->frame.ptr[off] == '"') {
|
||||||
struct mg_str m = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2);
|
struct mg_str method = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2);
|
||||||
struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
|
mg_rpc_call(r, method);
|
||||||
while (h != NULL && !mg_match(m, h->method, NULL)) h = h->next;
|
} else if ((off = mg_json_get(r->frame, "$.result", &len)) > 0 ||
|
||||||
if (h != NULL) {
|
(off = mg_json_get(r->frame, "$.error", &len)) > 0) {
|
||||||
r->rpc = h;
|
mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler
|
||||||
h->fn(r);
|
|
||||||
} else {
|
|
||||||
mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) m.len, m.ptr);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mg_rpc_err(r, -32700, "%.*Q", (int) r->frame.len, r->frame.ptr);
|
mg_rpc_err(r, -32700, "%.*Q", (int) r->frame.len, r->frame.ptr); // Invalid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,20 +20,27 @@ void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mg_rpc_call(struct mg_rpc_req *r, struct mg_str method) {
|
||||||
|
struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
|
||||||
|
while (h != NULL && !mg_match(method, h->method, NULL)) h = h->next;
|
||||||
|
if (h != NULL) {
|
||||||
|
r->rpc = h;
|
||||||
|
h->fn(r);
|
||||||
|
} else {
|
||||||
|
mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) method.len, method.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mg_rpc_process(struct mg_rpc_req *r) {
|
void mg_rpc_process(struct mg_rpc_req *r) {
|
||||||
int len, off = mg_json_get(r->frame, "$.method", &len);
|
int len, off = mg_json_get(r->frame, "$.method", &len);
|
||||||
if (off > 0 && r->frame.ptr[off] == '"') {
|
if (off > 0 && r->frame.ptr[off] == '"') {
|
||||||
struct mg_str m = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2);
|
struct mg_str method = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2);
|
||||||
struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
|
mg_rpc_call(r, method);
|
||||||
while (h != NULL && !mg_match(m, h->method, NULL)) h = h->next;
|
} else if ((off = mg_json_get(r->frame, "$.result", &len)) > 0 ||
|
||||||
if (h != NULL) {
|
(off = mg_json_get(r->frame, "$.error", &len)) > 0) {
|
||||||
r->rpc = h;
|
mg_rpc_call(r, mg_str("")); // JSON response! call "" method handler
|
||||||
h->fn(r);
|
|
||||||
} else {
|
|
||||||
mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) m.len, m.ptr);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mg_rpc_err(r, -32700, "%.*Q", (int) r->frame.len, r->frame.ptr);
|
mg_rpc_err(r, -32700, "%.*Q", (int) r->frame.len, r->frame.ptr); // Invalid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2493,6 +2493,11 @@ static void test_json(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void resp_rpc(struct mg_rpc_req *r) {
|
||||||
|
int len = 0, off = mg_json_get(r->frame, "$.result", &len);
|
||||||
|
mg_xprintf(r->pfn, r->pfn_data, "%.*s", len, &r->frame.ptr[off]);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_rpc(void) {
|
static void test_rpc(void) {
|
||||||
struct mg_rpc *head = NULL;
|
struct mg_rpc *head = NULL;
|
||||||
struct mg_iobuf io = {0, 0, 0, 256};
|
struct mg_iobuf io = {0, 0, 0, 256};
|
||||||
@@ -2541,10 +2546,30 @@ static void test_rpc(void) {
|
|||||||
const char *resp = "{\"error\":{\"code\":-32700,\"message\":\"haha\"}}";
|
const char *resp = "{\"error\":{\"code\":-32700,\"message\":\"haha\"}}";
|
||||||
req.frame = mg_str("haha");
|
req.frame = mg_str("haha");
|
||||||
mg_rpc_process(&req);
|
mg_rpc_process(&req);
|
||||||
|
// MG_INFO(("-> %s", io.buf));
|
||||||
ASSERT(strcmp((char *) io.buf, resp) == 0);
|
ASSERT(strcmp((char *) io.buf, resp) == 0);
|
||||||
mg_iobuf_free(&io);
|
mg_iobuf_free(&io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *resp =
|
||||||
|
"{\"id\":1,\"error\":{\"code\":-32601,\"message\":\" not found\"}}";
|
||||||
|
req.frame = mg_str("{\"id\":1,\"result\":123}");
|
||||||
|
mg_rpc_process(&req);
|
||||||
|
// MG_INFO(("-> %s", io.buf));
|
||||||
|
ASSERT(strcmp((char *) io.buf, resp) == 0);
|
||||||
|
mg_iobuf_free(&io);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
req.frame = mg_str("{\"id\":1,\"result\":123}");
|
||||||
|
mg_rpc_add(&head, mg_str(""), resp_rpc, NULL);
|
||||||
|
mg_rpc_process(&req);
|
||||||
|
MG_INFO(("-> %s", io.buf));
|
||||||
|
ASSERT(strcmp((char *) io.buf, "123") == 0);
|
||||||
|
mg_iobuf_free(&io);
|
||||||
|
}
|
||||||
|
|
||||||
mg_rpc_del(&head, NULL);
|
mg_rpc_del(&head, NULL);
|
||||||
ASSERT(head == NULL);
|
ASSERT(head == NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user