diff options
-rw-r--r-- | include/local-def.h | 14 | ||||
-rw-r--r-- | nbproject/configurations.xml | 16 | ||||
-rw-r--r-- | src/afbs-api.c | 59 | ||||
-rw-r--r-- | src/rest-api.c | 51 |
4 files changed, 69 insertions, 71 deletions
diff --git a/include/local-def.h b/include/local-def.h index 47513e68..021ef13e 100644 --- a/include/local-def.h +++ b/include/local-def.h @@ -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 { diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 2435ae96..b1f18a07 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -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> @@ -105,22 +103,12 @@ </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"> diff --git a/src/afbs-api.c b/src/afbs-api.c index ae6ec639..1a3399f9 100644 --- a/src/afbs-api.c +++ b/src/afbs-api.c @@ -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 diff --git a/src/rest-api.c b/src/rest-api.c index cf13a7c9..35e81d7e 100644 --- a/src/rest-api.c +++ b/src/rest-api.c @@ -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) { |