Merge origin/master
authorFulup Ar Foll <fulup@iot.bzh>
Wed, 17 Feb 2016 13:41:07 +0000 (14:41 +0100)
committerFulup Ar Foll <fulup@iot.bzh>
Wed, 17 Feb 2016 13:41:07 +0000 (14:41 +0100)
1  2 
src/rest-api.c
src/session.c

diff --combined src/rest-api.c
@@@ -45,7 -45,7 +45,7 @@@ PUBLIC void endPostRequest(AFB_PostHand
      if (postHandle->type == AFB_POST_FORM) {
           if (verbose) fprintf(stderr, "End PostForm Request UID=%d\n", postHandle->uid);
      }
-     if (postHandle->private) free(postHandle->private);
+     if (postHandle->privatebuf) free(postHandle->privatebuf);
      free(postHandle);
  }
  
@@@ -107,7 -107,7 +107,7 @@@ STATIC AFB_error callPluginApi(AFB_requ
                              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(jreqt, "request", jcall);
 -                            return AFB_DONE;
 +                            goto ExitOnDone;
                         }
                      }
                      // Trigger a timer to protect from unacceptable long time execution
                          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(jreqt, "request", jcall);
 -                        return (AFB_DONE);                              
 +                        goto ExitOnDone;
                      };
                      
                      if (verbose) fprintf(stderr, "Plugin=[%s] Api=[%s] Middleware=[%d] Client=[0x%x] Uuid=[%s] Token=[%s]\n"
                      switch(plugin->apis[idx].session) {
  
                          case AFB_SESSION_CREATE:
 -                            if (clientCtx->token[0] != '\0') {
 +                            if (clientCtx->token[0] != '\0' && request->config->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(jreqt, "request", jcall);
 -                                return (AFB_DONE);                              
 +                                goto ExitOnDone;
                              }
                          
                              if (AFB_SUCCESS != ctxTokenCreate (clientCtx, request)) {
                                  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(jreqt, "request", jcall);
 -                                return (AFB_DONE);
 +                                goto ExitOnDone;
                              } 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, "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(jreqt, "request", jcall);
 -                                return (AFB_DONE);
 +                                goto ExitOnDone;
                              } 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, "status", json_object_new_string ("empty"));
                                  json_object_object_add(jcall, "info", json_object_new_string ("AFB_SESSION_CLOSE Not a Valid Access Token"));
                                  json_object_object_add(jreqt, "request", jcall);
 -                                return (AFB_DONE);
 +                                goto ExitOnDone;
                              } else {
                                  json_object_object_add(jcall, "uuid", json_object_new_string (clientCtx->uuid));                                
                              }
                                  json_object_object_add(jcall, "status", json_object_new_string ("fail"));
                                  json_object_object_add(jcall, "info", json_object_new_string ("AFB_SESSION_CHECK Invalid Active Token"));
                                  json_object_object_add(jreqt, "request", jcall);
 -                                return (AFB_DONE);
 +                                goto ExitOnDone;
                              }
                              break;
                      }
                  // Effectively CALL PLUGIN API with a subset of the context
                  jresp = plugin->apis[idx].callback(request, context);
                  
 -                // prefix response with request object;
 -                request->jresp = jreqt;
 -                
                  // Store context in case it was updated by plugins
                  if (request->context != NULL) clientCtx->contexts[plugidx] = request->context;               
                  
                  // API should return NULL of a valid Json Object
                  if (jresp == NULL) {
                      json_object_object_add(jcall, "status", json_object_new_string ("null"));
 -                    json_object_object_add(request->jresp, "request", jcall);
 +                    json_object_object_add(jreqt, "request", jcall);
                      request->errcode = MHD_HTTP_NO_RESPONSE;
                      
                  } else {
                      json_object_object_add(jcall, "status", json_object_new_string ("processed"));
 -                    json_object_object_add(request->jresp, "request", jcall);
 -                    json_object_object_add(request->jresp, "response", jresp);
 +                    json_object_object_add(jreqt, "request", jcall);
 +                    json_object_object_add(jreqt, "response", jresp);
                  }
                  // cancel timeout and plugin signal handle before next call
                  if (request->config->apiTimeout > 0) {
                      }
                  }              
              }       
 -            return (AFB_DONE);
 +            goto ExitOnDone; 
          }
      }   
      return (AFB_FAIL);
 +    
 +ExitOnDone:
 +    request->jresp = jreqt;
 +    return (AFB_DONE);                        
  }
  
  STATIC AFB_error findAndCallApi (AFB_request *request, void *context) {
@@@ -281,10 -280,11 +281,11 @@@ STATIC int doPostIterate (void *cls, en
      
    // retrieve API request from Post iterator handle  
    AFB_PostHandle *postHandle  = (AFB_PostHandle*)cls;
-   AFB_request *request = (AFB_request*)postHandle->private;
+   AFB_request *request = (AFB_request*)postHandle->privatebuf;
    AFB_PostRequest postRequest;
    
-   fprintf (stderr, "postHandle key=%s filename=%s len=%d mime=%s\n", key, filename, size, mimetype);
+   if (verbose)
+     fprintf (stderr, "postHandle key=%s filename=%s len=%d mime=%s\n", key, filename, size, mimetype);
     
    // Create and Item value for Plugin API
    item.kind     = kind;
@@@ -405,7 -405,7 +406,7 @@@ PUBLIC int doRestApi(struct MHD_Connect
                  request = createRequest (connection, session, url);
                  if (request->jresp != NULL) goto ProcessApiCall;
                  postHandle->type   = AFB_POST_FORM;
-                 postHandle->private= (void*)request;
+                 postHandle->privatebuf = (void*)request;
                  postHandle->pp     = MHD_create_post_processor (connection, MAX_POST_SIZE, &doPostIterate, postHandle);
                  
                  if (NULL == postHandle->pp) {
  
                  // Size is OK, let's allocate a buffer to hold post data
                  postHandle->type = AFB_POST_JSON;
-                 postHandle->private = malloc(contentlen + 1); // allocate memory for full POST data + 1 for '\0' enf of string
+                 postHandle->privatebuf = malloc(contentlen + 1); // allocate memory for full POST data + 1 for '\0' enf of string
  
                  // if (verbose) fprintf(stderr, "Create PostJson[uid=%d] Size=%d\n", postHandle->uid, contentlen);
                  return MHD_YES;
              // Process JsonPost request when buffer is completed let's call API    
              if (postHandle->type == AFB_POST_JSON) {
                  // if (verbose) fprintf(stderr, "Updating PostJson[uid=%d]\n", postHandle->uid);
-                 memcpy(&postHandle->private[postHandle->len], upload_data, *upload_data_size);
+                 memcpy(&postHandle->privatebuf[postHandle->len], upload_data, *upload_data_size);
                  postHandle->len = postHandle->len + *upload_data_size;
              }
              
                  }
  
                  // Before processing data, make sure buffer string is properly ended
-                 postHandle->private[postHandle->len] = '\0';
-                 postRequest.data = postHandle->private;
+                 postHandle->privatebuf[postHandle->len] = '\0';
+                 postRequest.data = postHandle->privatebuf;
                  request->post = &postRequest;
  
                  // if (verbose) fprintf(stderr, "Close Post[%d] Buffer=%s\n", postHandle->uid, request->post->data);
@@@ -563,15 -563,15 +564,15 @@@ STATIC AFB_plugin ** RegisterJsonPlugin
                
              // Prebuild each API jtype to boost API json response
              for (jdx = 0; plugins[idx]->apis[jdx].name != NULL; jdx++) {
-                 AFB_privateApi *private = malloc (sizeof (AFB_privateApi));
-                 if (plugins[idx]->apis[jdx].private != NULL) {
+                 AFB_privateApi *privateapi = malloc (sizeof (AFB_privateApi));
+                 if (plugins[idx]->apis[jdx].privateapi != NULL) {
                      fprintf (stderr, "WARNING: plugin=%s api=%s private handle should be NULL=0x%x\n"
-                             ,plugins[idx]->prefix,plugins[idx]->apis[jdx].name, plugins[idx]->apis[jdx].private);
+                             ,plugins[idx]->prefix,plugins[idx]->apis[jdx].name, plugins[idx]->apis[jdx].privateapi);
                  }
-                 private->len = strlen (plugins[idx]->apis[jdx].name);
-                 private->jtype=json_object_new_string(plugins[idx]->apis[jdx].name);
-                 json_object_get(private->jtype); // increase reference count to make it permanent
-                 plugins[idx]->apis[jdx].private = private;
+                 privateapi->len = strlen (plugins[idx]->apis[jdx].name);
+                 privateapi->jtype=json_object_new_string(plugins[idx]->apis[jdx].name);
+                 json_object_get(privateapi->jtype); // increase reference count to make it permanent
+                 plugins[idx]->apis[jdx].privateapi = privateapi;
              }
          }
      }
@@@ -637,17 -637,18 +638,18 @@@ STATIC void scanDirectory(char *dirpath
              }
  
              if (verbose) fprintf(stderr, "[%s] is a valid AFB plugin, loading pos[%d]\n", pluginDir.d_name, *count);
-             plugins[*count] = (AFB_plugin *) malloc (sizeof(AFB_plugin));
-             plugins[*count] = (**pluginRegisterFct)();
-             *count = *count +1;
+             plugins[*count] = pluginRegisterFct();
+             if (!plugins[*count]) {
+                 if (verbose) fprintf(stderr, "ERROR: plugin [%s] register function failed. continuing...\n", pluginDir.d_name);
+             } else
+                 *count = *count +1;
          }
      }
      closedir (dir);
  }
  
  void initPlugins(AFB_session *session) {
-     static AFB_plugin **plugins;
+     AFB_plugin **plugins;
      
      afbJsonType = json_object_new_string (AFB_MSG_JTYPE);
      int count = 0;
      int dirfd;
  
      /* pre-allocate for AFB_MAX_PLUGINS plugins, we will downsize later */
-     plugins = (AFB_plugin **) malloc (AFB_MAX_PLUGINS *sizeof(AFB_plugin));
+     plugins = (AFB_plugin **) malloc (AFB_MAX_PLUGINS *sizeof(AFB_plugin*));
      
      // Loop on every directory passed in --plugins=xxx
      while (dirpath = strsep(&session->config->ldpaths, ":")) {
      }
      
      // downsize structure to effective number of loaded plugins
-     plugins = (AFB_plugin **)realloc (plugins, (count+1)*sizeof(AFB_plugin));
+     plugins = (AFB_plugin **)realloc (plugins, (count+1)*sizeof(AFB_plugin*));
      plugins[count] = NULL;
  
      // complete plugins and save them within current sessions    
diff --combined src/session.c
@@@ -525,7 -525,6 +525,7 @@@ PUBLIC AFB_error ctxTokenReset (AFB_cli
      int ret;
  
      if (clientCtx == NULL) return AFB_EMPTY;
 +    //if (verbose) fprintf (stderr, "ctxClientReset New uuid=[%s] token=[%s] timestamp=%d\n", clientCtx->uuid, clientCtx->token, clientCtx->timeStamp);      
      
      // Search for an existing client with the same UUID
      clientCtx = ctxStoreSearch (clientCtx->uuid);
@@@ -583,6 -582,10 +583,10 @@@ PUBLIC AFB_error ctxTokenRefresh (AFB_c
      // Old token was valid let's regenerate a new one    
      uuid_generate(newuuid);         // create a new UUID
      uuid_unparse_lower(newuuid, clientCtx->token);
+     
+     // keep track of time for session timeout and further clean up
+     clientCtx->timeStamp=time(NULL);
+     
      return (AFB_SUCCESS);    
      
  }