aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/afb-plugin.h1
-rw-r--r--include/afb-req-itf.h58
-rw-r--r--plugins/samples/ClientCtx.c42
-rw-r--r--plugins/session/token-api.c19
-rw-r--r--src/afb-api-so.c15
-rw-r--r--src/afb-apis.c9
-rw-r--r--src/afb-apis.h2
-rw-r--r--src/afb-hreq.c6
-rw-r--r--src/afb-ws-json.c7
-rw-r--r--src/main.c3
-rw-r--r--src/session.c33
-rw-r--r--src/session.h13
12 files changed, 97 insertions, 111 deletions
diff --git a/include/afb-plugin.h b/include/afb-plugin.h
index c7252d64..dfb6fbad 100644
--- a/include/afb-plugin.h
+++ b/include/afb-plugin.h
@@ -55,7 +55,6 @@ struct AFB_plugin
const char *info;
const char *prefix;
const struct AFB_restapi *apis;
- void (*freeCtxCB)(void*); // callback to free application context [null for standard free]
};
/* config mode */
diff --git a/include/afb-req-itf.h b/include/afb-req-itf.h
index 357ffd7b..f03ce868 100644
--- a/include/afb-req-itf.h
+++ b/include/afb-req-itf.h
@@ -26,26 +26,27 @@ struct afb_arg {
};
struct afb_req_itf {
- struct json_object *(*json)(void *data);
- struct afb_arg (*get)(void *data, const char *name);
- void (*success)(void *data, struct json_object *obj, const char *info);
- void (*fail)(void *data, const char *status, const char *info);
- const char *(*raw)(void *data, size_t *size);
- void (*send)(void *data, char *buffer, size_t size);
- int (*session_create)(void *data);
- int (*session_check)(void *data, int refresh);
- void (*session_close)(void *data);
+ struct json_object *(*json)(void *req_closure);
+ struct afb_arg (*get)(void *req_closure, const char *name);
+ void (*success)(void *req_closure, struct json_object *obj, const char *info);
+ void (*fail)(void *req_closure, const char *status, const char *info);
+ const char *(*raw)(void *req_closure, size_t *size);
+ void (*send)(void *req_closure, char *buffer, size_t size);
+ void *(*context_get)(void *ctx_closure);
+ void (*context_set)(void *ctx_closure, void *context, void (*free_context)(void*));
+ int (*session_create)(void *req_closure);
+ int (*session_check)(void *req_closure, int refresh);
+ void (*session_close)(void *req_closure);
};
struct afb_req {
const struct afb_req_itf *itf;
- void *data;
- void **context;
+ void *req_closure;
+ void *ctx_closure;
};
-
static inline struct afb_arg afb_req_get(struct afb_req req, const char *name)
{
- return req.itf->get(req.data, name);
+ return req.itf->get(req.req_closure, name);
}
static inline const char *afb_req_value(struct afb_req req, const char *name)
@@ -60,32 +61,47 @@ static inline const char *afb_req_path(struct afb_req req, const char *name)
static inline struct json_object *afb_req_json(struct afb_req req)
{
- return req.itf->json(req.data);
+ return req.itf->json(req.req_closure);
}
static inline void afb_req_success(struct afb_req req, struct json_object *obj, const char *info)
{
- req.itf->success(req.data, obj, info);
+ req.itf->success(req.req_closure, obj, info);
}
static inline void afb_req_fail(struct afb_req req, const char *status, const char *info)
{
- req.itf->fail(req.data, status, info);
+ req.itf->fail(req.req_closure, status, info);
}
static inline const char *afb_req_raw(struct afb_req req, size_t *size)
{
- return req.itf->raw(req.data, size);
+ return req.itf->raw(req.req_closure, size);
}
static inline void afb_req_send(struct afb_req req, char *buffer, size_t size)
{
- req.itf->send(req.data, buffer, size);
+ req.itf->send(req.req_closure, buffer, size);
+}
+
+static inline void *afb_req_context_get(struct afb_req req)
+{
+ return req.itf->context_get(req.ctx_closure);
+}
+
+static inline void afb_req_context_set(struct afb_req req, void *context, void (*free_context)(void*))
+{
+ return req.itf->context_set(req.ctx_closure, context, free_context);
+}
+
+static inline void afb_req_context_clear(struct afb_req req)
+{
+ afb_req_context_set(req, NULL, NULL);
}
static inline int afb_req_session_create(struct afb_req req)
{
- int result = req.itf->session_create(req.data);
+ int result = req.itf->session_create(req.req_closure);
if (!result)
afb_req_fail(req, "fail", "Can't create the session");
return result;
@@ -93,7 +109,7 @@ static inline int afb_req_session_create(struct afb_req req)
static inline int afb_req_session_check(struct afb_req req, int refresh)
{
- int result = req.itf->session_check(req.data, refresh);
+ int result = req.itf->session_check(req.req_closure, refresh);
if (!result)
afb_req_fail(req, "fail", "Token chek failed for the session");
return result;
@@ -101,7 +117,7 @@ static inline int afb_req_session_check(struct afb_req req, int refresh)
static inline void afb_req_session_close(struct afb_req req)
{
- req.itf->session_close(req.data);
+ req.itf->session_close(req.req_closure);
}
#if !defined(_GNU_SOURCE)
diff --git a/plugins/samples/ClientCtx.c b/plugins/samples/ClientCtx.c
index 24cb4f30..11d10240 100644
--- a/plugins/samples/ClientCtx.c
+++ b/plugins/samples/ClientCtx.c
@@ -23,19 +23,6 @@
typedef struct {
/*
- * In case your plugin is implemented on multiple files or used share routines
- * with other plugins, it might not be possible to use global static variable.
- * In this case you can attach a static handle to your plugin. This handle
- * is passed within each API call under request->handle
- *
- */
- void *anythingYouWant;
-
-
-} MyPluginHandleT;
-
-typedef struct {
- /*
* client context is attached a session but private to a each plugin.
* Context is passed to each API under request->context
*
@@ -57,24 +44,19 @@ typedef struct {
} MyClientContextT;
-
-// Plugin handle should not be in stack (malloc or static)
-static MyPluginHandleT global_handle;
-
// This function is call at session open time. Any client trying to
// call it with an already open session will be denied.
// Ex: http://localhost:1234/api/context/create?token=123456789
static void myCreate (struct afb_req request)
{
MyClientContextT *ctx = malloc (sizeof (MyClientContextT));
- MyPluginHandleT *handle = (MyPluginHandleT*) &global_handle;
// store something in our plugin private client context
ctx->count = 0;
ctx->abcd = "SomeThingUseful";
- *request.context = ctx;
- afb_req_success_f(request, NULL, "SUCCESS: create client context for plugin [%s]", handle->anythingYouWant);
+ afb_req_context_set(request, ctx, free);
+ afb_req_success_f(request, NULL, "SUCCESS: create client context for plugin [%s]", ctx->abcd);
}
// This function can only be called with a valid token. Token should be renew before
@@ -83,12 +65,11 @@ static void myCreate (struct afb_req request)
// ex: http://localhost:1234/api/context/action?token=xxxxxx-xxxxxx-xxxxx-xxxxx-xxxxxx
static void myAction (struct afb_req request)
{
- MyPluginHandleT *handle = (MyPluginHandleT*) &global_handle;
- MyClientContextT *ctx = (MyClientContextT*) *request.context;
+ MyClientContextT *ctx = (MyClientContextT*) afb_req_context_get(request);
// store something in our plugin private client context
ctx->count++;
- afb_req_success_f(request, NULL, "SUCCESS: plugin [%s] Check=[%d]\n", handle->anythingYouWant, ctx->count);
+ afb_req_success_f(request, NULL, "SUCCESS: plugin [%s] Check=[%d]\n", ctx->abcd, ctx->count);
}
// After execution of this function, client session will be close and if they
@@ -97,20 +78,11 @@ static void myAction (struct afb_req request)
// ex: http://localhost:1234/api/context/close?token=xxxxxx-xxxxxx-xxxxx-xxxxx-xxxxxx
static void myClose (struct afb_req request)
{
- MyPluginHandleT *handle = (MyPluginHandleT*) &global_handle;
- MyClientContextT *ctx = (MyClientContextT*) *request.context;
+ MyClientContextT *ctx = (MyClientContextT*) afb_req_context_get(request);
// store something in our plugin private client context
ctx->count++;
- afb_req_success_f(request, NULL, "SUCCESS: plugin [%s] Close=[%d]\n", handle->anythingYouWant, ctx->count);
-}
-
-static void freeCtxCB (MyClientContextT *ctx) {
- MyPluginHandleT *handle = (MyPluginHandleT*) &global_handle;
- fprintf (stderr, "FreeCtxCB Plugin=[%s] count=[%d]", (char*)handle->anythingYouWant, ctx->count);
- free (ctx);
-
- // Note: handle should be free it is a static resource attached to plugin and not to session
+ afb_req_success_f(request, NULL, "SUCCESS: plugin [%s] Close=[%d]\n", ctx->abcd, ctx->count);
}
// NOTE: this sample does not use session to keep test a basic as possible
@@ -127,12 +99,10 @@ static const struct AFB_plugin plugin_desc = {
.info = "Sample of Client Context Usage",
.prefix = "context",
.apis = pluginApis,
- .freeCtxCB = (void*)freeCtxCB
};
const struct AFB_plugin *pluginRegister (const struct AFB_interface *itf)
{
- global_handle.anythingYouWant = "anythingYouWant";
return &plugin_desc;
}
diff --git a/plugins/session/token-api.c b/plugins/session/token-api.c
index 91f9cd8f..bd76ceef 100644
--- a/plugins/session/token-api.c
+++ b/plugins/session/token-api.c
@@ -28,13 +28,20 @@ typedef struct {
} MyClientApplicationHandle;
+// This function is call when Client Session Context is removed
+// Note: when freeCtxCB==NULL standard free/malloc is called
+static void clientContextFree(void *context) {
+ fprintf (stderr,"Plugin[token] Closing Session\n");
+ free (context);
+}
+
// Request Creation of new context if it does not exist
static void clientContextCreate (struct afb_req request)
{
json_object *jresp;
// add an application specific client context to session
- request.context = malloc (sizeof (MyClientApplicationHandle));
+ afb_req_context_set(request, malloc (sizeof (MyClientApplicationHandle)), clientContextFree);
// Send response to UI
jresp = json_object_new_object();
@@ -92,13 +99,6 @@ static void clientGetPing (struct afb_req request) {
}
-// This function is call when Client Session Context is removed
-// Note: when freeCtxCB==NULL standard free/malloc is called
-static void clientContextFree(void *context) {
- fprintf (stderr,"Plugin[token] Closing Session\n");
- free (context);
-}
-
static const struct AFB_restapi pluginApis[]= {
{"ping" , AFB_SESSION_NONE , clientGetPing ,"Ping Rest Test Service"},
{"create" , AFB_SESSION_CREATE, clientContextCreate ,"Request Client Context Creation"},
@@ -112,8 +112,7 @@ static const struct AFB_plugin plugin_desc = {
.type = AFB_PLUGIN_JSON,
.info = "Application Framework Binder Service",
.prefix = "token",
- .apis = pluginApis,
- .freeCtxCB = clientContextFree
+ .apis = pluginApis
};
const struct AFB_plugin *pluginRegister (const struct AFB_interface *itf)
diff --git a/src/afb-api-so.c b/src/afb-api-so.c
index 60af72ef..c3cb08d7 100644
--- a/src/afb-api-so.c
+++ b/src/afb-api-so.c
@@ -86,17 +86,6 @@ static const struct afb_daemon_itf daemon_itf = {
.get_pollmgr = (void*)afb_api_so_get_pollmgr
};
-static void free_context(struct api_so_desc *desc, void *context)
-{
- void (*cb)(void*);
-
- cb = desc->plugin->freeCtxCB;
- if (cb)
- cb(context);
- else
- free(context);
-}
-
static void trapping_call(struct afb_req req, void(*cb)(struct afb_req))
{
volatile int signum, timerset;
@@ -159,7 +148,6 @@ static void call_check(struct afb_req req, const struct AFB_restapi *verb)
break;
}
trapping_call(req, verb->callback);
-
if (verb->session == AFB_SESSION_CLOSE)
afb_req_session_close(req);
}
@@ -238,8 +226,7 @@ int afb_api_so_add_plugin(const char *path)
/* records the plugin */
if (afb_apis_add(desc->plugin->prefix, (struct afb_api){
.closure = desc,
- .call = (void*)call,
- .free_context = (void*)free_context}) < 0) {
+ .call = (void*)call}) < 0) {
fprintf(stderr, "ERROR: plugin [%s] can't be registered...\n", path);
goto error3;
}
diff --git a/src/afb-apis.c b/src/afb-apis.c
index 0af3b42c..2822575b 100644
--- a/src/afb-apis.c
+++ b/src/afb-apis.c
@@ -41,13 +41,6 @@ int afb_apis_count()
return apis_count;
}
-void afb_apis_free_context(int apiidx, void *context)
-{
- const struct afb_api *api;
- api = &apis_array[apiidx].api;
- api->free_context(api->closure, context);
-}
-
int afb_apis_add(const char *name, struct afb_api api)
{
struct api_desc *apis;
@@ -98,7 +91,7 @@ void afb_apis_call(struct afb_req req, struct AFB_clientCtx *context, const char
a = apis_array;
for (i = 0 ; i < apis_count ; i++, a++) {
if (a->namelen == lenapi && !strncasecmp(a->name, api, lenapi)) {
- req.context = &context->contexts[i];
+ req.ctx_closure = &context->contexts[i];
a->api.call(a->api.closure, req, verb, lenverb);
return;
}
diff --git a/src/afb-apis.h b/src/afb-apis.h
index 59c7008f..985923f5 100644
--- a/src/afb-apis.h
+++ b/src/afb-apis.h
@@ -24,7 +24,6 @@ struct afb_api
{
void *closure;
void (*call)(void *closure, struct afb_req req, const char *verb, size_t lenverb);
- void (*free_context)(void *closure, void *context);
};
@@ -32,5 +31,4 @@ extern int afb_apis_count();
extern int afb_apis_add(const char *name, struct afb_api api);
extern void afb_apis_call(struct afb_req req, struct AFB_clientCtx *context, const char *api, size_t lenapi, const char *verb, size_t lenverb);
-extern void afb_apis_free_context(int apiidx, void *context);
diff --git a/src/afb-hreq.c b/src/afb-hreq.c
index 93cce62b..72b90504 100644
--- a/src/afb-hreq.c
+++ b/src/afb-hreq.c
@@ -81,7 +81,9 @@ static const struct afb_req_itf afb_hreq_itf = {
.send = (void*)req_send,
.session_create = (void*)req_session_create,
.session_check = (void*)req_session_check,
- .session_close = (void*)req_session_close
+ .session_close = (void*)req_session_close,
+ .context_get = (void*)afb_context_get,
+ .context_set = (void*)afb_context_set
};
static struct hreq_data *get_data(struct afb_hreq *hreq, const char *key, int create)
@@ -584,7 +586,7 @@ int afb_hreq_post_add_file(struct afb_hreq *hreq, const char *key, const char *f
struct afb_req afb_hreq_to_req(struct afb_hreq *hreq)
{
- return (struct afb_req){ .itf = &afb_hreq_itf, .data = hreq };
+ return (struct afb_req){ .itf = &afb_hreq_itf, .req_closure = hreq };
}
static struct afb_arg req_get(struct afb_hreq *hreq, const char *name)
diff --git a/src/afb-ws-json.c b/src/afb-ws-json.c
index a1766888..a34142c9 100644
--- a/src/afb-ws-json.c
+++ b/src/afb-ws-json.c
@@ -141,7 +141,10 @@ static const struct afb_req_itf wsreq_itf = {
.send = (void*)wsreq_send,
.session_create = (void*)wsreq_session_create,
.session_check = (void*)wsreq_session_check,
- .session_close = (void*)wsreq_session_close
+ .session_close = (void*)wsreq_session_close,
+ .context_get = (void*)afb_context_get,
+ .context_set = (void*)afb_context_set
+
};
static int aws_wsreq_parse(struct afb_wsreq *r, char *text, size_t size)
@@ -297,7 +300,7 @@ static void aws_on_text(struct afb_ws_json *ws, char *text, size_t size)
wsreq->next = ws->requests;
ws->requests = wsreq;
- r.data = wsreq;
+ r.req_closure = wsreq;
r.itf = &wsreq_itf;
afb_apis_call(r, ws->context, wsreq->api, wsreq->apilen, wsreq->verb, wsreq->verblen);
return;
diff --git a/src/main.c b/src/main.c
index e899739c..8ec684fe 100644
--- a/src/main.c
+++ b/src/main.c
@@ -34,6 +34,7 @@
#include "afb-config.h"
#include "afb-hswitch.h"
+#include "afb-apis.h"
#include "afb-api-so.h"
#include "afb-hsrv.h"
#include "afb-hreq.h"
@@ -577,7 +578,7 @@ int main(int argc, char *argv[]) {
if (config->ldpaths)
afb_api_so_add_pathset(config->ldpaths);
- ctxStoreInit(CTX_NBCLIENTS, config->cntxTimeout, config->token);
+ ctxStoreInit(CTX_NBCLIENTS, config->cntxTimeout, config->token, afb_apis_count());
if (!afb_hreq_init_cookie(config->httpdPort, config->rootapi, DEFLT_CNTX_TIMEOUT)) {
fprintf (stderr, "ERR: initialisation of cookies failed\n");
exit (1);
diff --git a/src/session.c b/src/session.c
index 329e17ab..fbc7f2fb 100644
--- a/src/session.c
+++ b/src/session.c
@@ -24,7 +24,6 @@
#include <uuid/uuid.h>
#include <assert.h>
-#include "afb-apis.h"
#include "session.h"
#define NOW (time(NULL))
@@ -40,6 +39,20 @@ static struct {
const char *initok;
} sessions;
+void *afb_context_get(struct afb_context *actx)
+{
+ return actx->context;
+}
+
+void afb_context_set(struct afb_context *actx, void *context, void (*free_context)(void*))
+{
+fprintf(stderr, "afb_context_set(%p,%p) was (%p,%p)\n",context, free_context, actx->context, actx->free_context);
+ if (actx->context != NULL && actx->free_context != NULL)
+ actx->free_context(actx->context);
+ actx->context = context;
+ actx->free_context = free_context;
+}
+
// Free context [XXXX Should be protected again memory abort XXXX]
static void ctxUuidFreeCB (struct AFB_clientCtx *client)
{
@@ -49,22 +62,18 @@ static void ctxUuidFreeCB (struct AFB_clientCtx *client)
assert (client->contexts != NULL);
// Free client handle with a standard Free function, with app callback or ignore it
- for (idx=0; idx < sessions.apicount; idx ++) {
- if (client->contexts[idx] != NULL) {
- afb_apis_free_context(idx, client->contexts[idx]);
- client->contexts[idx] = NULL;
- }
- }
+ for (idx=0; idx < sessions.apicount; idx ++)
+ afb_context_set(&client->contexts[idx], NULL, NULL);
}
// Create a new store in RAM, not that is too small it will be automatically extended
-void ctxStoreInit (int nbSession, int timeout, const char *initok)
+void ctxStoreInit (int max_session_count, int timeout, const char *initok, int context_count)
{
// let's create as store as hashtable does not have any
- sessions.store = calloc (1 + (unsigned)nbSession, sizeof(struct AFB_clientCtx));
- sessions.max = nbSession;
+ sessions.store = calloc (1 + (unsigned)max_session_count, sizeof(struct AFB_clientCtx));
+ sessions.max = max_session_count;
sessions.timeout = timeout;
- sessions.apicount = afb_apis_count();
+ sessions.apicount = context_count;
if (strlen(initok) >= 37) {
fprintf(stderr, "Error: initial token '%s' too long (max length 36)", initok);
exit(1);
@@ -191,7 +200,7 @@ TODO remove? not remove?
/* returns a new one */
clientCtx = calloc(1, sizeof(struct AFB_clientCtx)); // init NULL clientContext
if (clientCtx != NULL) {
- clientCtx->contexts = calloc ((unsigned)sessions.apicount, sizeof (void*));
+ clientCtx->contexts = calloc ((unsigned)sessions.apicount, sizeof(*clientCtx->contexts));
if (clientCtx->contexts != NULL) {
/* generate the uuid */
if (uuid == NULL) {
diff --git a/src/session.h b/src/session.h
index 0a61612d..569af654 100644
--- a/src/session.h
+++ b/src/session.h
@@ -18,17 +18,26 @@
#pragma once
+struct afb_context
+{
+ void *context;
+ void (*free_context)(void*);
+};
+
+extern void *afb_context_get(struct afb_context *actx);
+extern void afb_context_set(struct afb_context *actx, void *context, void (*free_context)(void*));
+
struct AFB_clientCtx
{
time_t expiration; // expiration time of the token
int created;
unsigned refcount;
- void **contexts; // application specific context [one per plugin]
+ struct afb_context *contexts;
char uuid[37]; // long term authentication of remote client
char token[37]; // short term authentication of remote client
};
-extern void ctxStoreInit (int nbSession, int timeout, const char *initok);
+extern void ctxStoreInit (int max_session_count, int timeout, const char *initok, int context_count);
extern struct AFB_clientCtx *ctxClientGetForUuid (const char *uuid);
extern struct AFB_clientCtx *ctxClientGet(struct AFB_clientCtx *clientCtx);