/*
- * Copyright (C) 2016 "IoT.bzh"
+ * Copyright (C) 2016, 2017 "IoT.bzh"
* Author José Bollo <jose.bollo@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
#include "afb-context.h"
#include "afb-hook.h"
-#include "session.h"
+#include "afb-session.h"
#include "verbose.h"
/*
- * Trace
+ * Definition of a hook
*/
struct afb_hook {
struct afb_hook *next; /* next hook */
unsigned refcount; /* reference count */
- char *api;
- char *verb;
- struct AFB_clientCtx *session;
+ char *api; /* api hooked or NULL for any */
+ char *verb; /* verb hooked or NULL for any */
+ struct afb_session *session; /* session hooked or NULL if any */
unsigned flags; /* hook flags */
- struct afb_hook_req_itf *reqitf;
- void *closure;
+ struct afb_hook_req_itf *reqitf; /* interface of hook */
+ void *closure; /* closure for callbacks */
};
+/*
+ * Link hooks to a hooked request
+ */
struct hook_req_observer {
- struct afb_hook *hook;
- struct hook_req_observer *next;
+ struct afb_hook *hook; /* the hook */
+ struct hook_req_observer *next; /* the next observer */
};
/*
void *cb_closure; /* cient closure */
};
+/* counter of hooking */
static unsigned hook_count = 0;
+/* list of hooks */
static struct afb_hook *list_of_hooks = NULL;
/******************************************************************************
}
}
-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;
}
* 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;
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);
}
return req;
}
-struct afb_hook *afb_hook_req_create(const char *api, const char *verb, struct AFB_clientCtx *session, unsigned flags, struct afb_hook_req_itf *itf, void *closure)
+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)
{
struct afb_hook *hook;
hook->api = api ? strdup(api) : NULL;
hook->verb = verb ? strdup(verb) : NULL;
- hook->session = session ? ctxClientAddRef(session) : NULL;
+ hook->session = session ? afb_session_addref(session) : NULL;
if ((api && !hook->api) || (verb && !hook->verb)) {
free(hook->api);
free(hook->verb);
if (hook->session)
- ctxClientUnref(hook->session);
+ afb_session_unref(hook->session);
free(hook);
return NULL;
}
free(hook->api);
free(hook->verb);
if (hook->session)
- ctxClientUnref(hook->session);
+ afb_session_unref(hook->session);
free(hook);
}
}