X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-rest-api.c;h=49e5d8b2491da05f2cde9e55cac1bbd87c612b39;hb=cc4b56b6710624c069642d1a510d0060949fe5b9;hp=febe19f83993366341e6003373b861dc95c3a1e9;hpb=ca208671cc79bbc05c574df788035878e5d39382;p=src%2Fapp-framework-binder.git diff --git a/src/afb-rest-api.c b/src/afb-rest-api.c index febe19f8..49e5d8b2 100644 --- a/src/afb-rest-api.c +++ b/src/afb-rest-api.c @@ -31,11 +31,12 @@ #include #include "afb-apis.h" +#include "session.h" #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; @@ -66,30 +67,31 @@ 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(); json_object_object_add(jcall, "prefix", json_object_new_string(request->prefix)); - json_object_object_add(jcall, "api", json_object_new_string(request->api)); + json_object_object_add(jcall, "api", json_object_new_string(request->method)); // Out of SessionNone every call get a client context session session = afb_apis_get(apiidx, verbidx)->session; if (AFB_SESSION_NONE != session) { // add client context to request - clientCtx = ctxClientGet(request, apiidx); + clientCtx = ctxClientGet(request); if (clientCtx == NULL) { request->errcode = MHD_HTTP_INSUFFICIENT_STORAGE; json_object_object_add(jcall, "status", json_object_new_string("fail")); json_object_object_add(jcall, "info", json_object_new_string("Client Session Context Full !!!")); json_object_object_add(jreqt, "request", jcall); goto ExitOnDone; - }; + } + request->context = clientCtx->contexts[apiidx]; + request->uuid = clientCtx->uuid; if (verbose) - fprintf(stderr, "Plugin=[%s] Api=[%s] Middleware=[%d] Client=[%p] Uuid=[%s] Token=[%s]\n", request->prefix, request->api, session, clientCtx, clientCtx->uuid, clientCtx->token); + fprintf(stderr, "Plugin=[%s] Api=[%s] Middleware=[%d] Client=[%p] Uuid=[%s] Token=[%s]\n", request->prefix, request->method, session, clientCtx, clientCtx->uuid, clientCtx->token); switch (session) { @@ -154,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); @@ -190,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; @@ -201,36 +204,32 @@ 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(); json_object_object_add(jcall, "prefix", json_object_new_string(request->prefix)); - json_object_object_add(jcall, "api", json_object_new_string(request->api)); + json_object_object_add(jcall, "api", json_object_new_string(request->method)); // Plugin aborted somewhere during its execution json_object_object_add(jcall, "status", json_object_new_string("abort")); 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; } @@ -239,7 +238,7 @@ STATIC AFB_error findAndCallApi(AFB_request * request, void *context) int apiidx, verbidx; AFB_error status; - if (!request->api || !request->prefix) + if (!request->method || !request->prefix) return AFB_FAIL; /* get the plugin if any */ @@ -251,9 +250,9 @@ STATIC AFB_error findAndCallApi(AFB_request * request, void *context) } /* get the verb if any */ - verbidx = afb_apis_get_verbidx(apiidx, request->api); + verbidx = afb_apis_get_verbidx(apiidx, request->method); if (verbidx < 0) { - request->jresp = jsonNewMessage(AFB_FATAL, "No API=[%s] for Plugin=[%s] url=[%s]", request->api, request->prefix, request->url); + request->jresp = jsonNewMessage(AFB_FATAL, "No API=[%s] for Plugin=[%s] url=[%s]", request->method, request->prefix, request->url); request->errcode = MHD_HTTP_UNPROCESSABLE_ENTITY; return AFB_FAIL; } @@ -263,7 +262,7 @@ STATIC AFB_error findAndCallApi(AFB_request * request, void *context) /* plugin callback did not return a valid Json Object */ if (status == AFB_FAIL) { - request->jresp = jsonNewMessage(AFB_FATAL, "No API=[%s] for Plugin=[%s] url=[%s]", request->api, request->prefix, request->url); + request->jresp = jsonNewMessage(AFB_FATAL, "No API=[%s] for Plugin=[%s] url=[%s]", request->method, request->prefix, request->url); request->errcode = MHD_HTTP_UNPROCESSABLE_ENTITY; return AFB_FAIL; } @@ -317,7 +316,7 @@ STATIC void freeRequest(AFB_request * request) { free(request->prefix); - free(request->api); + free(request->method); free(request); } @@ -351,7 +350,7 @@ STATIC AFB_request *createRequest(struct MHD_Connection *connection, AFB_session request->config = session->config; request->url = url; request->prefix = strdup(baseurl); - request->api = strdup(baseapi); + request->method = strdup(baseapi); Done: free(urlcpy1); @@ -408,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) @@ -446,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 @@ -472,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: