Hack --plugins=path
authorFulup Ar Foll <fulup@iot.bzh>
Mon, 21 Dec 2015 15:33:23 +0000 (16:33 +0100)
committerFulup Ar Foll <fulup@iot.bzh>
Mon, 21 Dec 2015 15:33:23 +0000 (16:33 +0100)
.gitignore
include/local-def.h
include/proto-def.h
plugins/samples/SamplePost.c
plugins/session/token-api.c
src/CMakeLists.txt
src/config.c
src/helper-api.c [new file with mode: 0644]
src/main.c
src/rest-api.c

index b47de8f..6f88c4e 100644 (file)
@@ -7,4 +7,4 @@ dist/*
 .dep.inc
 CMakeFiles/
 CMakeCache.txt
-nbproject/**
+nbproject/private/*
index 961fdd2..8f297c5 100644 (file)
@@ -107,6 +107,13 @@ typedef struct {
 
 typedef enum  {AFB_POST_NONE=0, AFB_POST_JSON, AFB_POST_FORM} AFB_PostType;
 
+// Post Upload File Handle
+typedef struct {
+   int   fd; 
+   char *path; 
+   json_object* jerror;
+} AFB_PostCtx;
+
 typedef  struct {
     int  len;   // post element size
     char *data; // post data in raw format
index 937d693..ac4f21b 100644 (file)
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-   $Id: $
 */
 
-// Rest-api
-
-PUBLIC json_object* apiPingTest(AFB_request *request);
+// helper-api
+PUBLIC json_object* getPingTest(AFB_request *request);
 PUBLIC const char* getQueryValue (AFB_request * request, char *name);
 PUBLIC int getQueryAll(AFB_request * request, char *query, size_t len);
+PUBLIC AFB_PostHandle* getPostHandle (AFB_request *request);
+PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* destination) ;
+PUBLIC AFB_PostCtx* getPostContext (AFB_request *request);
 
+// rest-api
 PUBLIC void endPostRequest(AFB_PostHandle *posthandle); 
 PUBLIC int doRestApi(struct MHD_Connection *connection, AFB_session *session, const char* url, const char *method
     , const char *upload_data, size_t *upload_data_size, void **con_cls);
-PUBLIC AFB_PostHandle* getPostHandle (AFB_request *request);
 
 void initPlugins (AFB_session *session);
 
index 223f74e..56c3f24 100644 (file)
 
 #include "local-def.h"
 
