+ json_object_put(resu);
+ return rc;
+}
+
+static void xreq_vverbose_cb(struct afb_request *closure, int level, const char *file, int line, const char *func, const char *fmt, va_list args)
+{
+ char *p;
+ struct afb_xreq *xreq = xreq_from_request(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->request.api, p);
+ free(p);
+ }
+}
+
+static struct afb_stored_req *xreq_store_cb(struct afb_request *closure)
+{
+ xreq_addref_cb(closure);
+ return (struct afb_stored_req*)closure;
+}
+
+static int xreq_has_permission_cb(struct afb_request *closure, const char *permission)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_auth_has_permission(xreq, permission);
+}
+
+static char *xreq_get_application_id_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return xreq->cred && xreq->cred->id ? strdup(xreq->cred->id) : NULL;
+}
+
+static void *xreq_context_make_cb(struct afb_request *closure, int replace, void *(*create_value)(void*), void (*free_value)(void*), void *create_closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_context_make(&xreq->context, replace, create_value, free_value, create_closure);
+}
+
+static int xreq_get_uid_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return xreq->cred && xreq->cred->id ? (int)xreq->cred->uid : -1;
+}
+
+/******************************************************************************/
+
+static struct json_object *xreq_hooked_json_cb(struct afb_request *closure)
+{
+ struct json_object *r = xreq_json_cb(closure);
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_hook_xreq_json(xreq, r);
+}
+
+static struct afb_arg xreq_hooked_get_cb(struct afb_request *closure, const char *name)
+{
+ struct afb_arg r = xreq_get_cb(closure, name);
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_hook_xreq_get(xreq, name, r);
+}
+
+static void xreq_hooked_success_cb(struct afb_request *closure, struct json_object *obj, const char *info)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ afb_hook_xreq_success(xreq, obj, info);
+ xreq_success_cb(closure, obj, info);
+}
+
+static void xreq_hooked_fail_cb(struct afb_request *closure, const char *status, const char *info)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ afb_hook_xreq_fail(xreq, status, info);
+ xreq_fail_cb(closure, status, info);
+}
+
+static void xreq_hooked_vsuccess_cb(struct afb_request *closure, struct json_object *obj, const char *fmt, va_list args)
+{
+ vinfo(closure, obj, fmt, args, (void*)xreq_hooked_success_cb);
+}
+
+static void xreq_hooked_vfail_cb(struct afb_request *closure, const char *status, const char *fmt, va_list args)
+{
+ vinfo(closure, (void*)status, fmt, args, (void*)xreq_hooked_fail_cb);
+}
+
+static void *xreq_hooked_context_get_cb(struct afb_request *closure)
+{
+ void *r = xreq_context_get_cb(closure);
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_hook_xreq_context_get(xreq, r);
+}
+
+static void xreq_hooked_context_set_cb(struct afb_request *closure, void *value, void (*free_value)(void*))
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ afb_hook_xreq_context_set(xreq, value, free_value);
+ xreq_context_set_cb(closure, value, free_value);
+}
+
+static struct afb_request *xreq_hooked_addref_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ afb_hook_xreq_addref(xreq);
+ return xreq_addref_cb(closure);
+}
+
+static void xreq_hooked_unref_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ afb_hook_xreq_unref(xreq);
+ xreq_unref_cb(closure);
+}
+
+static void xreq_hooked_session_close_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ afb_hook_xreq_session_close(xreq);
+ xreq_session_close_cb(closure);
+}
+
+static int xreq_hooked_session_set_LOA_cb(struct afb_request *closure, unsigned level)
+{
+ int r = xreq_session_set_LOA_cb(closure, level);
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_hook_xreq_session_set_LOA(xreq, level, r);
+}
+
+static int xreq_hooked_subscribe_eventid_cb(struct afb_request *closure, struct afb_eventid *eventid);
+static int xreq_hooked_subscribe_cb(struct afb_request *closure, struct afb_event event)
+{
+ return xreq_hooked_subscribe_eventid_cb(closure, afb_event_to_eventid(event));
+}
+
+static int xreq_hooked_subscribe_eventid_cb(struct afb_request *closure, struct afb_eventid *eventid)
+{
+ int r = xreq_subscribe_eventid_cb(closure, eventid);
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_hook_xreq_subscribe(xreq, eventid, r);
+}
+
+static int xreq_hooked_unsubscribe_eventid_cb(struct afb_request *closure, struct afb_eventid *eventid);
+static int xreq_hooked_unsubscribe_cb(struct afb_request *closure, struct afb_event event)
+{
+ return xreq_hooked_unsubscribe_eventid_cb(closure, afb_event_to_eventid(event));
+}
+
+static int xreq_hooked_unsubscribe_eventid_cb(struct afb_request *closure, struct afb_eventid *eventid)
+{
+ int r = xreq_unsubscribe_eventid_cb(closure, eventid);
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ return afb_hook_xreq_unsubscribe(xreq, eventid, r);
+}
+
+static void xreq_hooked_subcall_cb(struct afb_request *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cb_closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ struct subcall *sc;
+
+ afb_hook_xreq_subcall(xreq, api, verb, args);
+ sc = subcall_alloc(xreq, api, verb, args);
+ if (sc == NULL) {
+ if (callback)
+ callback(cb_closure, 1, afb_msg_json_internal_error());
+ json_object_put(args);
+ } else {
+ subcall_hooked(sc, callback, cb_closure);
+ }
+}
+
+static void xreq_hooked_subcall_req_cb(struct afb_request *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*, struct afb_req), void *cb_closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ struct subcall *sc;
+
+ afb_hook_xreq_subcall_req(xreq, api, verb, args);
+ sc = subcall_alloc(xreq, api, verb, args);
+ if (sc == NULL) {
+ if (callback)
+ callback(cb_closure, 1, afb_msg_json_internal_error(), xreq_to_req(xreq));
+ json_object_put(args);
+ } else {
+ subcall_req_hooked(sc, callback, cb_closure);
+ }
+}
+
+static void xreq_hooked_subcall_request_cb(struct afb_request *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*, struct afb_request *), void *cb_closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ struct subcall *sc;
+
+ afb_hook_xreq_subcall(xreq, api, verb, args);
+ sc = subcall_alloc(xreq, api, verb, args);
+ if (sc == NULL) {
+ if (callback)
+ callback(cb_closure, 1, afb_msg_json_internal_error(), xreq_to_request(xreq));
+ json_object_put(args);
+ } else {
+ subcall_request_hooked(sc, callback, cb_closure);
+ }
+}
+
+static int xreq_hooked_subcallsync_cb(struct afb_request *closure, const char *api, const char *verb, struct json_object *args, struct json_object **result)
+{
+ int r;
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ afb_hook_xreq_subcallsync(xreq, api, verb, args);
+ r = xreq_subcallsync_cb(closure, api, verb, args, result);
+ return afb_hook_xreq_subcallsync_result(xreq, r, *result);
+}
+
+static void xreq_hooked_vverbose_cb(struct afb_request *closure, int level, const char *file, int line, const char *func, const char *fmt, va_list args)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ va_list ap;
+ va_copy(ap, args);
+ xreq_vverbose_cb(closure, level, file, line, func, fmt, args);
+ afb_hook_xreq_vverbose(xreq, level, file, line, func, fmt, ap);
+ va_end(ap);
+}
+
+static struct afb_stored_req *xreq_hooked_store_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ struct afb_stored_req *r = xreq_store_cb(closure);
+ afb_hook_xreq_store(xreq, r);
+ return r;
+}
+
+static int xreq_hooked_has_permission_cb(struct afb_request *closure, const char *permission)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ int r = xreq_has_permission_cb(closure, permission);
+ return afb_hook_xreq_has_permission(xreq, permission, r);
+}
+
+static char *xreq_hooked_get_application_id_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ char *r = xreq_get_application_id_cb(closure);
+ return afb_hook_xreq_get_application_id(xreq, r);
+}
+
+static void *xreq_hooked_context_make_cb(struct afb_request *closure, int replace, void *(*create_value)(void*), void (*free_value)(void*), void *create_closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ void *result = xreq_context_make_cb(closure, replace, create_value, free_value, create_closure);
+ return afb_hook_xreq_context_make(xreq, replace, create_value, free_value, create_closure, result);
+}
+
+static int xreq_hooked_get_uid_cb(struct afb_request *closure)
+{
+ struct afb_xreq *xreq = xreq_from_request(closure);
+ int r = xreq_get_uid_cb(closure);
+ return afb_hook_xreq_get_uid(xreq, r);
+}
+
+/******************************************************************************/
+
+const struct afb_request_itf xreq_itf = {
+ .json = xreq_json_cb,
+ .get = xreq_get_cb,
+ .success = xreq_success_cb,
+ .fail = xreq_fail_cb,
+ .vsuccess = xreq_vsuccess_cb,
+ .vfail = xreq_vfail_cb,
+ .context_get = xreq_context_get_cb,
+ .context_set = xreq_context_set_cb,
+ .addref = xreq_addref_cb,
+ .unref = xreq_unref_cb,
+ .session_close = xreq_session_close_cb,
+ .session_set_LOA = xreq_session_set_LOA_cb,
+ .subscribe = xreq_subscribe_cb,
+ .unsubscribe = xreq_unsubscribe_cb,
+ .subcall = xreq_subcall_cb,
+ .subcallsync = xreq_subcallsync_cb,
+ .vverbose = xreq_vverbose_cb,
+ .store = xreq_store_cb,
+ .subcall_req = xreq_subcall_req_cb,
+ .has_permission = xreq_has_permission_cb,
+ .get_application_id = xreq_get_application_id_cb,
+ .context_make = xreq_context_make_cb,
+ .subscribe_eventid = xreq_subscribe_eventid_cb,
+ .unsubscribe_eventid = xreq_unsubscribe_eventid_cb,
+ .subcall_request = xreq_subcall_request_cb,
+ .get_uid = xreq_get_uid_cb,
+};
+
+const struct afb_request_itf xreq_hooked_itf = {
+ .json = xreq_hooked_json_cb,
+ .get = xreq_hooked_get_cb,
+ .success = xreq_hooked_success_cb,
+ .fail = xreq_hooked_fail_cb,
+ .vsuccess = xreq_hooked_vsuccess_cb,
+ .vfail = xreq_hooked_vfail_cb,
+ .context_get = xreq_hooked_context_get_cb,
+ .context_set = xreq_hooked_context_set_cb,
+ .addref = xreq_hooked_addref_cb,
+ .unref = xreq_hooked_unref_cb,
+ .session_close = xreq_hooked_session_close_cb,
+ .session_set_LOA = xreq_hooked_session_set_LOA_cb,
+ .subscribe = xreq_hooked_subscribe_cb,
+ .unsubscribe = xreq_hooked_unsubscribe_cb,
+ .subcall = xreq_hooked_subcall_cb,
+ .subcallsync = xreq_hooked_subcallsync_cb,
+ .vverbose = xreq_hooked_vverbose_cb,
+ .store = xreq_hooked_store_cb,
+ .subcall_req = xreq_hooked_subcall_req_cb,
+ .has_permission = xreq_hooked_has_permission_cb,
+ .get_application_id = xreq_hooked_get_application_id_cb,
+ .context_make = xreq_hooked_context_make_cb,
+ .subscribe_eventid = xreq_hooked_subscribe_eventid_cb,
+ .unsubscribe_eventid = xreq_hooked_unsubscribe_eventid_cb,
+ .subcall_request = xreq_hooked_subcall_request_cb,
+ .get_uid = xreq_hooked_get_uid_cb,
+};
+
+/******************************************************************************/
+
+struct afb_req afb_xreq_unstore(struct afb_stored_req *sreq)
+{
+ struct afb_xreq *xreq = (struct afb_xreq *)sreq;
+ if (xreq->hookflags)
+ afb_hook_xreq_unstore(xreq);
+ return xreq_to_req(xreq);
+}
+
+struct json_object *afb_xreq_json(struct afb_xreq *xreq)
+{
+ return afb_request_json(xreq_to_request(xreq));
+}
+
+void afb_xreq_success(struct afb_xreq *xreq, struct json_object *obj, const char *info)
+{
+ afb_request_success(xreq_to_request(xreq), obj, info);