summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2020-09-14 17:15:23 +0200
committerRafał Miłecki <rafal@milecki.pl>2020-09-15 13:22:48 +0200
commit11723570af9cb7bd87842e79c85ee99530be9902 (patch)
tree32b8f70cea60a84f1b010787894a5f75e035e0b5 /main.c
parentfe1888f19e7f8ee4237409b8616c82926190c2f8 (diff)
ubus: add new RESTful API
Initial uhttpd ubus API was fully based on JSON-RPC. That restricted it from supporting ubus notifications that don't fit its model. Notifications require protocol that allows server to send data without being polled. There are two candidates for that: 1. Server-sent events 2. WebSocket The later one is overcomplex for this simple task so ideally uhttps ubus should support text-based server-sent events. It's not possible with JSON-RPC without violating it. Specification requires server to reply with Response object. Replying with text/event-stream is not allowed. All above led to designing new API that: 1. Uses GET and POST requests 2. Makes use of RESTful URLs 3. Uses JSON-RPC in cleaner form and only for calling ubus methods This new API allows: 1. Listing all ubus objects and their methods using GET <prefix>/list 2. Listing object methods using GET <prefix>/list/<path> 3. Listening to object notifications with GET <prefix>/subscribe/<path> 4. Calling ubus methods using POST <prefix>/call/<path> JSON-RPC custom protocol was also simplified to: 1. Use "method" member for ubus object method name It was possible thanks to using RESTful URLs. Previously "method" had to be "list" or "call". 2. Reply with Error object on ubus method call error This simplified "result" member format as it doesn't need to contain ubus result code anymore. This patch doesn't break or change the old API. The biggest downside of the new API is no support for batch requests. It's cost of using RESTful URLs. It should not matter much as uhttpd supports keep alive. Example usages: 1. Getting all objects and their methods: $ curl http://192.168.1.1/ubus/list { "dhcp": { "ipv4leases": { }, "ipv6leases": { } }, "log": { "read": { "lines": "number", "stream": "boolean", "oneshot": "boolean" }, "write": { "event": "string" } } } 2. Getting object methods: $ curl http://192.168.1.1/ubus/list/log { "read": { "lines": "number", "stream": "boolean", "oneshot": "boolean" }, "write": { "event": "string" } } 3. Subscribing to notifications: $ curl http://192.168.1.1/ubus/subscribe/foo event: status data: {"count":5} 4. Calling ubus object method: $ curl -d '{ "jsonrpc": "2.0", "id": 1, "method": "login", "params": {"username": "root", "password": "password" } }' http://192.168.1.1/ubus/call/session { "jsonrpc": "2.0", "id": 1, "result": { "ubus_rpc_session": "01234567890123456789012345678901", (...) } } $ curl -H 'Authorization: Bearer 01234567890123456789012345678901' -d '{ "jsonrpc": "2.0", "id": 1, "method": "write", "params": {"event": "Hello world" } }' http://192.168.1.1/ubus/call/log { "jsonrpc": "2.0", "id": 1, "result": null } Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Diffstat (limited to 'main.c')
-rw-r--r--main.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/main.c b/main.c
index 26e74ec..73e3d42 100644
--- a/main.c
+++ b/main.c
@@ -159,6 +159,7 @@ static int usage(const char *name)
" -U file Override ubus socket path\n"
" -a Do not authenticate JSON-RPC requests against UBUS session api\n"
" -X Enable CORS HTTP headers on JSON-RPC api\n"
+ " -e Events subscription reconnection time (retry value)\n"
#endif
" -x string URL prefix for CGI handler, default is '/cgi-bin'\n"
" -y alias[=path] URL alias handle\n"
@@ -262,7 +263,7 @@ int main(int argc, char **argv)
init_defaults_pre();
signal(SIGPIPE, SIG_IGN);
- while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:fh:H:I:i:K:k:L:l:m:N:n:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
+ while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:e:fh:H:I:i:K:k:L:l:m:N:n:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
switch(ch) {
#ifdef HAVE_TLS
case 'C':
@@ -490,11 +491,16 @@ int main(int argc, char **argv)
case 'X':
conf.ubus_cors = 1;
break;
+
+ case 'e':
+ conf.events_retry = atoi(optarg);
+ break;
#else
case 'a':
case 'u':
case 'U':
case 'X':
+ case 'e':
fprintf(stderr, "uhttpd: UBUS support not compiled, "
"ignoring -%c\n", ch);
break;