aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-03-27 11:23:51 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2017-03-27 11:23:51 +0200
commit44f21bd2a3b50f92669223cdafe79993654c1e19 (patch)
treeb8656cf9c11f25183bd95822c085ce35a459a9e5
parentfeccdb76f572a5fad947475c21b5b9aff696b04b (diff)
Simplify functions for calls
For historical reasons, the call to apis was passing the length of the api and the length of the verb. The reason was to avoid a copy of strings. But the copy occured only for HTTP requests. Having this implementation is of small interest and compromise future changes. This patch simplify things. Change-Id: I8157724c6c721b6797cd0eab52b07e1b8d6eb5f8 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/afb-api-dbus.c16
-rw-r--r--src/afb-api-so.c6
-rw-r--r--src/afb-api-ws.c12
-rw-r--r--src/afb-apis.c38
-rw-r--r--src/afb-apis.h5
-rw-r--r--src/afb-hook.c46
-rw-r--r--src/afb-hook.h2
-rw-r--r--src/afb-hreq.c16
-rw-r--r--src/afb-hreq.h4
-rw-r--r--src/afb-hswitch.c4
-rw-r--r--src/afb-subcall.c2
-rw-r--r--src/afb-svc.c22
-rw-r--r--src/afb-ws-json1.c2
13 files changed, 108 insertions, 67 deletions
diff --git a/src/afb-api-dbus.c b/src/afb-api-dbus.c
index 4a5a4f1f..179f8954 100644
--- a/src/afb-api-dbus.c
+++ b/src/afb-api-dbus.c
@@ -317,11 +317,11 @@ static int api_dbus_client_on_reply(sd_bus_message *message, void *userdata, sd_
}
/* on call, propagate it to the dbus service */
-static void api_dbus_client_call(struct api_dbus *api, struct afb_req req, struct afb_context *context, const char *verb, size_t lenverb)
+static void api_dbus_client_call(void *closure, struct afb_req req, struct afb_context *context, const char *verb)
{
+ struct api_dbus *api = closure;
size_t size;
int rc;
- char *method = strndupa(verb, lenverb);
struct dbus_memo *memo;
struct sd_bus_message *msg;
@@ -334,7 +334,7 @@ static void api_dbus_client_call(struct api_dbus *api, struct afb_req req, struc
/* creates the message */
msg = NULL;
- rc = sd_bus_message_new_method_call(api->sdbus, &msg, api->name, api->path, api->name, method);
+ rc = sd_bus_message_new_method_call(api->sdbus, &msg, api->name, api->path, api->name, verb);
if (rc < 0)
goto error;
@@ -363,8 +363,10 @@ end:
sd_bus_message_unref(msg);
}
-static int api_dbus_service_start(struct api_dbus *api, int share_session, int onneed)
+static int api_dbus_service_start(void *closure, int share_session, int onneed)
{
+ struct api_dbus *api = closure;
+
/* not an error when onneed */
if (onneed != 0)
return 0;
@@ -618,8 +620,8 @@ int afb_api_dbus_add_client(const char *path)
/* record it as an API */
afb_api.closure = api;
- afb_api.call = (void*)api_dbus_client_call;
- afb_api.service_start = (void*)api_dbus_service_start;
+ afb_api.call = api_dbus_client_call;
+ afb_api.service_start = api_dbus_service_start;
if (afb_apis_add(api->api, afb_api) < 0)
goto error2;
@@ -1003,7 +1005,7 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd
dreq->refcount = 1;
areq.itf = &afb_api_dbus_req_itf;
areq.closure = dreq;
- afb_apis_call_(areq, &dreq->context, api->api, method);
+ afb_apis_call(areq, &dreq->context, api->api, method);
dbus_req_unref(dreq);
return 1;
diff --git a/src/afb-api-so.c b/src/afb-api-so.c
index 222fbbbd..daa35334 100644
--- a/src/afb-api-so.c
+++ b/src/afb-api-so.c
@@ -182,16 +182,16 @@ static int call_check(struct afb_req req, struct afb_context *context, const str
return 1;
}
-static void call_cb(void *closure, struct afb_req req, struct afb_context *context, const char *strverb, size_t lenverb)
+static void call_cb(void *closure, struct afb_req req, struct afb_context *context, const char *strverb)
{
const struct afb_verb_desc_v1 *verb;
struct api_so_desc *desc = closure;
verb = desc->binding->v1.verbs;
- while (verb->name && (strncasecmp(verb->name, strverb, lenverb) || verb->name[lenverb]))
+ while (verb->name && strcasecmp(verb->name, strverb))
verb++;
if (!verb->name)
- afb_req_fail_f(req, "unknown-verb", "verb %.*s unknown within api %s", (int)lenverb, strverb, desc->binding->v1.prefix);
+ afb_req_fail_f(req, "unknown-verb", "verb %s unknown within api %s", strverb, desc->binding->v1.prefix);
else if (call_check(req, context, verb)) {
afb_thread_req_call(req, verb->callback, api_timeout, desc);
}
diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c
index a56cfbef..89b83bc5 100644
--- a/src/afb-api-ws.c
+++ b/src/afb-api-ws.c
@@ -431,12 +431,6 @@ static int api_ws_write_uint32(struct writebuf *wb, uint32_t value)
return 1;
}
-static int api_ws_write_string_nz(struct writebuf *wb, const char *value, size_t length)
-{
- uint32_t len = (uint32_t)length;
- return (size_t)len == length && ++len && api_ws_write_uint32(wb, len) && api_ws_write_put(wb, value, length) && api_ws_write_char(wb, '\0');
-}
-
static int api_ws_write_string_length(struct writebuf *wb, const char *value, size_t length)
{
uint32_t len = (uint32_t)++length;
@@ -815,7 +809,7 @@ static void api_ws_client_on_binary(void *closure, char *data, size_t size)
}
/* on call, propagate it to the ws service */
-static void api_ws_client_call_cb(void * closure, struct afb_req req, struct afb_context *context, const char *verb, size_t lenverb)
+static void api_ws_client_call_cb(void * closure, struct afb_req req, struct afb_context *context, const char *verb)
{
int rc;
struct api_ws_memo *memo;
@@ -837,7 +831,7 @@ static void api_ws_client_call_cb(void * closure, struct afb_req req, struct afb
goto internal_error;
if (!api_ws_write_uint32(&wb, memo->msgid)
|| !api_ws_write_uint32(&wb, (uint32_t)context->flags)
- || !api_ws_write_string_nz(&wb, verb, lenverb)
+ || !api_ws_write_string(&wb, verb)
|| !api_ws_write_string(&wb, afb_session_uuid(context->session))
|| !api_ws_write_string_length(&wb, raw, szraw))
goto overflow;
@@ -988,7 +982,7 @@ static void api_ws_server_called(struct api_ws_client *client, struct readbuf *r
/* makes the call */
areq.itf = &afb_api_ws_req_itf;
areq.closure = wreq;
- afb_apis_call_(areq, &wreq->context, client->api, verb);
+ afb_apis_call(areq, &wreq->context, client->api, verb);
api_ws_server_req_unref(wreq);
return;
diff --git a/src/afb-apis.c b/src/afb-apis.c
index 7db3e75a..3463f535 100644
--- a/src/afb-apis.c
+++ b/src/afb-apis.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <errno.h>
#include "afb-session.h"
#include "verbose.h"
@@ -32,24 +33,32 @@
struct api_desc {
struct afb_api api;
const char *name;
- size_t namelen;
};
static struct api_desc *apis_array = NULL;
static int apis_count = 0;
+/**
+ * Returns the current count of APIs
+ */
int afb_apis_count()
{
return apis_count;
}
+/**
+ * Checks wether 'name' is a valid API name.
+ * @return 1 if valid, 0 otherwise
+ */
int afb_apis_is_valid_api_name(const char *name)
{
unsigned char c;
c = (unsigned char)*name;
if (c == 0)
+ /* empty names aren't valid */
return 0;
+
do {
if (c < (unsigned char)'\x80') {
switch(c) {
@@ -74,6 +83,16 @@ int afb_apis_is_valid_api_name(const char *name)
return 1;
}
+/**
+ * Adds the api of 'name' described by 'api'.
+ * @param name the name of the api to add
+ * @param api the api
+ * @returns 0 in case of success or -1 in case
+ * of error with errno set:
+ * - EINVAL if name isn't valid
+ * - EEXIST if name already registered
+ * - ENOMEM when out of memory
+ */
int afb_apis_add(const char *name, struct afb_api api)
{
struct api_desc *apis;
@@ -82,6 +101,7 @@ int afb_apis_add(const char *name, struct afb_api api)
/* Checks the api name */
if (!afb_apis_is_valid_api_name(name)) {
ERROR("invalid api name forbidden (name is '%s')", name);
+ errno = EINVAL;
goto error;
}
@@ -89,6 +109,7 @@ int afb_apis_add(const char *name, struct afb_api api)
for (i = 0 ; i < apis_count ; i++) {
if (!strcasecmp(apis_array[i].name, name)) {
ERROR("api of name %s already exists", name);
+ errno = EEXIST;
goto error;
}
}
@@ -97,6 +118,7 @@ int afb_apis_add(const char *name, struct afb_api api)
apis = realloc(apis_array, ((unsigned)apis_count + 1) * sizeof * apis);
if (apis == NULL) {
ERROR("out of memory");
+ errno = ENOMEM;
goto error;
}
apis_array = apis;
@@ -104,7 +126,6 @@ int afb_apis_add(const char *name, struct afb_api api)
/* record the plugin */
apis = &apis_array[apis_count];
apis->api = api;
- apis->namelen = strlen(name);
apis->name = name;
apis_count++;
@@ -114,22 +135,17 @@ error:
return -1;
}
-void afb_apis_call_(struct afb_req req, struct afb_context *context, const char *api, const char *verb)
-{
- afb_apis_call(req, context, api, strlen(api), verb, strlen(verb));
-}
-
-void afb_apis_call(struct afb_req req, struct afb_context *context, const char *api, size_t lenapi, const char *verb, size_t lenverb)
+void afb_apis_call(struct afb_req req, struct afb_context *context, const char *api, const char *verb)
{
int i;
const struct api_desc *a;
- req = afb_hook_req_call(req, context, api, lenapi, verb, lenverb);
+ req = afb_hook_req_call(req, context, api, verb);
a = apis_array;
for (i = 0 ; i < apis_count ; i++, a++) {
- if (a->namelen == lenapi && !strncasecmp(a->name, api, lenapi)) {
+ if (!strcasecmp(a->name, api)) {
context->api_index = i;
- a->api.call(a->api.closure, req, context, verb, lenverb);
+ a->api.call(a->api.closure, req, context, verb);
return;
}
}
diff --git a/src/afb-apis.h b/src/afb-apis.h
index 1dd9566b..3e90f661 100644
--- a/src/afb-apis.h
+++ b/src/afb-apis.h
@@ -23,7 +23,7 @@ struct afb_context;
struct afb_api
{
void *closure;
- void (*call)(void *closure, struct afb_req req, struct afb_context *context, const char *verb, size_t lenverb);
+ void (*call)(void *closure, struct afb_req req, struct afb_context *context, const char *verb);
int (*service_start)(void *closure, int share_session, int onneed);
};
@@ -36,7 +36,6 @@ extern int afb_apis_add(const char *name, struct afb_api api);
extern int afb_apis_start_all_services(int share_session);
extern int afb_apis_start_service(const char *name, int share_session, int onneed);
-extern void afb_apis_call(struct afb_req req, struct afb_context *context, const char *api, size_t lenapi, const char *verb, size_t lenverb);
-extern void afb_apis_call_(struct afb_req req, struct afb_context *context, const char *api, const char *verb);
+extern void afb_apis_call(struct afb_req req, struct afb_context *context, const char *api, const char *verb);
diff --git a/src/afb-hook.c b/src/afb-hook.c
index d5c534d0..f59192a7 100644
--- a/src/afb-hook.c
+++ b/src/afb-hook.c
@@ -272,25 +272,33 @@ static void hook_req_unref(struct afb_hook_req *tr)
}
}
-static struct afb_hook_req *hook_req_create(struct afb_req req, struct afb_context *context, const char *api, size_t lenapi, const char *verb, size_t lenverb)
+static struct afb_hook_req *hook_req_create(struct afb_req req, struct afb_context *context, const char *api, const char *verb)
{
+ int len;
+ char name[257];
unsigned id;
struct afb_hook_req *tr;
- tr = malloc(sizeof *tr + 8 + lenapi + lenverb);
- if (tr != NULL) {
- /* get the call id */
- id = ++hook_count;
- if (id == 1000000)
- id = hook_count = 1;
-
- /* init hook */
- tr->observers = NULL;
- tr->refcount = 1;
- tr->context = context;
- tr->req = req;
- afb_req_addref(req);
- snprintf(tr->name, 9 + lenapi + lenverb, "%06d:%.*s/%.*s", id, (int)lenapi, api, (int)lenverb, verb);
+ /* get the call id */
+ id = ++hook_count;
+ if (id == 1000000)
+ id = hook_count = 1;
+
+ /* creates the name */
+ len = snprintf(name, sizeof name, "%06d:%s/%s", id, api, verb);
+ if (len < 0 || (size_t)len >= sizeof name) {
+ tr = NULL;
+ } else {
+ tr = malloc(sizeof *tr + (size_t)len);
+ if (tr != NULL) {
+ /* init hook */
+ tr->observers = NULL;
+ tr->refcount = 1;
+ tr->context = context;
+ tr->req = req;
+ afb_req_addref(req);
+ memcpy(tr->name, name, (size_t)(len + 1));
+ }
}
return tr;
}
@@ -494,7 +502,7 @@ static struct afb_req_itf req_hook_itf = {
* section:
*****************************************************************************/
-struct afb_req afb_hook_req_call(struct afb_req req, struct afb_context *context, const char *api, size_t lenapi, const char *verb, size_t lenverb)
+struct afb_req afb_hook_req_call(struct afb_req req, struct afb_context *context, const char *api, const char *verb)
{
int add;
struct afb_hook_req *tr;
@@ -506,11 +514,11 @@ struct afb_req afb_hook_req_call(struct afb_req req, struct afb_context *context
do {
add = (hook->flags & afb_hook_flags_req_all) != 0
&& (!hook->session || hook->session == context->session)
- && (!hook->api || !(memcmp(hook->api, api, lenapi) || hook->api[lenapi]))
- && (!hook->verb || !(memcmp(hook->verb, verb, lenverb) || hook->verb[lenverb]));
+ && (!hook->api || !strcasecmp(hook->api, api))
+ && (!hook->verb || !strcasecmp(hook->verb, verb));
if (add) {
if (!tr)
- tr = hook_req_create(req, context, api, lenapi, verb, lenverb);
+ tr = hook_req_create(req, context, api, verb);
if (tr)
hook_req_add_observer(tr, hook);
}
diff --git a/src/afb-hook.h b/src/afb-hook.h
index 2ad01b85..3edf8102 100644
--- a/src/afb-hook.h
+++ b/src/afb-hook.h
@@ -88,7 +88,7 @@ struct afb_hook_req_itf {
void (*hook_req_subcall_result)(void * closure, const struct afb_hook_req *tr, int status, struct json_object *result);
};
-extern struct afb_req afb_hook_req_call(struct afb_req req, struct afb_context *context, const char *api, size_t lenapi, const char *verb, size_t lenverb);
+extern struct afb_req afb_hook_req_call(struct afb_req req, struct afb_context *context, const char *api, const char *verb);
extern struct afb_hook *afb_hook_req_create(const char *api, const char *verb, struct afb_session *session, unsigned flags, struct afb_hook_req_itf *itf, void *closure);
extern struct afb_hook *afb_hook_addref(struct afb_hook *spec);
diff --git a/src/afb-hreq.c b/src/afb-hreq.c
index 00d4b0eb..0fe908cb 100644
--- a/src/afb-hreq.c
+++ b/src/afb-hreq.c
@@ -335,6 +335,8 @@ void afb_hreq_unref(struct afb_hreq *hreq)
}
afb_context_disconnect(&hreq->context);
json_object_put(hreq->json);
+ free(hreq->api);
+ free(hreq->verb);
free(hreq);
}
@@ -940,6 +942,20 @@ static void req_subcall(struct afb_hreq *hreq, const char *api, const char *verb
afb_subcall(&hreq->context, api, verb, args, callback, closure, (struct afb_req){ .itf = &afb_hreq_req_itf, .closure = hreq });
}
+int afb_hreq_init_req_call(struct afb_hreq *hreq, const char *api, size_t lenapi, const char *verb, size_t lenverb)
+{
+ free(hreq->api);
+ free(hreq->verb);
+ hreq->api = strndup(api, lenapi);
+ hreq->verb = strndup(verb, lenverb);
+ if (hreq->api == NULL || hreq->verb == NULL) {
+ ERROR("Out of memory");
+ errno = ENOMEM;
+ return -1;
+ }
+ return afb_hreq_init_context(hreq);
+}
+
int afb_hreq_init_context(struct afb_hreq *hreq)
{
const char *uuid;
diff --git a/src/afb-hreq.h b/src/afb-hreq.h
index f07f2fa6..5cb86091 100644
--- a/src/afb-hreq.h
+++ b/src/afb-hreq.h
@@ -51,6 +51,8 @@ struct afb_hreq {
struct hreq_data *data;
struct json_object *json;
int upgrade;
+ char *api;
+ char *verb;
};
extern int afb_hreq_unprefix(struct afb_hreq *request, const char *prefix, size_t length);
@@ -83,6 +85,8 @@ extern int afb_hreq_post_add(struct afb_hreq *hreq, const char *name, const char
extern struct afb_req afb_hreq_to_req(struct afb_hreq *hreq);
+extern int afb_hreq_init_req_call(struct afb_hreq *hreq, const char *api, size_t lenapi, const char *verb, size_t lenverb);
+
extern int afb_hreq_init_context(struct afb_hreq *hreq);
extern int afb_hreq_init_cookie(int port, const char *path, int maxage);
diff --git a/src/afb-hswitch.c b/src/afb-hswitch.c
index 9c929e83..909480af 100644
--- a/src/afb-hswitch.c
+++ b/src/afb-hswitch.c
@@ -44,10 +44,10 @@ int afb_hswitch_apis(struct afb_hreq *hreq, void *data)
if (!(*api && *verb && lenapi && lenverb))
return 0;
- if (afb_hreq_init_context(hreq) < 0)
+ if (afb_hreq_init_req_call(hreq, api, lenapi, verb, lenverb) < 0)
afb_hreq_reply_error(hreq, MHD_HTTP_INTERNAL_SERVER_ERROR);
else
- afb_apis_call(afb_hreq_to_req(hreq), &hreq->context, api, lenapi, verb, lenverb);
+ afb_apis_call(afb_hreq_to_req(hreq), &hreq->context, hreq->api, hreq->verb);
return 1;
}
diff --git a/src/afb-subcall.c b/src/afb-subcall.c
index 00547c47..65bef2ff 100644
--- a/src/afb-subcall.c
+++ b/src/afb-subcall.c
@@ -187,7 +187,7 @@ void afb_subcall(struct afb_context *context, const char *api, const char *verb,
subcall->closure = closure;
subcall->context = *context;
afb_req_addref(req);
- afb_apis_call_((struct afb_req){ .itf = &afb_subcall_req_itf, .closure = subcall }, &subcall->context, api, verb);
+ afb_apis_call((struct afb_req){ .itf = &afb_subcall_req_itf, .closure = subcall }, &subcall->context, api, verb);
subcall_unref(subcall);
}
diff --git a/src/afb-svc.c b/src/afb-svc.c
index c52ad654..20dcdcfc 100644
--- a/src/afb-svc.c
+++ b/src/afb-svc.c
@@ -64,19 +64,19 @@ struct svc_req
};
/* functions for services */
-static void svc_on_event(struct afb_svc *svc, const char *event, int eventid, struct json_object *object);
-static void svc_call(struct afb_svc *svc, const char *api, const char *verb, struct json_object *args,
- void (*callback)(void*, int, struct json_object*), void *closure);
+static void svc_on_event(void *closure, const char *event, int eventid, struct json_object *object);
+static void svc_call(void *closure, const char *api, const char *verb, struct json_object *args,
+ void (*callback)(void*, int, struct json_object*), void *cbclosure);
/* the interface for services */
static const struct afb_service_itf service_itf = {
- .call = (void*)svc_call
+ .call = svc_call
};
/* the interface for events */
static const struct afb_evt_itf evt_itf = {
- .broadcast = (void*)svc_on_event,
- .push = (void*)svc_on_event
+ .broadcast = svc_on_event,
+ .push = svc_on_event
};
/* functions for requests of services */
@@ -163,8 +163,9 @@ error:
/*
* Propagates the event to the service
*/
-static void svc_on_event(struct afb_svc *svc, const char *event, int eventid, struct json_object *object)
+static void svc_on_event(void *closure, const char *event, int eventid, struct json_object *object)
{
+ struct afb_svc *svc = closure;
svc->on_event(event, object);
json_object_put(object);
}
@@ -172,14 +173,15 @@ static void svc_on_event(struct afb_svc *svc, const char *event, int eventid, st
/*
* Initiates a call for the service
*/
-static void svc_call(struct afb_svc *svc, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure)
+static void svc_call(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cbclosure)
{
+ struct afb_svc *svc = closure;
struct svc_req *svcreq;
/* allocates the request */
svcreq = malloc(sizeof *svcreq);
if (svcreq == NULL)
- return afb_subcall_internal_error(callback, closure);
+ return afb_subcall_internal_error(callback, cbclosure);
/* initialises the request */
afb_context_init(&svcreq->context, svc->session, NULL);
@@ -188,7 +190,7 @@ static void svc_call(struct afb_svc *svc, const char *api, const char *verb, str
svcreq->refcount = 1;
/* makes the call */
- afb_subcall(&svcreq->context, api, verb, args, callback, closure, (struct afb_req){ .itf = &afb_svc_req_itf, .closure = svcreq });
+ afb_subcall(&svcreq->context, api, verb, args, callback, cbclosure, (struct afb_req){ .itf = &afb_svc_req_itf, .closure = svcreq });
/* terminates and frees ressources if needed */
svcreq_unref(svcreq);
diff --git a/src/afb-ws-json1.c b/src/afb-ws-json1.c
index f383868a..8309065d 100644
--- a/src/afb-ws-json1.c
+++ b/src/afb-ws-json1.c
@@ -220,7 +220,7 @@ static void aws_on_call(struct afb_ws_json1 *ws, const char *api, const char *ve
/* emits the call */
r.closure = wsreq;
r.itf = &afb_ws_json1_req_itf;
- afb_apis_call_(r, &wsreq->context, api, verb);
+ afb_apis_call(r, &wsreq->context, api, verb);
wsreq_unref(wsreq);
}