-
-// In this case or handle is quite basic
-typedef struct {
-   int   fd; 
-   char *path; 
-   json_object* jerror;
-} appPostCtx;
-
 // With content-type=json data are directly avaliable in request->post->data
 STATIC json_object* GetJsonByPost (AFB_request *request) {
     json_object* jresp;
@@ -46,122 +38,72 @@ STATIC json_object* GetJsonByPost (AFB_request *request) {
     return (jresp);    
 }
 
-// This function is call when PostForm processing is completed
-STATIC void DonePostForm (AFB_request *request) { 
-    
-    // Retrieve PostHandle Context from request
-    AFB_PostHandle *postHandle = getPostHandle(request);
-    appPostCtx *appCtx= (appPostCtx*) postHandle->ctx;
-
-    if (verbose) fprintf (stderr, "DonePostForm file=[%s]upload done\n", appCtx->path);
-    
-
-}
 
 
-// PostForm callback is called multiple times (one or each key within form, or once per file buffer)
-// When processing POST_FORM request->data holds a PostHandle and not data directly as for POST_JSON
-// When file has been fully uploaded call is call with item==NULL it is application responsibility to free appPostCtx
-STATIC json_object* UploadFile (AFB_request *request, AFB_PostItem *item) {
+// Upload a file and execute a function when upload is done
+STATIC json_object* UploadAppli (AFB_request *request, AFB_PostItem *item) {
+    
+    char *destination = "applications";
 
-    AFB_PostHandle *postHandle = getPostHandle(request);
-    appPostCtx *appCtx;
-    char filepath[512];
-    int len;
-            
     // This is called after PostForm and then after DonePostForm
     if (item == NULL) {
-        json_object* jresp;
-        appCtx = (appPostCtx*) postHandle->ctx;
-        
-        // No Post Application Context [something really bad happen]
-        if (appCtx == NULL) {
-            request->errcode = MHD_HTTP_EXPECTATION_FAILED;
-            return(jsonNewMessage(AFB_FAIL,"Error: PostForm no PostContext to free\n"));          
+        AFB_PostCtx *postFileCtx = getPostContext(request);      
+        if (postFileCtx != NULL) {
+            
+            // request Application Framework to install application
+            
+            request->errcode = MHD_HTTP_OK;   // or error is something went wrong;   
+            request->jresp   = jsonNewMessage(AFB_FAIL,"UploadFile Post Request file=[%s] done", postFileCtx->path);
         }
-        
-        // We have a context but last Xform iteration fail.
-        if (appCtx->jerror != NULL) {
-            request->errcode = MHD_HTTP_EXPECTATION_FAILED;
-            jresp = appCtx->jerror;  // retrieve previous error from postCtx
-        } else jresp = jsonNewMessage(AFB_FAIL,"UploadFile Post Request file=[%s] done", appCtx->path);
-        
-        // Error or not let's free all resources
-        close(appCtx->fd);
-        free (appCtx->path);
-        free (appCtx);
-        return (jresp);  
     }
     
-    // Make sure it's a valid PostForm request
-    if (!request->post && request->post->type != AFB_POST_FORM) {
-        appCtx->jerror= jsonNewMessage(AFB_FAIL,"This is not a valid PostForm request\n");
-        goto ExitOnError;
-    } 
-    
-    // Check this is a file element
-    if (item->filename == NULL) {
-        appCtx->jerror= jsonNewMessage(AFB_FAIL,"No Filename attached to key=%s\n", item->key);
-        goto ExitOnError;
-    }
-    
-    // Check we got something in buffer
-    if (item->len <= 0) {       
-        appCtx->jerror= jsonNewMessage(AFB_FAIL,"Buffer size NULL key=%s]\n", item->key);
-        goto ExitOnError;
-    }
+    // upload multi iteration logic is handle by getPostedFile
+    return (getPostFile (request, item, destination));
+}
 
-    // Extract Application Context from posthandle [NULL == 1st iteration]    
-    appCtx = (appPostCtx*) postHandle->ctx;
+// Simples Upload case just upload a file
+STATIC json_object* UploadMusic (AFB_request *request, AFB_PostItem *item) {
+    
+    char *destination = "musics";
 
-    // This is the 1st Item iteration let's open output file and allocate necessary resources
-    if (appCtx == NULL)  {
-        // Create an application specific context
-        appCtx = calloc (1, sizeof(appPostCtx)); // May place anything here until post->completeCB handle resources liberation
-        appCtx->path = strdup (filepath);
-        
-        // attach application to postHandle
-        postHandle->ctx = (void*) appCtx;   // May place anything here until post->completeCB handle resources liberation  
-        
-        // Allocate an application specific handle to this post
-        strncpy (filepath, request->config->sessiondir, sizeof(filepath));
-        strncat (filepath, "/", sizeof(filepath));
-        strncat (filepath, item->filename, sizeof(filepath));  
+    // upload multi iteration logic is handle by getPostedFile
+    return (getPostFile (request, item, destination));
+}
 
-        if((appCtx->fd = open(filepath, O_RDWR |O_CREAT, S_IRWXU|S_IRGRP)) < 0) {
-            appCtx->jerror= jsonNewMessage(AFB_FAIL,"Fail to Create destination=[%s] error=%s\n", filepath, strerror(errno));
-            goto ExitOnError;
-        } 
-    } else {     
-        // reuse existing application context
-        appCtx = (appPostCtx*) postHandle->ctx;  
-    } 
+// PostForm callback is called multiple times (one or each key within form, or once per file buffer)
+// When file has been fully uploaded call is call with item==NULL 
+STATIC json_object* UploadImage (AFB_request *request, AFB_PostItem *item) {
+    
+    // note if directory is relative it will be prefixed by request->config->sessiondir
+    char *destination = "images";
 
-    // Check we successfully wrote full buffer
-    len = write (appCtx->fd, item->data, item->len);
-    if (item->len != len) {
-        appCtx->jerror= jsonNewMessage(AFB_FAIL,"Fail to write file [%s] at [%s] error=\n", item->filename, strerror(errno));
-        goto ExitOnError;
+    // This is called after PostForm and then after DonePostForm
+    if (item == NULL) {
+        AFB_PostCtx *postFileCtx = getPostContext(request);
+        
+        // if postFileCtx == NULL then an error happen [getPostedFile automatically reports errors]
+        if (postFileCtx != NULL) {
+            // Do something with your newly upload filepath=postFileCtx->path
+            request->errcode = MHD_HTTP_OK;     
+            request->jresp   = jsonNewMessage(AFB_FAIL,"UploadFile Post Request file=[%s] done", postFileCtx->path);    
+            
+            // Note: should not return here in order getPostedFile to clear Post resources.
+        }
     }
-  
-    // every intermediary iteration should return Success & NULL
-    request->errcode = MHD_HTTP_OK;
-    return NULL;
     
-ExitOnError:    
-    request->errcode = MHD_HTTP_EXPECTATION_FAILED;
-    return NULL;
+    // upload multi iteration logic is handle by getPostedFile
+    return (getPostFile (request, item, destination));
 }
 
 
 // NOTE: this sample does not use session to keep test a basic as possible
 //       in real application upload-xxx should be protected with AFB_SESSION_CHECK
 STATIC  AFB_restapi pluginApis[]= {
-  {"ping"         , AFB_SESSION_NONE  , (AFB_apiCB)apiPingTest    ,"Ping Rest Test Service"},
+  {"ping"         , AFB_SESSION_NONE  , (AFB_apiCB)getPingTest    ,"Ping Rest Test Service"},
   {"upload-json"  , AFB_SESSION_NONE  , (AFB_apiCB)GetJsonByPost  ,"Demo for Json Buffer on Post"},
-  {"upload-image" , AFB_SESSION_NONE  , (AFB_apiCB)UploadFile     ,"Demo for file upload"},
-  {"upload-music" , AFB_SESSION_NONE  , (AFB_apiCB)UploadFile     ,"Demo for file upload"},
-  {"upload-appli" , AFB_SESSION_NONE  , (AFB_apiCB)UploadFile     ,"Demo for file upload"},
+  {"upload-image" , AFB_SESSION_NONE  , (AFB_apiCB)UploadImage    ,"Demo for file upload"},
+  {"upload-music" , AFB_SESSION_NONE  , (AFB_apiCB)UploadMusic    ,"Demo for file upload"},
+  {"upload-appli" , AFB_SESSION_NONE  , (AFB_apiCB)UploadAppli    ,"Demo for file upload"},
   {NULL}
 };
 
index ba6d276..585c343 100644 (file)
@@ -86,7 +86,7 @@ STATIC void clientContextFree(AFB_clientCtx *client) {
 }
 
 STATIC  AFB_restapi pluginApis[]= {
-  {"ping"    , AFB_SESSION_NONE  , (AFB_apiCB)apiPingTest         ,"Ping Rest Test Service"},
+  {"ping"    , AFB_SESSION_NONE  , (AFB_apiCB)getPingTest         ,"Ping Rest Test Service"},
   {"create"  , AFB_SESSION_CREATE, (AFB_apiCB)clientContextCreate ,"Request Client Context Creation"},
   {"refresh" , AFB_SESSION_RENEW , (AFB_apiCB)clientContextRefresh,"Refresh Client Context Token"},
   {"check"   , AFB_SESSION_CHECK , (AFB_apiCB)clientContextCheck  ,"Check Client Context Token"},
index ebf023a..6f7117d 100644 (file)
@@ -5,5 +5,5 @@ IF(librtlsdr_FOUND)
   ADD_DEFINITIONS(-DHAVE_RADIO_PLUGIN=1)
 ENDIF(librtlsdr_FOUND)
 
-ADD_LIBRARY(src OBJECT main.c config.c session.c http-svc.c rest-api.c)
+ADD_LIBRARY(src OBJECT main.c config.c session.c http-svc.c rest-api.c helper-api.c)
 INCLUDE_DIRECTORIES(${include_dirs})
index 2e7611a..815d11f 100644 (file)
@@ -114,8 +114,8 @@ PUBLIC AFB_error configLoadFile (AFB_session * session, AFB_config *cliconfig) {
        session->config->smack= cliconfig->smack;
    }
 
-   if  (cliconfig->smack == NULL) {
-       session->config->plugins = "all";
+   if  (cliconfig->plugins == NULL) {
+       session->config->plugins = PLUGIN_INSTALL_DIR;
    } else {
        session->config->plugins= cliconfig->plugins;
    }
diff --git a/src/helper-api.c b/src/helper-api.c
new file mode 100644 (file)
index 0000000..670c9a1
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2015 "IoT.bzh"
+ * Author "Fulup Ar Foll"
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ */
+
+#include "../include/local-def.h"
+
+
+// handle to hold queryAll values
+typedef struct {
+     char    *msg;
+     int     idx;
+     size_t  len;
+} queryHandleT;
+
+// Sample Generic Ping Debug API
+PUBLIC json_object* getPingTest(AFB_request *request) {
+    static pingcount = 0;
+    json_object *response;
+    char query  [256];
+    char session[256];
+
+    int len;
+    AFB_clientCtx *client=request->client; // get client context from request
+    
+    // request all query key/value
+    len = getQueryAll (request, query, sizeof(query));
+    if (len == 0) strncpy (query, "NoSearchQueryList", sizeof(query));
+    
+    // check if we have some post data
+    if (request->post == NULL)  request->post->data="NoData"; 
+    
+    // check is we have a session and a plugin handle
+    if (client == NULL) strncpy (session,"NoSession", sizeof(session));       
+    else snprintf(session, sizeof(session),"uuid=%s token=%s ctx=0x%x handle=0x%x", client->uuid, client->token, client->ctx, client->ctx); 
+        
+    // return response to caller
+    response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon count=%d CtxtId=%d query={%s} session={%s} PostData: [%s] "
+               , pingcount++, request->client->cid, query, session, request->post->data);
+    return (response);
+}
+
+
+// Helper to retrieve argument from  connection
+PUBLIC const char* getQueryValue(AFB_request * request, char *name) {
+    const char *value;
+
+    value = MHD_lookup_connection_value(request->connection, MHD_GET_ARGUMENT_KIND, name);
+    return (value);
+}
+
+STATIC int getQueryCB (void*handle, enum MHD_ValueKind kind, const char *key, const char *value) {
+    queryHandleT *query = (queryHandleT*)handle;
+        
+    query->idx += snprintf (&query->msg[query->idx],query->len," %s: \'%s\',", key, value);
+}
+
+// Helper to retrieve argument from  connection
+PUBLIC int getQueryAll(AFB_request * request, char *buffer, size_t len) {
+    queryHandleT query;
+    buffer[0] = '\0'; // start with an empty string
+    query.msg= buffer;
+    query.len= len;
+    query.idx= 0;
+
+    MHD_get_connection_values (request->connection, MHD_GET_ARGUMENT_KIND, getQueryCB, &query);
+    return (len);
+}
+
+// Helper to retrieve POST handle
+PUBLIC AFB_PostHandle* getPostHandle (AFB_request *request) {
+    if (request->post == NULL) return (NULL);
+    return ((AFB_PostHandle*) request->post->data);
+}
+
+// Helper to retrieve POST file context
+PUBLIC AFB_PostCtx* getPostContext (AFB_request *request) {
+    AFB_PostHandle* postHandle;
+    if (request->post == NULL) return (NULL);
+    
+    postHandle = (AFB_PostHandle*) request->post->data;
+    if (postHandle == NULL) return NULL;
+       
+    return ((AFB_PostCtx*) postHandle->ctx);
+}
+
+PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* destination) {
+
+    AFB_PostHandle *postHandle = getPostHandle(request);
+    AFB_PostCtx *appCtx;
+    char filepath[512];
+    int len;
+            
+    // This is called after PostForm and then after DonePostForm
+    if (item == NULL) {
+        json_object* jresp;
+        appCtx = (AFB_PostCtx*) postHandle->ctx;
+        
+        // No Post Application Context [something really bad happen]
+        if (appCtx == NULL) {
+            request->errcode = MHD_HTTP_EXPECTATION_FAILED;
+            return(jsonNewMessage(AFB_FAIL,"Error: PostForm no PostContext to free\n"));          
+        }
+        
+        // We have a context but last Xform iteration fail.
+        if (appCtx->jerror != NULL) {
+            // request->errcode = appCtx->errcode;
+            jresp = appCtx->jerror;  // retrieve previous error from postCtx
+        } else jresp = jsonNewMessage(AFB_FAIL,"UploadFile Post Request file=[%s] done", appCtx->path);
+        
+        // Error or not let's free all resources
+        close(appCtx->fd);
+        free (appCtx->path);
+        free (appCtx);
+        return (jresp);  
+    }
+    
+    // Make sure it's a valid PostForm request
+    if (!request->post && request->post->type != AFB_POST_FORM) {
+        appCtx->jerror= jsonNewMessage(AFB_FAIL,"This is not a valid PostForm request\n");
+        goto ExitOnError;
+    } 
+    
+    // Check this is a file element
+    if (item->filename == NULL) {
+        appCtx->jerror= jsonNewMessage(AFB_FAIL,"No Filename attached to key=%s\n", item->key);
+        goto ExitOnError;
+    }
+    
+    // Check we got something in buffer
+    if (item->len <= 0) {       
+        appCtx->jerror= jsonNewMessage(AFB_FAIL,"Buffer size NULL key=%s]\n", item->key);
+        goto ExitOnError;
+    }
+
+    // Extract Application Context from posthandle [NULL == 1st iteration]    
+    appCtx = (AFB_PostCtx*) postHandle->ctx;
+
+    // This is the 1st Item iteration let's open output file and allocate necessary resources
+    if (appCtx == NULL)  {
+        int destDir;
+        
+        // Create an application specific context
+        appCtx = calloc (1, sizeof(AFB_PostCtx)); // May place anything here until post->completeCB handle resources liberation
+        appCtx->path = strdup (filepath);
+        
+        // attach application to postHandle
+        postHandle->ctx = (void*) appCtx;   // May place anything here until post->completeCB handle resources liberation  
+        
+        // Build destination directory full path
+        if (destination[0] != '/') {
+           strncpy (filepath, request->config->sessiondir, sizeof(filepath)); 
+           strncat (filepath, destination, sizeof(filepath)); 
+           strncat (filepath, "/", sizeof(filepath));
+           strncat (filepath, destination, sizeof(filepath)); 
+        } else strncpy (filepath, destination, sizeof(filepath));
+        
+
+        // make sure destination directory exist
+        destDir = openat (filepath, request->plugin,  O_DIRECTORY);
+        if (destDir < 0) {
+          destDir = mkdir(filepath,O_RDWR | S_IRWXU | S_IRGRP); 
+          if (destDir < 0) {
+            appCtx->jerror= jsonNewMessage(AFB_FAIL,"Fail to Create destination directory=[%s] error=%s\n", filepath, strerror(errno));
+            goto ExitOnError;
+          }
+        } else close (destDir);
+        
+        strncat (filepath, "/", sizeof(filepath));
+        strncat (filepath, item->filename, sizeof(filepath));  
+
+        if((appCtx->fd = open(filepath, O_RDWR |O_CREAT, S_IRWXU|S_IRGRP)) < 0) {
+            appCtx->jerror= jsonNewMessage(AFB_FAIL,"Fail to Create destination=[%s] error=%s\n", filepath, strerror(errno));
+            goto ExitOnError;
+        } 
+    } else {     
+        // reuse existing application context
+        appCtx = (AFB_PostCtx*) postHandle->ctx;  
+    } 
+
+    // Check we successfully wrote full buffer
+    len = write (appCtx->fd, item->data, item->len);
+    if (item->len != len) {
+        appCtx->jerror= jsonNewMessage(AFB_FAIL,"Fail to write file [%s] at [%s] error=\n", item->filename, strerror(errno));
+        goto ExitOnError;
+    }
+  
+    // every intermediary iteration should return Success & NULL
+    request->errcode = MHD_HTTP_OK;
+    return NULL;
+    
+ExitOnError:    
+    request->errcode = MHD_HTTP_EXPECTATION_FAILED;
+    return NULL;
+}
index aa0e9bc..dddc3e1 100644 (file)
@@ -108,7 +108,7 @@ static  AFB_options cliOptions [] = {
   {SET_CONFIG_EXIT  ,0,"saveonly"        , "Save config on disk and then exit"},
 
   {SET_SMACK        ,1,"smack"           , "Set Smack Label [default demo]"},
-  {SET_PLUGINS      ,1,"mods"            , "Enable module [default all]"},
+  {SET_PLUGINS      ,1,"plugins"         , "Load Plugins from dir [default = PLUGIN_INSTALL_DIR"},
   {SET_AUTH_TOKEN   ,1,"token"           , "Initial Secret [default=no-session, --token="" for session without authentication]"},
   
   {DISPLAY_VERSION  ,0,"version"         , "Display version and copyright"},
@@ -159,7 +159,7 @@ void signalQuit (int signum) {
          fprintf (stderr,"  --%-15s %s\n", command, cliOptions[ind].help);
       }
     }
-    fprintf (stderr,"Example:\n  %s\\\n  --verbose --port=1234 --smack=xxxx --token='azerty' --mods=alsa:dbus\n", name);
+    fprintf (stderr,"Example:\n  %s\\\n  --verbose --port=1234 --smack=xxxx --token='azerty' --plugins=build/plugins\n", name);
 } // end printHelp
 
 /*----------------------------------------------------------
@@ -357,7 +357,6 @@ int main(int argc, char *argv[])  {
 
     case SET_PLUGINS:
        if (optarg == 0) goto needValueForOption;
-       fprintf (stderr, "Not Implemented yet\n");
        cliconfig.plugins = optarg;
        break;
 
index da33167..0a31e20 100644 (file)
 #define AFB_MSG_JTYPE "AJB_reply"
 
 
-// handle to hold queryAll values
-typedef struct {
-     char    *msg;
-     int     idx;
-     size_t  len;
-} queryHandleT;
 
 static json_object     *afbJsonType;
 
 
-// Sample Generic Ping Debug API
-PUBLIC json_object* apiPingTest(AFB_request *request) {
-    static pingcount = 0;
-    json_object *response;
-    char query  [256];
-    char session[256];
-
-    int len;
-    AFB_clientCtx *client=request->client; // get client context from request
-    
-    // request all query key/value
-    len = getQueryAll (request, query, sizeof(query));
-    if (len == 0) strncpy (query, "NoSearchQueryList", sizeof(query));
-    
-    // check if we have some post data
-    if (request->post == NULL)  request->post->data="NoData"; 
-    
-    // check is we have a session and a plugin handle
-    if (client == NULL) strcpy (session,"NoSession");       
-    else snprintf(session, sizeof(session),"uuid=%s token=%s ctx=0x%x handle=0x%x", client->uuid, client->token, client->ctx, client->ctx); 
-        
-    // return response to caller
-    response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon count=%d CtxtId=%d query={%s} session={%s} PostData: [%s] "
-               , pingcount++, request->client->cid, query, session, request->post->data);
-    return (response);
-}
-
-
-// Helper to retrieve argument from  connection
-PUBLIC const char* getQueryValue(AFB_request * request, char *name) {
-    const char *value;
-
-    value = MHD_lookup_connection_value(request->connection, MHD_GET_ARGUMENT_KIND, name);
-    return (value);
-}
-
-STATIC int getQueryCB (void*handle, enum MHD_ValueKind kind, const char *key, const char *value) {
-    queryHandleT *query = (queryHandleT*)handle;
-        
-    query->idx += snprintf (&query->msg[query->idx],query->len," %s: \'%s\',", key, value);
-}
-
-// Helper to retrieve argument from  connection
-PUBLIC int getQueryAll(AFB_request * request, char *buffer, size_t len) {
-    queryHandleT query;
-    buffer[0] = '\0'; // start with an empty string
-    query.msg= buffer;
-    query.len= len;
-    query.idx= 0;
-
-    MHD_get_connection_values (request->connection, MHD_GET_ARGUMENT_KIND, getQueryCB, &query);
-    return (len);
-}
-
-
-// Helper to retreive POST handle
-PUBLIC AFB_PostHandle* getPostHandle (AFB_request *request) {
-    if (request->post == NULL) return (NULL);
-    return ((AFB_PostHandle*) request->post->data);
-}
-
 // Because of POST call multiple time requestApi we need to free POST handle here
 // Note this method is called from http-svc just before closing session
 PUBLIC void endPostRequest(AFB_PostHandle *postHandle) {
@@ -640,8 +573,8 @@ void initPlugins(AFB_session *session) {
     afbJsonType = json_object_new_string (AFB_MSG_JTYPE);
     int i = 0;
 
-    if ((dir = opendir(PLUGIN_INSTALL_DIR)) == NULL) {
-        fprintf(stderr, "Could not open plugin directory=%s\n", PLUGIN_INSTALL_DIR);
+    if ((dir = opendir(session->config->plugins)) == NULL) {
+        fprintf(stderr, "Could not open plugin directory=%s\n", session->config->plugins);
         return;
     }
 
@@ -650,7 +583,7 @@ void initPlugins(AFB_session *session) {
         if (!strstr (pluginDir->d_name, ".so"))
             continue;
 
-        asprintf (&pluginPath, PLUGIN_INSTALL_DIR "/%s", pluginDir->d_name);
+        asprintf (&pluginPath, "%s/%s", session->config->plugins, pluginDir->d_name);
         plugin = dlopen (pluginPath, RTLD_NOW | RTLD_LOCAL);
         pluginRegisterFct = dlsym (plugin, "pluginRegister");
         free (pluginPath);