summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFulup Ar Foll <fulup@iot.bzh>2015-12-15 18:39:45 +0100
committerFulup Ar Foll <fulup@iot.bzh>2015-12-15 18:39:45 +0100
commit1250a56369315c017abfe429c556b863730b9b44 (patch)
tree979cd438bbaf7360336714501caa3c8001e24971
parenta644a48c2dfdc4ba5129aa3b85a21aadc429f65d (diff)
Post En court Ne fonctionne pas
-rw-r--r--include/local-def.h14
-rw-r--r--nbproject/configurations.xml16
-rw-r--r--src/afbs-api.c59
-rw-r--r--src/rest-api.c51
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) {