session: moves initialisation to main
[src/app-framework-binder.git] / src / session.c
index 781ecd9..3b9288f 100644 (file)
 #include <search.h>
 
 
-#define AFB_SESSION_JTYPE "AFB_session"
-#define AFB_SESSION_JLIST "AFB_sessions.hash"
-#define AFB_SESSION_JINFO "AFB_infos"
-
-
-#define AFB_CURRENT_SESSION "active-session"  // file link name within sndcard dir
-#define AFB_DEFAULT_SESSION "current-session" // should be in sync with UI
-
 // Session UUID are store in a simple array [for 10 sessions this should be enough]
 static struct {
   pthread_mutex_t mutex;          // declare a mutex to protect hash table
@@ -47,30 +39,15 @@ static struct {
   int max;
 } sessions;
 
-// verify we can read/write in session dir
-PUBLIC AFB_error sessionCheckdir (AFB_session *session) {
-
-   int err;
+#if defined(ALLOWS_SESSION_FILES)
 
-   // in case session dir would not exist create one
-   if (verbose) fprintf (stderr, "AFB:notice checking session dir [%s]\n", session->config->sessiondir);
-   mkdir(session->config->sessiondir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+#define AFB_SESSION_JTYPE "AFB_session"
+#define AFB_SESSION_JLIST "AFB_sessions.hash"
+#define AFB_SESSION_JINFO "AFB_infos"
 
-   // change for session directory
-   err = chdir(session->config->sessiondir);
-   if (err) {
-     fprintf(stderr,"AFB: Fail to chdir to %s error=%s\n", session->config->sessiondir, strerror(err));
-     return err;
-   }
 
-   // verify we can write session in directory
-   json_object *dummy= json_object_new_object();
-   json_object_object_add (dummy, "checked"  , json_object_new_int (getppid()));
-   err = json_object_to_file ("./AFB-probe.json", dummy);
-   if (err < 0) return err;
-
-   return AFB_SUCCESS;
-}
+#define AFB_CURRENT_SESSION "active-session"  // file link name within sndcard dir
+#define AFB_DEFAULT_SESSION "current-session" // should be in sync with UI
 
 // let's return only sessions.hash files
 STATIC int fileSelect (const struct dirent *entry) {
@@ -103,6 +80,48 @@ STATIC  json_object *checkCardDirExit (AFB_session *session, AFB_request *reques
     return NULL;
 }
 
+// Create a link toward last used sessionname within sndcard directory
+STATIC void makeSessionLink (const char *cardname, const char *sessionname) {
+   char linkname [256], filename [256];
+   int err;
+   // create a link to keep track of last uploaded sessionname for this card
+   strncpy (filename, sessionname, sizeof(filename));
+   strncat (filename, ".afb", sizeof(filename));
+
+   strncpy (linkname, cardname, sizeof(linkname));
+   strncat (linkname, "/", sizeof(filename));
+   strncat (linkname, AFB_CURRENT_SESSION, sizeof(linkname));
+   strncat (linkname, ".afb", sizeof(filename));
+   unlink (linkname); // remove previous link if any
+   err = symlink (filename, linkname);
+   if (err < 0) fprintf (stderr, "Fail to create link %s->%s error=%s\n", linkname, filename, strerror(errno));
+}
+
+// verify we can read/write in session dir
+PUBLIC AFB_error sessionCheckdir (AFB_session *session) {
+
+   int err;
+
+   // in case session dir would not exist create one
+   if (verbose) fprintf (stderr, "AFB:notice checking session dir [%s]\n", session->config->sessiondir);
+   mkdir(session->config->sessiondir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+
+   // change for session directory
+   err = chdir(session->config->sessiondir);
+   if (err) {
+     fprintf(stderr,"AFB: Fail to chdir to %s error=%s\n", session->config->sessiondir, strerror(err));
+     return err;
+   }
+
+   // verify we can write session in directory
+   json_object *dummy= json_object_new_object();
+   json_object_object_add (dummy, "checked"  , json_object_new_int (getppid()));
+   err = json_object_to_file ("./AFB-probe.json", dummy);
+   if (err < 0) return err;
+
+   return AFB_SUCCESS;
+}
+
 // create a session in current directory
 PUBLIC json_object *sessionList (AFB_session *session, AFB_request *request) {
     json_object *sessionsJ, *ajgResponse;
@@ -163,23 +182,6 @@ PUBLIC json_object *sessionList (AFB_session *session, AFB_request *request) {
     return (ajgResponse);
 }
 
-// Create a link toward last used sessionname within sndcard directory
-STATIC void makeSessionLink (const char *cardname, const char *sessionname) {
-   char linkname [256], filename [256];
-   int err;
-   // create a link to keep track of last uploaded sessionname for this card
-   strncpy (filename, sessionname, sizeof(filename));
-   strncat (filename, ".afb", sizeof(filename));
-
-   strncpy (linkname, cardname, sizeof(linkname));
-   strncat (linkname, "/", sizeof(filename));
-   strncat (linkname, AFB_CURRENT_SESSION, sizeof(linkname));
-   strncat (linkname, ".afb", sizeof(filename));
-   unlink (linkname); // remove previous link if any
-   err = symlink (filename, linkname);
-   if (err < 0) fprintf (stderr, "Fail to create link %s->%s error=%s\n", linkname, filename, strerror(errno));
-}
-
 // Load Json session object from disk
 PUBLIC json_object *sessionFromDisk (AFB_session *session, AFB_request *request, char *name) {
     json_object *jsonSession, *jtype, *response;
@@ -313,7 +315,7 @@ OnErrorExit:
    json_object_put (jsonSession);
    return response;
 }
-
+#endif
 
 // Free context [XXXX Should be protected again memory abort XXXX]
 STATIC void ctxUuidFreeCB (AFB_clientCtx *client) {
@@ -338,11 +340,10 @@ STATIC void ctxUuidFreeCB (AFB_clientCtx *client) {
 
 // Create a new store in RAM, not that is too small it will be automatically extended
 PUBLIC void ctxStoreInit (int nbSession) {
-   int res;
    
    // let's create as store as hashtable does not have any
-   sessions.store = calloc (nbSession+1, sizeof(AFB_clientCtx));
-   sessions.max=nbSession;
+   sessions.store = calloc (1 + (unsigned)nbSession, sizeof(AFB_clientCtx));
+   sessions.max = nbSession;
 }
 
 STATIC AFB_clientCtx *ctxStoreSearch (const char* uuid) {
@@ -421,7 +422,7 @@ STATIC int ctxStoreToOld (AFB_clientCtx *ctx, int timeout) {
 }
 
 // Loop on every entry and remove old context sessions.hash
-PUBLIC int ctxStoreGarbage (const int timeout) {
+PUBLIC void ctxStoreGarbage (const int timeout) {
     AFB_clientCtx *ctx;
     long idx;
     
@@ -439,7 +440,6 @@ PUBLIC AFB_clientCtx *ctxClientGet (AFB_request *request, int idx) {
   AFB_clientCtx *clientCtx=NULL;
   const char *uuid;
   uuid_t newuuid;
-  int ret;
   
     if (request->config->token == NULL) return NULL;
 
@@ -449,13 +449,14 @@ PUBLIC AFB_clientCtx *ctxClientGet (AFB_request *request, int idx) {
     // if UUID in query we're restfull with no cookies otherwise check for cookie
     if (uuid != NULL) request->restfull = TRUE;
     else {
+        char cookie[64];
         request->restfull = FALSE;
-        uuid = MHD_lookup_connection_value (request->connection, MHD_COOKIE_KIND, COOKIE_NAME);  
+        snprintf(cookie, sizeof cookie, "%s-%d", COOKIE_NAME, request->config->httpdPort);
+        uuid = MHD_lookup_connection_value (request->connection, MHD_COOKIE_KIND, cookie);  
     };
     
     // Warning when no cookie defined MHD_lookup_connection_value may return something !!!
     if ((uuid != NULL) && (strnlen (uuid, 10) >= 10))   {
-        int search;
         // search if client context exist and it not timeout let's use it
         clientCtx = ctxStoreSearch (uuid);
 
@@ -476,7 +477,7 @@ PUBLIC AFB_clientCtx *ctxClientGet (AFB_request *request, int idx) {
     // we have no session let's create one otherwise let's clean any exiting values
     if (clientCtx == NULL) {        
         clientCtx = calloc(1, sizeof(AFB_clientCtx)); // init NULL clientContext
-        clientCtx->contexts = calloc (1, request->config->pluginCount * (sizeof (void*)));        
+        clientCtx->contexts = calloc (1, (unsigned)request->config->pluginCount * (sizeof (void*)));
         clientCtx->plugins  = request->plugins;  
     }
     
@@ -522,9 +523,9 @@ PUBLIC AFB_error ctxTokenCheck (AFB_clientCtx *clientCtx, AFB_request *request)
 
 // Free Client Session Context
 PUBLIC AFB_error ctxTokenReset (AFB_clientCtx *clientCtx, AFB_request *request) {
-    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);
@@ -538,8 +539,6 @@ PUBLIC AFB_error ctxTokenReset (AFB_clientCtx *clientCtx, AFB_request *request)
 
 // generate a new token
 PUBLIC AFB_error ctxTokenCreate (AFB_clientCtx *clientCtx, AFB_request *request) {
-    int oldTnkValid;
-    const char *ornew;
     uuid_t newuuid;
     const char *token;
 
@@ -570,8 +569,6 @@ PUBLIC AFB_error ctxTokenCreate (AFB_clientCtx *clientCtx, AFB_request *request)
 
 // generate a new token and update client context
 PUBLIC AFB_error ctxTokenRefresh (AFB_clientCtx *clientCtx, AFB_request *request) {
-    int oldTnkValid;
-    const char *oldornew;
     uuid_t newuuid;
 
     if (clientCtx == NULL) return AFB_EMPTY;
@@ -582,6 +579,10 @@ PUBLIC AFB_error ctxTokenRefresh (AFB_clientCtx *clientCtx, AFB_request *request
     // 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);    
     
 }