Update the url of the project
[src/app-framework-binder.git] / src / afb-xreq.c
index 73841af..fe999af 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #define _GNU_SOURCE
-#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -438,8 +437,15 @@ static int xreq_subcallsync_cb(void *closure, const char *api, const char *verb,
 
 static void xreq_vverbose_cb(void*closure, int level, const char *file, int line, const char *func, const char *fmt, va_list args)
 {
-       /* TODO: improves the implementation. example: on condition make a list of log messages that will be returned */
-       vverbose(level, file, line, func, fmt, args);
+       char *p;
+       struct afb_xreq *xreq = closure;
+
+       if (!fmt || vasprintf(&p, fmt, args) < 0)
+               vverbose(level, file, line, func, fmt, args);
+       else {
+               verbose(level, file, line, func, "[REQ/API %s] %s", xreq->api, p);
+               free(p);
+       }
 }
 
 static struct afb_stored_req *xreq_store_cb(void *closure)
@@ -448,6 +454,12 @@ static struct afb_stored_req *xreq_store_cb(void *closure)
        return closure;
 }
 
+static int xreq_has_permission_cb(void*closure, const char *permission)
+{
+       struct afb_xreq *xreq = closure;
+       return afb_auth_has_permission(xreq, permission);
+}
+
 /******************************************************************************/
 
 static struct json_object *xreq_hooked_json_cb(void *closure)
@@ -627,6 +639,13 @@ static struct afb_stored_req *xreq_hooked_store_cb(void *closure)
        return r;
 }
 
+static int xreq_hooked_has_permission_cb(void*closure, const char *permission)
+{
+       struct afb_xreq *xreq = closure;
+       int r = xreq_has_permission_cb(closure, permission);
+       return afb_hook_xreq_has_permission(xreq, permission, r);
+}
+
 /******************************************************************************/
 
 const struct afb_req_itf xreq_itf = {
@@ -648,7 +667,8 @@ const struct afb_req_itf xreq_itf = {
        .subcallsync = xreq_subcallsync_cb,
        .vverbose = xreq_vverbose_cb,
        .store = xreq_store_cb,
-       .subcall_req = xreq_subcall_req_cb
+       .subcall_req = xreq_subcall_req_cb,
+       .has_permission = xreq_has_permission_cb
 };
 
 const struct afb_req_itf xreq_hooked_itf = {
@@ -670,7 +690,8 @@ const struct afb_req_itf xreq_hooked_itf = {
        .subcallsync = xreq_hooked_subcallsync_cb,
        .vverbose = xreq_hooked_vverbose_cb,
        .store = xreq_hooked_store_cb,
-       .subcall_req = xreq_hooked_subcall_req_cb
+       .subcall_req = xreq_hooked_subcall_req_cb,
+       .has_permission = xreq_hooked_has_permission_cb
 };
 
 /******************************************************************************/
@@ -823,7 +844,7 @@ static int xreq_session_check_apply_v2(struct afb_xreq *xreq, uint32_t sessionfl
                return -1;
        }
 
-       if (auth && !afb_auth_check(auth, xreq)) {
+       if (auth && !afb_auth_check(xreq, auth)) {
                afb_xreq_fail_f(xreq, "denied", "authorisation refused");
                errno = EPERM;
                return -1;
@@ -884,15 +905,15 @@ static void process_sync(struct afb_xreq *xreq)
                afb_hook_xreq_begin(xreq);
 
        /* search the api */
-       api = afb_apiset_lookup_started(xreq->apiset, xreq->api, 1);
-       if (!api) {
+       api = (const struct afb_api*)xreq->context.api_key;
+       if (api)
+               api->itf->call(api->closure, xreq);
+       else {
+               api = afb_apiset_lookup_started(xreq->apiset, xreq->api, 1);
                if (errno == ENOENT)
                        afb_xreq_fail_f(xreq, "unknown-api", "api %s not found", xreq->api);
                else
                        afb_xreq_fail_f(xreq, "bad-api-state", "api %s not started correctly: %m", xreq->api);
-       } else {
-               xreq->context.api_key = api->closure;
-               api->itf->call(api->closure, xreq);
        }
 }
 
@@ -910,10 +931,14 @@ static void process_async(int signum, void *arg)
 
 void afb_xreq_process(struct afb_xreq *xreq, struct afb_apiset *apiset)
 {
+       const struct afb_api *api;
+
        xreq->apiset = apiset;
+       api = afb_apiset_lookup_started(apiset, xreq->api, 1);
+       xreq->context.api_key = (void*)api;
 
        xreq_addref(xreq);
-       if (jobs_queue(NULL, afb_apiset_timeout_get(apiset), process_async, xreq) < 0) {
+       if (jobs_queue(api && api->noconcurrency ? (void*)api : NULL, afb_apiset_timeout_get(apiset), process_async, xreq) < 0) {
                /* TODO: allows or not to proccess it directly as when no threading? (see above) */
                ERROR("can't process job with threads: %m");
                afb_xreq_fail_f(xreq, "cancelled", "not able to create a job for the task");