Post En court Ne fonctionne pas
authorFulup Ar Foll <fulup@iot.bzh>
Tue, 15 Dec 2015 17:39:45 +0000 (18:39 +0100)
committerFulup Ar Foll <fulup@iot.bzh>
Tue, 15 Dec 2015 17:39:45 +0000 (18:39 +0100)
include/local-def.h
nbproject/configurations.xml
src/afbs-api.c
src/rest-api.c

index 47513e6..021ef13 100644 (file)
@@ -111,13 +111,13 @@ typedef  struct {
   
 // Post handler
 typedef struct {
-  void*  handle;
-  int    len;
-  int    uid;
-  AFB_PostType type;
-  struct MHD_PostProcessor *pp;
-  AFB_apiCB  completeCB;   // callback when post is completed
-  void   *private;
+  void*  ctx;               // Application context
+  int    len;               // current len for post
+  int    uid;               // post uid for debug
+  AFB_PostType type;        // JSON or FORM
+  AFB_apiCB  completeCB;    // callback when post is completed
+  void   *private;          // use internally to keep track or partial buffer
+  struct MHD_PostProcessor *pp; // iterator handle
 } AFB_PostHandle;
 
 typedef struct {
index 2435ae9..b1f18a0 100644 (file)
@@ -65,8 +65,6 @@
           <preBuildFirst>true</preBuildFirst>
         </preBuild>
       </makefileType>
-      <item path="src/SamplePost.c" ex="false" tool="0" flavor2="2">
-      </item>
       <item path="src/afbs-api.c" ex="false" tool="0" flavor2="2">
         <cTool flags="0">
           <incDir>
         </cTool>
       </item>
       <item path="src/dbus-api.c" ex="false" tool="0" flavor2="2">
-        <cTool flags="1">
+        <cTool flags="0">
           <incDir>
-            <pElem>src</pElem>
-            <pElem>/usr/include/json-c</pElem>
             <pElem>include</pElem>
-            <pElem>/usr/include/uuid</pElem>
+            <pElem>/usr/include/json-c</pElem>
             <pElem>build/src</pElem>
           </incDir>
-          <preprocessorList>
-            <Elem>__PIC__=2</Elem>
-            <Elem>__PIE__=2</Elem>
-            <Elem>__REGISTER_PREFIX__=</Elem>
-            <Elem>__USER_LABEL_PREFIX__=</Elem>
-            <Elem>__pic__=2</Elem>
-            <Elem>__pie__=2</Elem>
-          </preprocessorList>
         </cTool>
       </item>
       <item path="src/http-svc.c" ex="false" tool="0" flavor2="2">
index ae6ec63..1a3399f 100644 (file)
@@ -121,76 +121,89 @@ typedef struct {
 
 // This function is call when PostForm processing is completed
 STATIC void DonePostForm (AFB_request *request) {
-    AFB_PostHandle  *postHandle = (AFB_PostHandle*)request->post->data;;
-  
-    int fd = (int)postHandle->handle;
-    close (fd);
+    AFB_PostHandle  *postHandle = (AFB_PostHandle*)request->post->data;
+    appPostCtx *appCtx= postHandle->ctx;
+    
+    // Close upload file ID
+    close (appCtx->fd);
 
-    if (verbose) fprintf ("DonePostForm filename=%s upload done\n", form->filename);
+    // Free application specific handle
+    free (postHandle->ctx);
+    
+    if (verbose) fprintf (stderr, "DonePostForm upload done\n");
 }
 
 
-// WARNING: PostForm callback are call one type for form value
-STATIC AFB_error ProcessPostForm (AFB_request *request, AFB_PostItem *item) {
+// WARNING: PostForm callback are call multiple time (one or each key within form)
+// When processing POST_JSON request->data hold a PostHandle and not data directly as for POST_JSON
+STATIC json_object* ProcessPostForm (AFB_request *request, AFB_PostItem *item) {
 
     AFB_PostHandle  *postHandle;
     appPostCtx *appCtx;
+    char filepath[512];
             
     // When Post is fully processed the same callback is call with a item==NULL
     if (item == NULL) {
-        return(jsonNewMessage(AFB_SUCESS,"File [%s] uploaded at [%s] error=\n", item->filename, request->config->sessiondir));  
+        // Close file, Free handle
+        
+        request->errcode = MHD_HTTP_OK;
+        return(jsonNewMessage(AFB_SUCCESS,"File [%s] uploaded at [%s] error=\n", item->filename, request->config->sessiondir));  
     }
     
     // Let's make sure this is a valid PostForm request
     if (!request->post && request->post->type != AFB_POST_FORM) {
+        request->errcode = MHD_HTTP_FORBIDDEN;
         return(jsonNewMessage(AFB_FAIL,"This is not a valid PostForm request\n"));          
     } else {
         // In AFB_POST_FORM case post->data is a PostForm handle
         postHandle = (AFB_PostHandle*) request->post->data;
+        appCtx = (appPostCtx*) postHandle->ctx;
     }
 
     // Check this is a file element
     if (0 != strcmp (item->key, "file")) {
         request->errcode = MHD_HTTP_FORBIDDEN;
-        request.jresp = jsonNewMessage(AFB_FAIL,"No File within element key=%s\n", item->key);
-        return AFB_FAIL;
+        return (jsonNewMessage(AFB_FAIL,"No File within element key=%s\n", item->key));
     }
 
     // This is the 1st Item iteration let's open output file and allocate necessary resources
-    if (postHandle->handle == NULL)  {
+    if (postHandle->ctx == NULL)  {
+        int fd;
+        
         strncpy (filepath, request->config->sessiondir, sizeof(filepath));
         strncat (filepath, "/", sizeof(filepath));
         strncat (filepath, item->filename, sizeof(filepath));  
 
         if((fd = open(request->config->sessiondir, O_RDONLY)) < 0) {
             request->errcode = MHD_HTTP_FORBIDDEN;
-            request->jresp = jsonNewMessage(AFB_FAIL,"Fail to Upload file [%s] at [%s] error=\n", item->filename, request->config->sessiondir, strerror(errno));
-            return AFB_FAIL;
+            return (jsonNewMessage(AFB_FAIL,"Fail to Upload file [%s] at [%s] error=\n", item->filename, request->config->sessiondir, strerror(errno)));
         };            
 
-        // keep track of file handle with item
-        appCtx = malloc (size(appPostCtx)); // May place anything here until post->completeCB handle resources liberation
-        postHandle->handle = malloc (size(appPostCtx)); // May place anything here until post->completeCB handle resources liberation
+        // Create an application specific context
+        appCtx = malloc (sizeof(appPostCtx)); // May place anything here until post->completeCB handle resources liberation
+        appCtx->fd = fd;
         
-        postHandle->completeCB = DonePostForm; // CallBack when Form Processing is finished
+        // attach application to postHandle
+        postHandle->ctx = (void*) appCtx;   // May place anything here until post->completeCB handle resources liberation        
+        postHandle->completeCB = (AFB_apiCB)DonePostForm; // CallBack when Form Processing is finished
         
     } else {
         // this is not the call, FD is already open
-        fd = (int)post->handle;
+        appCtx = (appPostCtx*) postHandle->ctx;
     }
 
     // We have something to write
-    if (item.len > 0) {
+    if (item->len > 0) {
         
-        if (!write (fd, item->data, item->len)) {
+        if (!write (appCtx->fd, item->data, item->len)) {
             request->errcode = MHD_HTTP_FORBIDDEN;
-            request->json = jsonNewMessage(AFB_FAIL,"Fail to write file [%s] at [%s] error=\n", item->filename, strerror(errno));
-            return AFB_FAIL;
+            return (jsonNewMessage(AFB_FAIL,"Fail to write file [%s] at [%s] error=\n", item->filename, strerror(errno)));
         }
     }
   
     // every event should return Sucess or Form processing stop
-    return AFB_SUCCESS;
+    request->errcode = MHD_HTTP_OK;
+    return NULL;
 }
 
 // This function is call when Client Session Context is removed
index cf13a7c..35e81d7 100644 (file)
@@ -53,7 +53,7 @@ PUBLIC json_object* apiPingTest(AFB_request *request) {
     if (len == 0) strncpy (query, "NoSearchQueryList", sizeof(query));
     
     // check if we have some post data
-    if (request->post == NULL)  request->post="NoData"; 
+    if (request->post == NULL)  request->post->data="NoData"; 
     
     // check is we have a session and a plugin handle
     if (client == NULL) strcpy (session,"NoSession");       
@@ -61,7 +61,7 @@ PUBLIC json_object* apiPingTest(AFB_request *request) {
         
     // 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);
+               , pingcount++, request->client->cid, query, session, request->post->data);
     return (response);
 }
 
@@ -92,30 +92,27 @@ PUBLIC int getQueryAll(AFB_request * request, char *buffer, size_t len) {
 }
 
 // Because of POST call multiple time requestApi we need to free POST handle here
-PUBLIC void endPostRequest(AFB_PostHandle *posthandle) {
+PUBLIC void endPostRequest(AFB_PostHandle *postHandle) {
 
-    if (posthandle->type == AFB_POST_JSON) {
-        if (verbose) fprintf(stderr, "End PostJson Request UID=%d\n", posthandle->uid);
+    if (postHandle->type == AFB_POST_JSON) {
+        if (verbose) fprintf(stderr, "End PostJson Request UID=%d\n", postHandle->uid);
     }
 
-    if (posthandle->type == AFB_POST_FORM) {
-        AFB_PostHandle *postform = (AFB_PostHandle*) posthandle->private;
-        if (verbose) fprintf(stderr, "End PostForm Request UID=%d\n", posthandle->uid);
+    if (postHandle->type == AFB_POST_FORM) {
+        AFB_PostHandle *postform = (AFB_PostHandle*) postHandle->private;
+        if (verbose) fprintf(stderr, "End PostForm Request UID=%d\n", postHandle->uid);
 
         // call API termination callback
-        if (!posthandle->private) {
-
-            && !posthandle->private->completeCB) {
-           posthandle->private->completeCB (posthandle->private); 
+        if (!postHandle->private) {
+            if (!postHandle->completeCB) postHandle->completeCB (postHandle->private);
         }
     }
-    freeRequest (posthandle->private);
-    free(posthandle);
-
+    freeRequest (postHandle->private);
+    free(postHandle);
 }
 
 // Check of apiurl is declare in this plugin and call it
-STATIC AFB_error callPluginApi(AFB_plugin *plugin, AFB_request *request) {
+STATIC AFB_error callPluginApi(AFB_plugin *plugin, AFB_request *request, void *context) {
     json_object *jresp, *jcall;
     int idx, status, sig;
     int signals[]= {SIGALRM, SIGSEGV, SIGFPE, 0};
@@ -174,7 +171,7 @@ STATIC AFB_error callPluginApi(AFB_plugin *plugin, AFB_request *request) {
                 ctxClientGet(request, plugin);      
              
                 // Effectively call the API with a subset of the context
-                jresp = plugin->apis[idx].callback(request);
+                jresp = plugin->apis[idx].callback(request, context);
 
                 // Allocate Json object and build response
                 request->jresp  = json_object_new_object();
@@ -206,7 +203,7 @@ STATIC AFB_error callPluginApi(AFB_plugin *plugin, AFB_request *request) {
     return (AFB_FAIL);
 }
 
-STATIC AFB_error findAndCallApi (AFB_request *request, void *extractx) {
+STATIC AFB_error findAndCallApi (AFB_request *request, void *context) {
     int idx;
     char *baseurl, *baseapi;
     AFB_error status;
@@ -214,7 +211,7 @@ STATIC AFB_error findAndCallApi (AFB_request *request, void *extractx) {
     // Search for a plugin with this urlpath
     for (idx = 0; request->plugins[idx] != NULL; idx++) {
         if (!strcmp(request->plugins[idx]->prefix, baseurl)) {
-            status =callPluginApi(request->plugins[idx], request, extractx);
+            status =callPluginApi(request->plugins[idx], request, context);
             break;
         }
     }
@@ -242,16 +239,16 @@ ExitOnError:
 // and callback Plugin API for each Item within PostForm.
 doPostIterate (void *cls, enum MHD_ValueKind kind, const char *key,
               const char *filename, const char *mimetype,
-              const char *encoding, const char *data, uint64_t off,
+              const char *encoding, const char *data, uint64_t offset,
               size_t size) {
   
   AFB_error    status;
-  AFB_HttpItem item;
+  AFB_PostItem item;
     
   // retrieve API request from Post iterator handle  
-  AFB_PostHandle *postctx  = (AFB_PostHandle*)cls;
-  AFB_request *request = (AFB_request*)post->private;
-  AFB_PostRequest post;
+  AFB_PostHandle *postHandle  = (AFB_PostHandle*)cls;
+  AFB_request *request = (AFB_request*)postHandle->private;
+  AFB_PostRequest postRequest;
   
    
   // Create and Item value for Plugin API
@@ -262,7 +259,7 @@ doPostIterate (void *cls, enum MHD_ValueKind kind, const char *key,
   item.encoding = encoding;
   item.len      = size;
   item.data     = data;
-  item.off      = off;
+  item.offset   = offset;
   
   // Reformat Request to make it somehow similar to GET/PostJson case
   post.data= (char*) postctx;
@@ -330,14 +327,14 @@ PUBLIC int doRestApi(struct MHD_Connection *connection, AFB_session *session, co
     struct MHD_Response *webResponse;
     const char *serialized;
     AFB_request request;
-    AFB_PostHandle *posthandle = *con_cls;
+    AFB_PostHandle *posthandle;
     int ret;
   
     // if post data may come in multiple calls
     if (0 == strcmp(method, MHD_HTTP_METHOD_POST)) {
         const char *encoding, *param;
         int contentlen = -1;
-        AFB_PostHandle *posthandle = *con_cls;
+        posthandle = *con_cls;
 
         // This is the initial post event let's create form post structure POST datas come in multiple events
         if (posthandle == NULL) {