Prehandler works! It needs to send an error response if itâs denying the request, else the client hangs. I donât have access to client information from the prehandler, but there you can see the channel, method, and args.
Example that letâs you call the âsumâ method from websocket, but not the âsum2â method.
static bool my_rpc_prehandler (struct mg_rpc_request_info *ri, void *cb_arg,
struct mg_rpc_frame_info *fi, struct mg_str args) {
LOG(LL_INFO, ("prehandler hit: %.*s via %s, args %.*s",
(int) ri->method.len,
ri->method.p,
fi->channel_type,
(int) args.len,
args.p
));
if (mg_vcmp(&ri->method, "sum2") == 0 && strcmp(fi->channel_type, "WS_in") == 0) {
LOG (LL_WARN, ("no, you can't call %.*s from %s", (int) ri->method.len, ri->method.p, fi->channel_type));
mg_rpc_send_errorf(ri, -1, "no, you can't call %.*s from %s", (int) ri->method.len, ri->method.p, fi->channel_type);
return false;
}
return true;
}
void rpc_filter_setup() {
struct mg_rpc * global_rpc = mgos_rpc_get_global();
mg_rpc_set_prehandler (global_rpc, my_rpc_prehandler, NULL);
}
static void sum_rpc(struct mg_rpc_request_info *ri, void *cb_arg,
struct mg_rpc_frame_info *fi, struct mg_str args) {
double a = 0, b = 0;
if (json_scanf(args.p, args.len, ri->args_fmt, &a, &b) == 2) {
mg_rpc_send_responsef(ri, "%.2lf", a + b);
} else {
mg_rpc_send_errorf(ri, -1, "Bad request. Expected: {\"a\":N1,\"b\":N2}");
}
(void) cb_arg;
(void) fi;
}
// and somewhere
mg_rpc_add_handler(mgos_rpc_get_global(), "sum", "{a: %lf, b: %lf}", sum_rpc, NULL);
mg_rpc_add_handler(mgos_rpc_get_global(), "sum2", "{a: %lf, b: %lf}", sum_rpc, NULL);
Client usage looks like this:
$ mos --port ws://sti_B4E62DD60069.attlocal.net/rpc call sum '{"a":1, "b": 2}'
3.00
$ mos --port ws://sti_B4E62DD60069.attlocal.net/rpc call sum2 '{"a":1, "b": 2}'
Error: /build/mos-i_6ltm/mos-2.13.1+2034cc0~bionic0/obj-x86_64-linux-gnu/src/cesanta.com/mos/dev/dev_conn_impl.go:156: remote error -1: no, you can't call sum2 from WS_in
/build/mos-i_6ltm/mos-2.13.1+2034cc0~bionic0/obj-x86_64-linux-gnu/src/cesanta.com/mos/dev/dev_conn_impl.go:165:
/build/mos-i_6ltm/mos-2.13.1+2034cc0~bionic0/obj-x86_64-linux-gnu/src/cesanta.com/mos/main.go:178: call failed
$ # can work via http though
$ curl -d '{"a":1, "b": 2}' http://sti_B4E62DD60069.attlocal.net/rpc/sum
3.00
$ curl -d '{"a":1, "b": 2}' http://sti_B4E62DD60069.attlocal.net/rpc/sum2
3.00
and the device log:
[Jun 5 16:24:28.261] mgos_http_server.c:176 0x3ffeb14c HTTP connection from 192.168.1.212:55782
[Jun 5 16:24:28.276] rpc_filter.c:19 prehandler hit: sum via WS_in, args {"a":1,"b":2}
[Jun 5 16:24:28.282] mg_rpc.c:293 sum via WS_in 192.168.1.212:55782
[Jun 5 16:24:34.771] mgos_http_server.c:176 0x3ffeb14c HTTP connection from 192.168.1.212:55784
[Jun 5 16:24:34.786] rpc_filter.c:19 prehandler hit: sum2 via WS_in, args {"a":1,"b":2}
[Jun 5 16:24:34.793] rpc_filter.c:23 no, you can't call sum2 from WS_in
[Jun 5 16:33:47.625] mgos_http_server.c:176 0x3ffeb14c HTTP connection from 192.168.1.212:55886
[Jun 5 16:33:47.634] rpc_filter.c:19 prehandler hit: sum via HTTP, args {"a":1, "b": 2}
[Jun 5 16:33:47.641] mg_rpc.c:293 sum via HTTP 192.168.1.212:55886
[Jun 5 16:33:49.746] mgos_http_server.c:176 0x3ffeb14c HTTP connection from 192.168.1.212:55888
[Jun 5 16:33:49.755] rpc_filter.c:19 prehandler hit: sum2 via HTTP, args {"a":1, "b": 2}
[Jun 5 16:33:49.762] mg_rpc.c:293 sum2 via HTTP 192.168.1.212:55888