From fc19b7d7974f9c64dffc40e180464d595a9805cd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Thu, 7 Apr 2016 00:05:11 +0200 Subject: [PATCH] improves file handling MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I285cb6333d939a8afed07d8388d1d7850e50fe28 Signed-off-by: José Bollo --- include/afb-req-itf.h | 6 +-- plugins/afm-main-plugin/afm-main-plugin.c | 4 +- plugins/samples/HelloWorld.c | 51 ++++++------------- plugins/samples/SamplePost.c | 2 +- src/afb-hreq.c | 85 ++++++++++++------------------- src/afb-hreq.h | 4 -- src/afb-hsrv.c | 1 - src/afb-websock.c | 4 +- 8 files changed, 57 insertions(+), 100 deletions(-) diff --git a/include/afb-req-itf.h b/include/afb-req-itf.h index 8d869a6f..9ced7630 100644 --- a/include/afb-req-itf.h +++ b/include/afb-req-itf.h @@ -20,8 +20,8 @@ struct json_object; struct afb_arg { const char *name; const char *value; + const char *path; size_t size; - int is_file; }; struct afb_req_itf { @@ -50,9 +50,9 @@ static inline const char *afb_req_argument(struct afb_req req, const char *name) return afb_req_get(req, name).value; } -static inline int afb_req_is_argument_file(struct afb_req req, const char *name) +static inline const char *afb_req_path(struct afb_req req, const char *name) { - return afb_req_get(req, name).is_file; + return afb_req_get(req, name).path; } static inline void afb_req_iterate(struct afb_req req, int (*iterator)(void *closure, struct afb_arg arg), void *closure) diff --git a/plugins/afm-main-plugin/afm-main-plugin.c b/plugins/afm-main-plugin/afm-main-plugin.c index d86e9263..a23b1971 100644 --- a/plugins/afm-main-plugin/afm-main-plugin.c +++ b/plugins/afm-main-plugin/afm-main-plugin.c @@ -221,8 +221,8 @@ static void install(struct afb_req request) /* get the argument */ arg = afb_req_get(request, "widget"); - filename = arg.value; - if (filename == NULL || !arg.is_file) { + filename = arg.path; + if (filename == NULL) { afb_req_fail(request, "bad-request", "missing 'widget' file"); return; } diff --git a/plugins/samples/HelloWorld.c b/plugins/samples/HelloWorld.c index 72ad0b34..fd780e20 100644 --- a/plugins/samples/HelloWorld.c +++ b/plugins/samples/HelloWorld.c @@ -23,47 +23,28 @@ #include "afb-plugin.h" #include "afb-req-itf.h" -typedef struct queryHandleT { - char *msg; - size_t idx; - size_t len; -} queryHandleT; - -static int getQueryCB (queryHandleT *query, struct afb_arg arg) { - if (query->idx >= query->len) - return 0; - query->idx += (unsigned)snprintf (&query->msg[query->idx], query->len-query->idx, " %s: %s\'%s\',", arg.name, arg.is_file?"FILE=":"", arg.value); - return 1; /* continue to iterate */ -} +static int fillargs(json_object *args, struct afb_arg arg) +{ + json_object *obj; -// Helper to retrieve argument from connection -static size_t getQueryAll(struct afb_req 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; - - afb_req_iterate(request, (void*)getQueryCB, &query); - buffer[len-1] = 0; - return query.idx >= len ? len - 1 : query.idx; + obj = json_object_new_object(); + json_object_object_add (obj, "value", json_object_new_string(arg.value)); + json_object_object_add (obj, "path", json_object_new_string(arg.path)); + json_object_object_add (obj, "size", json_object_new_int64((int64_t)arg.size)); + json_object_object_add (args, arg.name && *arg.name ? arg.name : "", obj); + return 1; /* continue to iterate */ } -static void ping (struct afb_req request, json_object *jresp) +// Sample Generic Ping Debug API +static void ping(struct afb_req request, json_object *jresp) { static int pingcount = 0; - char query [512]; - size_t len; + json_object *query; - // request all query key/value - len = getQueryAll (request, query, sizeof(query)); - if (len == 0) strcpy (query,"NoSearchQueryList"); - - // return response to caller -// response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon %d query={%s}", pingcount++, query); - afb_req_success_f(request, jresp, "Ping Binder Daemon %d query={%s}", pingcount++, query); - - fprintf(stderr, "%d: \n", pingcount); + query = json_object_new_object(); + afb_req_iterate(request, (void*)fillargs, query); + + afb_req_success_f(request, jresp, "Ping Binder Daemon count=%d query=%s", ++pingcount, json_object_to_json_string(query)); } static void pingSample (struct afb_req request) diff --git a/plugins/samples/SamplePost.c b/plugins/samples/SamplePost.c index aab54e91..58a2a8b8 100644 --- a/plugins/samples/SamplePost.c +++ b/plugins/samples/SamplePost.c @@ -31,8 +31,8 @@ static int fillargs(json_object *args, struct afb_arg arg) obj = json_object_new_object(); json_object_object_add (obj, "value", json_object_new_string(arg.value)); + json_object_object_add (obj, "path", json_object_new_string(arg.path)); json_object_object_add (obj, "size", json_object_new_int64((int64_t)arg.size)); - json_object_object_add (obj, "is_file", json_object_new_boolean(arg.is_file)); json_object_object_add (args, arg.name && *arg.name ? arg.name : "", obj); return 1; /* continue to iterate */ } diff --git a/src/afb-hreq.c b/src/afb-hreq.c index 7c481e95..aff204d9 100644 --- a/src/afb-hreq.c +++ b/src/afb-hreq.c @@ -55,9 +55,9 @@ static const char token_cookie[] = "token"; struct hreq_data { struct hreq_data *next; char *key; - int file; size_t length; char *value; + char *path; }; static struct afb_arg req_get(struct afb_hreq *hreq, const char *name); @@ -415,23 +415,11 @@ const char *afb_hreq_get_header(struct afb_hreq *hreq, const char *name) return MHD_lookup_connection_value(hreq->connection, MHD_HEADER_KIND, name); } -void afb_hreq_post_end(struct afb_hreq *hreq) -{ - struct hreq_data *data = hreq->data; - while(data) { - if (data->file > 0) { - close(data->file); - data->file = -1; - } - data = data->next; - } -} - int afb_hreq_post_add(struct afb_hreq *hreq, const char *key, const char *data, size_t size) { void *p; struct hreq_data *hdat = get_data(hreq, key, 1); - if (hdat->file) { + if (hdat->path != NULL) { return 0; } p = realloc(hdat->value, hdat->length + size + 1); @@ -445,59 +433,52 @@ int afb_hreq_post_add(struct afb_hreq *hreq, const char *key, const char *data, return 1; } +static int opentempfile(char **path) +{ + int fd; + char *fname; + + fname = strdup("XXXXXX"); + if (fname == NULL) + return -1; + + fd = mkostemp(fname, O_CLOEXEC); + if (fd < 0) + free(fname); + return fd; +} + int afb_hreq_post_add_file(struct afb_hreq *hreq, const char *key, const char *file, const char *data, size_t size) { + int fd; ssize_t sz; struct hreq_data *hdat = get_data(hreq, key, 1); if (hdat->value == NULL) { - hdat->file = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); - if (hdat->file == 0) { - hdat->file = dup(0); - close(0); - } - if (hdat->file <= 0) { - hdat->file = 0; - return 0; - } hdat->value = strdup(file); - if (hdat->value == NULL) { - close(hdat->file); - hdat->file = 0; + if (hdat->value == NULL) return 0; - } + fd = opentempfile(&hdat->path); + } else if (strcmp(hdat->value, file) || hdat->path == NULL) { + return 0; } else { - if (strcmp(hdat->value, file)) - return 0; - } - if (hdat->file < 0) { - hdat->file = open(hdat->value, O_WRONLY|O_APPEND); - if (hdat->file == 0) { - hdat->file = dup(0); - close(0); - } - if (hdat->file <= 0) - return 0; + fd = open(hdat->path, O_WRONLY|O_APPEND); } + if (fd < 0) + return 0; while (size) { - sz = write(hdat->file, data, size); + sz = write(fd, data, size); if (sz >= 0) { hdat->length += (size_t)sz; size -= (size_t)sz; data += sz; } else if (errno != EINTR) - return 0; + break; } - return 1; + close(fd); + return !size; } -int afb_hreq_is_argument_a_file(struct afb_hreq *hreq, const char *key) -{ - struct hreq_data *hdat = get_data(hreq, key, 0); - return hdat != NULL && hdat->file != 0; -} - - struct afb_req afb_hreq_to_req(struct afb_hreq *hreq) { return (struct afb_req){ .itf = &afb_hreq_itf, .data = hreq }; @@ -511,14 +492,14 @@ static struct afb_arg req_get(struct afb_hreq *hreq, const char *name) .name = hdat->key, .value = hdat->value, .size = hdat->length, - .is_file = (hdat->file != 0) + .path = hdat->path }; return (struct afb_arg){ .name = name, .value = MHD_lookup_connection_value(hreq->connection, MHD_GET_ARGUMENT_KIND, name), .size = 0, - .is_file = 0 + .path = NULL }; } @@ -537,7 +518,7 @@ static int _iterargs_(struct iterdata *id, enum MHD_ValueKind kind, const char * .name = key, .value = value, .size = 0, - .is_file = 0 + .path = NULL }); } @@ -550,7 +531,7 @@ static void req_iterate(struct afb_hreq *hreq, int (*iterator)(void *closure, st .name = hdat->key, .value = hdat->value, .size = hdat->length, - .is_file = (hdat->file != 0)})) + .path = hdat->path})) return; hdat = hdat->next; } diff --git a/src/afb-hreq.h b/src/afb-hreq.h index 853190a8..c317a7a5 100644 --- a/src/afb-hreq.h +++ b/src/afb-hreq.h @@ -53,14 +53,10 @@ extern const char *afb_hreq_get_header(struct afb_hreq *hreq, const char *name); extern const char *afb_hreq_get_argument(struct afb_hreq *hreq, const char *name); -extern int afb_hreq_is_argument_a_file(struct afb_hreq *hreq, const char *name); - extern int afb_hreq_post_add_file(struct afb_hreq *hreq, const char *name, const char *file, const char *data, size_t size); extern int afb_hreq_post_add(struct afb_hreq *hreq, const char *name, const char *data, size_t size); -extern void afb_hreq_post_end(struct afb_hreq *hreq); - extern struct afb_req afb_hreq_to_req(struct afb_hreq *hreq); extern struct AFB_clientCtx *afb_hreq_context(struct afb_hreq *hreq); diff --git a/src/afb-hsrv.c b/src/afb-hsrv.c index afe865f7..334b8b3b 100644 --- a/src/afb-hsrv.c +++ b/src/afb-hsrv.c @@ -331,7 +331,6 @@ static int access_handler( } /* flush the data */ - afb_hreq_post_end(hreq); if (hreq->postform != NULL) { rc = MHD_destroy_post_processor(hreq->postform); hreq->postform = NULL; diff --git a/src/afb-websock.c b/src/afb-websock.c index cff995f2..1292d1f1 100644 --- a/src/afb-websock.c +++ b/src/afb-websock.c @@ -421,7 +421,7 @@ static struct afb_arg wsreq_get(struct afb_wsreq *wsreq, const char *name) arg.value = NULL; } arg.size = 0; - arg.is_file = 0; + arg.path = NULL; return arg; } @@ -432,7 +432,7 @@ static void wsreq_iterate(struct afb_wsreq *wsreq, int (*iterator)(void *closure struct json_object_iterator end = json_object_iter_end(wsreq->request); arg.size = 0; - arg.is_file = 0; + arg.path = NULL; while(!json_object_iter_equal(&it, &end)) { arg.name = json_object_iter_peek_name(&it); arg.value = json_object_get_string(json_object_iter_peek_value(&it)); -- 2.16.6