From 20f5ff02e455580c6e7129479f3328787b3333ff Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Wed, 30 Mar 2016 19:22:34 +0200 Subject: [PATCH] refactoring (in progress, tbf) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I7461983aa3177f8ae54ca72761d916e646888fca Signed-off-by: José Bollo --- include/proto-def.h | 4 - src/afb-hreq.c | 97 ++++++++++++++++++++++- src/afb-hreq.h | 23 +++--- src/afb-rest-api.c | 81 ++++++++++--------- src/afb-websock.c | 1 - src/helper-api.c | 29 +------ src/http-svc.c | 222 +++++++++++++++++++++++++++++++++------------------- 7 files changed, 286 insertions(+), 171 deletions(-) diff --git a/include/proto-def.h b/include/proto-def.h index 21e03035..0db8abb1 100644 --- a/include/proto-def.h +++ b/include/proto-def.h @@ -28,10 +28,6 @@ extern AFB_PostCtx* getPostContext (AFB_request *request); extern char* getPostPath (AFB_request *request); extern json_object *jsonNewMessage (AFB_error level, char* format, ...); -extern json_object *jsonNewStatus (AFB_error level); -extern json_object *jsonNewjtype (void); -extern json_object *jsonNewMessage (AFB_error level, char* format, ...); -extern void jsonDumpObject (json_object * jObject); // rest-api extern void endPostRequest(AFB_PostHandle *posthandle); diff --git a/src/afb-hreq.c b/src/afb-hreq.c index f7f3bb15..bc42bf12 100644 --- a/src/afb-hreq.c +++ b/src/afb-hreq.c @@ -26,8 +26,42 @@ #include "afb-req-itf.h" #include "afb-hreq.h" -static char empty_string[1] = ""; +static char empty_string[] = ""; +struct hreq_data { + struct hreq_data *next; + char *key; + int file; + size_t length; + char *value; +}; + + +static struct hreq_data *get_data(struct afb_hreq *hreq, const char *key, int create) +{ + struct hreq_data *data = hreq->data; + if (key == NULL) + key = empty_string; + while (data != NULL) { + if (!strcasecmp(data->key, key)) + return data; + data = data->next; + } + if (create) { + data = calloc(1, sizeof *data); + if (data != NULL) { + data->key = strdup(key); + if (data->key == NULL) { + free(data); + data = NULL; + } else { + data->next = hreq->data; + hreq->data = data; + } + } + } + return data; +} /* a valid subpath is a relative path not looking deeper than root using .. */ static int validsubpath(const char *subpath) @@ -237,7 +271,8 @@ const char *afb_hreq_get_cookie(struct afb_hreq *hreq, const char *name) const char *afb_hreq_get_argument(struct afb_hreq *hreq, const char *name) { - return MHD_lookup_connection_value(hreq->connection, MHD_GET_ARGUMENT_KIND, name); + struct hreq_data *data = get_data(hreq, name, 0); + return data ? data->value : MHD_lookup_connection_value(hreq->connection, MHD_GET_ARGUMENT_KIND, name); } const char *afb_hreq_get_header(struct afb_hreq *hreq, const char *name) @@ -245,8 +280,64 @@ const char *afb_hreq_get_header(struct afb_hreq *hreq, const char *name) return MHD_lookup_connection_value(hreq->connection, MHD_HEADER_KIND, name); } -struct afb_req_itf afb_hreq_itf = { +const struct afb_req_itf afb_hreq_itf = { .get_cookie = (void*)afb_hreq_get_cookie, .get_argument = (void*)afb_hreq_get_argument }; + +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) { + return 0; + } + p = realloc(hdat->value, hdat->length + size + 1); + if (p == NULL) { + return 0; + } + hdat->value = p; + memcpy(&hdat->value[hdat->length], data, size); + hdat->length += size; + hdat->value[hdat->length] = 0; + return 1; +} + +int afb_hreq_post_add_file(struct afb_hreq *hreq, const char *key, const char *file, const char *data, size_t size) +{ + struct hreq_data *hdat = get_data(hreq, key, 1); + + /* continuation with reopening */ + 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; + } + if (hdat->file > 0) { + write(hdat->file, data, size); + return 1; + } + + /* creation */ + /* TODO */ + return 0; + +} + diff --git a/src/afb-hreq.h b/src/afb-hreq.h index b5f1e0b2..7e774276 100644 --- a/src/afb-hreq.h +++ b/src/afb-hreq.h @@ -16,14 +16,6 @@ */ -struct afb_req_itf; - - -struct afb_hreq_post { - const char *upload_data; - size_t *upload_data_size; -}; - struct afb_hreq { AFB_session *session; struct MHD_Connection *connection; @@ -33,10 +25,8 @@ struct afb_hreq { size_t lenurl; const char *tail; size_t lentail; - struct afb_hreq **recorder; - int (*post_handler) (struct afb_hreq *, struct afb_hreq_post *); - int (*post_completed) (struct afb_hreq *, struct afb_hreq_post *); - void *post_data; + struct MHD_PostProcessor *postform; + void *data; }; extern int afb_hreq_unprefix(struct afb_hreq *request, const char *prefix, size_t length); @@ -57,5 +47,12 @@ extern const char *afb_hreq_get_argument(struct afb_hreq *hreq, const char *name extern const char *afb_hreq_get_header(struct afb_hreq *hreq, const char *name); -extern struct afb_req_itf afb_hreq_itf; +extern int afb_hreq_post_add_file(struct afb_hreq *hreq, const char *key, const char *file, const char *data, size_t size); + +extern int afb_hreq_post_add(struct afb_hreq *hreq, const char *key, const char *data, size_t size); + +extern void afb_hreq_post_end(struct afb_hreq *hreq); + +struct afb_req_itf; +extern const struct afb_req_itf afb_hreq_itf; diff --git a/src/afb-rest-api.c b/src/afb-rest-api.c index 2b47794e..49e5d8b2 100644 --- a/src/afb-rest-api.c +++ b/src/afb-rest-api.c @@ -36,7 +36,7 @@ #define AFB_MSG_JTYPE "AJB_reply" #define JSON_CONTENT "application/json" -#define FORM_CONTENT "multipart/form-data" /* TODO: replace with MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA */ +#define FORM_CONTENT MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA static json_object *afbJsonType; @@ -67,8 +67,7 @@ static AFB_error doCallPluginApi(AFB_request * request, int apiidx, int verbidx, // Request was found and at least partially executed jreqt = json_object_new_object(); - json_object_get(afbJsonType); // increate jsontype reference count - json_object_object_add(jreqt, "jtype", afbJsonType); + json_object_object_add(jreqt, "jtype", json_object_get(afbJsonType)); // prepare an object to store calling values jcall = json_object_new_object(); @@ -157,6 +156,7 @@ static AFB_error doCallPluginApi(AFB_request * request, int apiidx, int verbidx, break; } } + // Effectively CALL PLUGIN API with a subset of the context jresp = afb_apis_get(apiidx, verbidx)->callback(request, context); @@ -193,7 +193,7 @@ ExitOnDone: extern __thread sigjmp_buf *error_handler; static AFB_error callPluginApi(AFB_request * request, int apiidx, int verbidx, void *context) { - sigjmp_buf jmpbuf; + sigjmp_buf jmpbuf, *older; json_object *jcall, *jreqt; int status; @@ -204,8 +204,7 @@ static AFB_error callPluginApi(AFB_request * request, int apiidx, int verbidx, v // Request was found and at least partially executed jreqt = json_object_new_object(); - json_object_get(afbJsonType); // increate jsontype reference count - json_object_object_add(jreqt, "jtype", afbJsonType); + json_object_object_add(jreqt, "jtype", json_object_get(afbJsonType)); // prepare an object to store calling values jcall = json_object_new_object(); @@ -217,23 +216,20 @@ static AFB_error callPluginApi(AFB_request * request, int apiidx, int verbidx, v json_object_object_add(jcall, "info", json_object_new_string("Plugin broke during execution")); json_object_object_add(jreqt, "request", jcall); request->jresp = jreqt; - goto ExitOnDone; - } else { // Trigger a timer to protect from unacceptable long time execution if (request->config->apiTimeout > 0) alarm((unsigned)request->config->apiTimeout); + older = error_handler; error_handler = &jmpbuf; doCallPluginApi(request, apiidx, verbidx, context); - error_handler = NULL; + error_handler = older; // cancel timeout and plugin signal handle before next call alarm(0); } - -ExitOnDone: return AFB_DONE; } @@ -411,6 +407,7 @@ static int doRestApiPost(struct MHD_Connection *connection, AFB_session * sessio postHandle->type = AFB_POST_EMPTY; return MHD_YES; } + // Form post is handle through a PostProcessor and call API once per form key if (strcasestr(encoding, FORM_CONTENT) != NULL) { if (verbose) @@ -449,11 +446,10 @@ static int doRestApiPost(struct MHD_Connection *connection, AFB_session * sessio // if (verbose) fprintf(stderr, "Create PostJson[uid=%d] Size=%d\n", postHandle->uid, contentlen); return MHD_YES; - } else { - // We only support Json and Form Post format - errMessage = jsonNewMessage(AFB_FATAL, "Post Date wrong type encoding=%s != %s", encoding, JSON_CONTENT); - goto ExitOnError; } + // We only support Json and Form Post format + errMessage = jsonNewMessage(AFB_FATAL, "Post Date wrong type encoding=%s != %s", encoding, JSON_CONTENT); + goto ExitOnError; } // This time we receive partial/all Post data. Note that even if we get all POST data. We should nevertheless @@ -475,41 +471,44 @@ static int doRestApiPost(struct MHD_Connection *connection, AFB_session * sessio *upload_data_size = 0; return MHD_YES; - } else { // we have finish with Post reception let's finish the work + } + if (postHandle->type == AFB_POST_FORM) + request = postHandle->privatebuf; + else // Create a request structure to finalise the request request = createRequest(connection, session, url); - if (request->jresp != NULL) { - errMessage = request->jresp; - goto ExitOnError; - } - postRequest.type = postHandle->type; - // Postform add application context handle to request - if (postHandle->type == AFB_POST_FORM) { - postRequest.data = (char *)postHandle; - request->post = &postRequest; - } + if (request->jresp != NULL) { + errMessage = request->jresp; + goto ExitOnError; + } + postRequest.type = postHandle->type; - if (postHandle->type == AFB_POST_JSON) { - // if (verbose) fprintf(stderr, "Processing PostJson[uid=%d]\n", postHandle->uid); + // Postform add application context handle to request + if (postHandle->type == AFB_POST_FORM) { + postRequest.data = (char *)postHandle; + request->post = &postRequest; + } - param = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_CONTENT_LENGTH); - if (param) - sscanf(param, "%i", &contentlen); + if (postHandle->type == AFB_POST_JSON) { + // if (verbose) fprintf(stderr, "Processing PostJson[uid=%d]\n", postHandle->uid); - // At this level we're may verify that we got everything and process DATA - if (postHandle->len != contentlen) { - errMessage = jsonNewMessage(AFB_FATAL, "Post Data Incomplete UID=%d Len %d != %d", postHandle->uid, contentlen, postHandle->len); - goto ExitOnError; - } - // Before processing data, make sure buffer string is properly ended - postHandle->privatebuf[postHandle->len] = '\0'; - postRequest.data = postHandle->privatebuf; - request->post = &postRequest; + param = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_CONTENT_LENGTH); + if (param) + sscanf(param, "%i", &contentlen); - // if (verbose) fprintf(stderr, "Close Post[%d] Buffer=%s\n", postHandle->uid, request->post->data); + // At this level we're may verify that we got everything and process DATA + if (postHandle->len != contentlen) { + errMessage = jsonNewMessage(AFB_FATAL, "Post Data Incomplete UID=%d Len %d != %d", postHandle->uid, contentlen, postHandle->len); + goto ExitOnError; } + // Before processing data, make sure buffer string is properly ended + postHandle->privatebuf[postHandle->len] = '\0'; + postRequest.data = postHandle->privatebuf; + request->post = &postRequest; + + // if (verbose) fprintf(stderr, "Close Post[%d] Buffer=%s\n", postHandle->uid, request->post->data); } ProcessApiCall: diff --git a/src/afb-websock.c b/src/afb-websock.c index 1c087e25..b6044326 100644 --- a/src/afb-websock.c +++ b/src/afb-websock.c @@ -136,7 +136,6 @@ static int headerhas(const char *header, const char *needle) if (!*header) return 0; len = strcspn(header, sep); -printf("!!!%.*s!!!\n",len,header); if (n == len && 0 == strncasecmp(needle, header, n)) return 1; header += len; diff --git a/src/helper-api.c b/src/helper-api.c index 912093bb..303fd57d 100644 --- a/src/helper-api.c +++ b/src/helper-api.c @@ -234,25 +234,6 @@ static void jsoninit() } - -// get JSON object from error level and increase its reference count -struct json_object *jsonNewStatus (AFB_error level) -{ - jsoninit(); - json_object *target = AFBerr[level].json; - json_object_get (target); - - return (target); -} - -// get AFB object type with adequate usage count -struct json_object *jsonNewjtype (void) -{ - jsoninit(); - json_object_get (jTypeStatic); // increase reference count - return (jTypeStatic); -} - // build an ERROR message and return it as a valid json object struct json_object *jsonNewMessage (AFB_error level, char* format, ...) { static int count = 0; @@ -270,7 +251,7 @@ struct json_object *jsonNewMessage (AFB_error level, char* format, ...) { } AFBResponse = json_object_new_object(); - json_object_object_add (AFBResponse, "jtype", jsonNewjtype ()); + json_object_object_add (AFBResponse, "jtype", json_object_get (jTypeStatic)); json_object_object_add (AFBResponse, "status" , json_object_new_string (ERROR_LABEL[level])); if (format != NULL) { json_object_object_add (AFBResponse, "info" , json_object_new_string (message)); @@ -288,11 +269,3 @@ struct json_object *jsonNewMessage (AFB_error level, char* format, ...) { return (AFBResponse); } -// Dump a message on stderr -void jsonDumpObject (struct json_object * jObject) { - - if (verbose) { - fprintf (stderr, "AFB:dump [%s]\n", json_object_to_json_string(jObject)); - } -} - diff --git a/src/http-svc.c b/src/http-svc.c index f281bbf9..e8ccfe83 100644 --- a/src/http-svc.c +++ b/src/http-svc.c @@ -26,12 +26,14 @@ #include "afb-hreq.h" #include "afb-websock.h" +#define JSON_CONTENT "application/json" +#define FORM_CONTENT MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA struct afb_hsrv_handler { struct afb_hsrv_handler *next; const char *prefix; size_t length; - int (*handler) (struct afb_hreq *, struct afb_hreq_post *, void *); + int (*handler) (struct afb_hreq *, void *); void *data; int priority; }; @@ -45,7 +47,6 @@ struct afb_diralias { int afb_hreq_one_page_api_redirect( struct afb_hreq *hreq, - struct afb_hreq_post *post, void *data) { size_t plen; @@ -71,10 +72,10 @@ int afb_hreq_one_page_api_redirect( return afb_hreq_redirect_to(hreq, url); } -struct afb_hsrv_handler *afb_hsrv_handler_new( +static struct afb_hsrv_handler *new_handler( struct afb_hsrv_handler *head, const char *prefix, - int (*handler) (struct afb_hreq *, struct afb_hreq_post *, void *), + int (*handler) (struct afb_hreq *, void *), void *data, int priority) { @@ -112,37 +113,40 @@ struct afb_hsrv_handler *afb_hsrv_handler_new( return head; } -int afb_req_add_handler( +int afb_hsrv_add_handler( AFB_session * session, const char *prefix, - int (*handler) (struct afb_hreq *, struct afb_hreq_post *, void *), + int (*handler) (struct afb_hreq *, void *), void *data, int priority) { struct afb_hsrv_handler *head; - head = afb_hsrv_handler_new(session->handlers, prefix, handler, data, priority); + head = new_handler(session->handlers, prefix, handler, data, priority); if (head == NULL) return 0; session->handlers = head; return 1; } -static int relay_to_doRestApi(struct afb_hreq *hreq, struct afb_hreq_post *post, void *data) +static int relay_to_doRestApi(struct afb_hreq *hreq, void *data) { int later; - if (afb_websock_check(hreq, &later)) { + if (hreq->lentail == 0 && afb_websock_check(hreq, &later)) { if (!later) { struct afb_websock *ws = afb_websock_create(hreq->connection); } return 1; } +return 0; +/* return doRestApi(hreq->connection, hreq->session, &hreq->tail[1], get_method_name(hreq->method), post->upload_data, post->upload_data_size, (void **)hreq->recorder); +*/ } -static int handle_alias(struct afb_hreq *hreq, struct afb_hreq_post *post, void *data) +static int handle_alias(struct afb_hreq *hreq, void *data) { struct afb_diralias *da = data; @@ -159,7 +163,7 @@ static int handle_alias(struct afb_hreq *hreq, struct afb_hreq_post *post, void return afb_hreq_reply_file(hreq, da->dirfd, &hreq->tail[1]); } -int afb_req_add_alias(AFB_session * session, const char *prefix, const char *alias, int priority) +int afb_hsrv_add_alias(AFB_session * session, const char *prefix, const char *alias, int priority) { struct afb_diralias *da; int dirfd; @@ -175,7 +179,7 @@ int afb_req_add_alias(AFB_session * session, const char *prefix, const char *ali da->directory = alias; da->lendir = strlen(da->directory); da->dirfd = dirfd; - if (afb_req_add_handler(session, prefix, handle_alias, da, priority)) + if (afb_hsrv_add_handler(session, prefix, handle_alias, da, priority)) return 1; free(da); } @@ -183,25 +187,39 @@ int afb_req_add_alias(AFB_session * session, const char *prefix, const char *ali return 0; } -static int my_default_init(AFB_session * session) +void afb_hsrv_reply_error(struct MHD_Connection *connection, unsigned int status) { - int idx; - - if (!afb_req_add_handler(session, session->config->rootapi, relay_to_doRestApi, NULL, 1)) - return 0; - - for (idx = 0; session->config->aliasdir[idx].url != NULL; idx++) - if (!afb_req_add_alias - (session, session->config->aliasdir[idx].url, session->config->aliasdir[idx].path, 0)) - return 0; - - if (!afb_req_add_alias(session, "", session->config->rootdir, -10)) - return 0; - - if (!afb_req_add_handler(session, session->config->rootbase, afb_hreq_one_page_api_redirect, NULL, -20)) - return 0; + char *buffer; + int length; + struct MHD_Response *response; + + length = asprintf(&buffer, "error %u", status); + if (length > 0) + response = MHD_create_response_from_buffer((unsigned)length, buffer, MHD_RESPMEM_MUST_FREE); + else { + buffer = "error"; + response = MHD_create_response_from_buffer(strlen(buffer), buffer, MHD_RESPMEM_PERSISTENT); + } + if (!MHD_queue_response(connection, status, response)) + fprintf(stderr, "Failed to reply error code %u", status); + MHD_destroy_response(response); +} - return 1; +static int postproc(void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size) +{ + struct afb_hreq *hreq = cls; + if (filename != NULL) + return afb_hreq_post_add_file(hreq, key, filename, data, size); + else + return afb_hreq_post_add(hreq, key, data, size); } static int access_handler( @@ -211,83 +229,108 @@ static int access_handler( const char *methodstr, const char *version, const char *upload_data, - size_t * upload_data_size, - void **recorder) + size_t *upload_data_size, + void **recordreq) { - struct afb_hreq_post post; - struct afb_hreq hreq; + struct afb_hreq *hreq; enum afb_method method; AFB_session *session; struct afb_hsrv_handler *iter; + const char *type; session = cls; - post.upload_data = upload_data; - post.upload_data_size = upload_data_size; - -#if 0 - struct afb_hreq *previous; - - previous = *recorder; - if (previous) { - assert((void **)previous->recorder == recorder); - assert(previous->session == session); - assert(previous->connection == connection); - assert(previous->method == get_method(methodstr)); - assert(previous->url == url); + hreq = *recordreq; + if (hreq == NULL) { + /* create the request */ + hreq = calloc(1, sizeof *hreq); + if (hreq == NULL) + goto internal_error; + *recordreq = hreq; + + /* get the method */ + method = get_method(methodstr); + method &= afb_method_get | afb_method_post; + if (method == afb_method_none) { + afb_hsrv_reply_error(connection, MHD_HTTP_BAD_REQUEST); + return MHD_YES; + } - /* TODO */ -/* - assert(previous->post_handler != NULL); - previous->post_handler(previous, &post); - return MHD_NO; -*/ + /* init the request */ + hreq->session = cls; + hreq->connection = connection; + hreq->method = method; + hreq->version = version; + hreq->tail = hreq->url = url; + hreq->lentail = hreq->lenurl = strlen(url); + + /* init the post processing */ + if (method == afb_method_post) { + type = afb_hreq_get_header(hreq, MHD_HTTP_HEADER_CONTENT_TYPE); + if (type == NULL) { + /* an empty post, let's process it as a get */ + hreq->method = afb_method_get; + } else if (strcasestr(type, FORM_CONTENT) != NULL) { + hreq->postform = MHD_create_post_processor (connection, 65500, postproc, hreq); + if (hreq->postform == NULL) + goto internal_error; + } else if (strcasestr(type, JSON_CONTENT) == NULL) { + afb_hsrv_reply_error(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE); + return MHD_YES; + } + } } -#endif - method = get_method(methodstr); - if (method == afb_method_none) { - afb_hreq_reply_error(&hreq, MHD_HTTP_BAD_REQUEST); - return MHD_YES; + /* process further data */ + if (*upload_data_size) { + if (hreq->postform != NULL) { + if (!MHD_post_process (hreq->postform, upload_data, *upload_data_size)) + goto internal_error; + } else { + if (!afb_hreq_post_add(hreq, NULL, upload_data, *upload_data_size)) + goto internal_error; + } + *upload_data_size = 0; + return MHD_YES; } - /* init the request */ - hreq.session = cls; - hreq.connection = connection; - hreq.method = method; - hreq.version = version; - hreq.tail = hreq.url = url; - hreq.lentail = hreq.lenurl = strlen(url); - hreq.recorder = (struct afb_hreq **)recorder; - hreq.post_handler = NULL; - hreq.post_completed = NULL; - hreq.post_data = NULL; + /* flush the data */ + afb_hreq_post_end(hreq); /* search an handler for the request */ iter = session->handlers; while (iter) { - if (afb_hreq_unprefix(&hreq, iter->prefix, iter->length)) { - if (iter->handler(&hreq, &post, iter->data)) + if (afb_hreq_unprefix(hreq, iter->prefix, iter->length)) { + if (iter->handler(hreq, iter->data)) return MHD_YES; - hreq.tail = hreq.url; - hreq.lentail = hreq.lenurl; + hreq->tail = hreq->url; + hreq->lentail = hreq->lenurl; } iter = iter->next; } /* no handler */ - afb_hreq_reply_error(&hreq, method != afb_method_get ? MHD_HTTP_BAD_REQUEST : MHD_HTTP_NOT_FOUND); + afb_hreq_reply_error(hreq, MHD_HTTP_NOT_FOUND); + return MHD_YES; + +internal_error: + afb_hsrv_reply_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR); return MHD_YES; } /* Because of POST call multiple time requestApi we need to free POST handle here */ -static void end_handler(void *cls, struct MHD_Connection *connection, void **con_cls, +static void end_handler(void *cls, struct MHD_Connection *connection, void **recordreq, enum MHD_RequestTerminationCode toe) { - AFB_PostHandle *posthandle = *con_cls; + AFB_session *session; + struct afb_hreq *hreq; - /* if post handle was used let's free everything */ - if (posthandle != NULL) - endPostRequest(posthandle); + session = cls; + hreq = *recordreq; + + if (hreq != NULL) { + if (hreq->postform != NULL) + MHD_destroy_post_processor(hreq->postform); + } } static int new_client_handler(void *cls, const struct sockaddr *addr, socklen_t addrlen) @@ -316,20 +359,37 @@ static int init_lib_magic (AFB_session *session) /* Warning: should not use NULL for DB [libmagic bug wont pass efence check] */ if (magic_load(session->magic, MAGIC_DB) != 0) { fprintf(stderr,"cannot load magic database - %s\n", magic_error(session->magic)); -/* magic_close(session->magic); session->magic = NULL; return 0; -*/ } return 1; } #endif -AFB_error httpdStart(AFB_session * session) +static int my_default_init(AFB_session * session) { + int idx; + + if (!afb_hsrv_add_handler(session, session->config->rootapi, relay_to_doRestApi, NULL, 1)) + return 0; + for (idx = 0; session->config->aliasdir[idx].url != NULL; idx++) + if (!afb_hsrv_add_alias (session, session->config->aliasdir[idx].url, session->config->aliasdir[idx].path, 0)) + return 0; + + if (!afb_hsrv_add_alias(session, "", session->config->rootdir, -10)) + return 0; + + if (!afb_hsrv_add_handler(session, session->config->rootbase, afb_hreq_one_page_api_redirect, NULL, -20)) + return 0; + + return 1; +} + +AFB_error httpdStart(AFB_session * session) +{ if (!my_default_init(session)) { printf("Error: initialisation of httpd failed"); return AFB_FATAL; -- 2.16.6