+// Check of apiurl is declare in this plugin and call it
+STATIC AFB_error callPluginApi(AFB_request *request, int plugidx, void *context) {
+ json_object *jresp, *jcall;
+ int idx, status, sig;
+ AFB_clientCtx *clientCtx;
+ AFB_plugin *plugin = request->plugins[plugidx];
+ int signals[]= {SIGALRM, SIGSEGV, SIGFPE, 0};
+
+ /*---------------------------------------------------------------
+ | Signal handler defined inside CallPluginApi to access Request
+ +---------------------------------------------------------------- */
+ void pluginError (int signum) {
+ sigset_t sigset;
+
+
+ // unlock signal to allow a new signal to come
+ sigemptyset (&sigset);
+ sigaddset (&sigset, signum);
+ sigprocmask (SIG_UNBLOCK, &sigset, 0);
+
+ fprintf (stderr, "Oops:%s Plugin Api Timeout timeout\n", configTime());
+ longjmp (request->checkPluginCall, signum);
+ }
+
+
+ // If a plugin hold this urlpath call its callback
+ for (idx = 0; plugin->apis[idx].callback != NULL; idx++) {
+ if (!strcmp(plugin->apis[idx].name, request->api)) {
+
+ // Request was found and at least partially executed
+ request->jresp = json_object_new_object();
+ json_object_get (afbJsonType); // increate jsontype reference count
+ json_object_object_add (request->jresp, "jtype", afbJsonType);
+
+ // prepare an object to store calling values
+ jcall=json_object_new_object();
+ json_object_object_add(jcall, "prefix", json_object_new_string (plugin->prefix));
+ json_object_object_add(jcall, "api" , json_object_new_string (plugin->apis[idx].name));
+
+ // save context before calling the API
+ status = setjmp (request->checkPluginCall);
+ if (status != 0) {
+
+ // Plugin aborted somewhere during its execution
+ json_object_object_add(jcall, "status", json_object_new_string ("abort"));
+ json_object_object_add(jcall, "info" , json_object_new_string ("Plugin broke during execution"));
+ json_object_object_add(request->jresp, "request", jcall);
+
+ } else {
+
+ // If timeout protection==0 we are in debug and we do not apply signal protection
+ if (request->config->apiTimeout > 0) {
+ for (sig=0; signals[sig] != 0; sig++) {
+ if (signal (signals[sig], pluginError) == SIG_ERR) {
+ request->errcode = MHD_HTTP_UNPROCESSABLE_ENTITY;
+ json_object_object_add(jcall, "status", json_object_new_string ("fail"));
+ json_object_object_add(jcall, "info", json_object_new_string ("Setting Timeout Handler Failed"));
+ json_object_object_add(request->jresp, "request", jcall);
+ return AFB_DONE;
+ }
+ }
+ // Trigger a timer to protect from unacceptable long time execution
+ alarm (request->config->apiTimeout);
+ }
+
+ // Out of SessionNone every call get a client context session
+ if (AFB_SESSION_NONE != plugin->apis[idx].session) {
+
+ // add client context to request
+ clientCtx = ctxClientGet(request, plugidx);
+ if (clientCtx == NULL) {
+ request->errcode=MHD_HTTP_INSUFFICIENT_STORAGE;
+ json_object_object_add(jcall, "status", json_object_new_string ("fail"));
+ json_object_object_add(jcall, "info", json_object_new_string ("Client Session Context Full !!!"));
+ json_object_object_add(request->jresp, "request", jcall);
+ return (AFB_DONE);
+ };
+
+ if (verbose) fprintf(stderr, "Plugin=[%s] Api=[%s] Middleware=[%d] Client=[0x%x] Uuid=[%s] Token=[%s]\n"
+ , request->plugin, request->api, plugin->apis[idx].session, clientCtx, clientCtx->uuid, clientCtx->token);
+
+ switch(plugin->apis[idx].session) {
+
+ case AFB_SESSION_CREATE:
+ if (clientCtx->token[0] != '\0') {
+ request->errcode=MHD_HTTP_UNAUTHORIZED;
+ json_object_object_add(jcall, "status", json_object_new_string ("exist"));
+ json_object_object_add(jcall, "info", json_object_new_string ("AFB_SESSION_CREATE Session already exist"));
+ json_object_object_add(request->jresp, "request", jcall);
+ return (AFB_DONE);
+ }
+
+ if (AFB_SUCCESS != ctxTokenCreate (clientCtx, request)) {
+ request->errcode=MHD_HTTP_UNAUTHORIZED;
+ json_object_object_add(jcall, "status", json_object_new_string ("fail"));
+ json_object_object_add(jcall, "info", json_object_new_string ("AFB_SESSION_CREATE Invalid Initial Token"));
+ json_object_object_add(request->jresp, "request", jcall);
+ return (AFB_DONE);
+ } else {
+ json_object_object_add(jcall, "uuid", json_object_new_string (clientCtx->uuid));
+ json_object_object_add(jcall, "token", json_object_new_string (clientCtx->token));
+ json_object_object_add(jcall, "timeout", json_object_new_int (request->config->cntxTimeout));
+ }
+ break;
+
+
+ case AFB_SESSION_RENEW:
+ if (AFB_SUCCESS != ctxTokenRefresh (clientCtx, request)) {
+ request->errcode=MHD_HTTP_UNAUTHORIZED;
+ json_object_object_add(jcall, "status", json_object_new_string ("fail"));
+ json_object_object_add(jcall, "info", json_object_new_string ("AFB_SESSION_REFRESH Broken Exchange Token Chain"));
+ json_object_object_add(request->jresp, "request", jcall);
+ return (AFB_DONE);
+ } else {
+ json_object_object_add(jcall, "uuid", json_object_new_string (clientCtx->uuid));
+ json_object_object_add(jcall, "token", json_object_new_string (clientCtx->token));
+ json_object_object_add(jcall, "timeout", json_object_new_int (request->config->cntxTimeout));
+ }
+ break;