X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-hreq.c;h=474b90e8f2adecdbf4a1a202c3ca9ba011fa6e08;hb=8d21ca2e3daf37d8afe7b678edb0aa2e47a468ef;hp=e146bcb4ba2c24c3448f2abba0677fdfc75943aa;hpb=dde70b62b09f49ad672c104a3f81714bf11047be;p=src%2Fapp-framework-binder.git diff --git a/src/afb-hreq.c b/src/afb-hreq.c index e146bcb4..474b90e8 100644 --- a/src/afb-hreq.c +++ b/src/afb-hreq.c @@ -15,6 +15,7 @@ * limitations under the License. */ +#define USE_MAGIC_MIME_TYPE #define _GNU_SOURCE #include @@ -27,15 +28,30 @@ #include +#if defined(USE_MAGIC_MIME_TYPE) +#include +#endif + #include "local-def.h" #include "afb-method.h" #include "afb-req-itf.h" #include "afb-hreq.h" +#include "session.h" +#include "verbose.h" #define SIZE_RESPONSE_BUFFER 8000 static char empty_string[] = ""; +static const char uuid_header[] = "x-afb-uuid"; +static const char uuid_arg[] = "uuid"; +static const char uuid_cookie[] = "uuid"; + +static const char token_header[] = "x-afb-token"; +static const char token_arg[] = "token"; +static const char token_cookie[] = "token"; + + struct hreq_data { struct hreq_data *next; char *key; @@ -48,15 +64,19 @@ static struct afb_arg req_get(struct afb_hreq *hreq, const char *name); static void req_iterate(struct afb_hreq *hreq, int (*iterator)(void *closure, struct afb_arg arg), void *closure); static void req_fail(struct afb_hreq *hreq, const char *status, const char *info); static void req_success(struct afb_hreq *hreq, json_object *obj, const char *info); +static int req_session_create(struct afb_hreq *hreq); +static int req_session_check(struct afb_hreq *hreq, int refresh); +static void req_session_close(struct afb_hreq *hreq); static const struct afb_req_itf afb_hreq_itf = { .get = (void*)req_get, .iterate = (void*)req_iterate, .fail = (void*)req_fail, - .success = (void*)req_success + .success = (void*)req_success, + .session_create = (void*)req_session_create, + .session_check = (void*)req_session_check, + .session_close = (void*)req_session_close }; - void (*fail)(void *data, const char *status, const char *info); - void (*success)(void *data, json_object *obj, const char *info); static struct hreq_data *get_data(struct afb_hreq *hreq, const char *key, int create) { @@ -121,8 +141,97 @@ static int validsubpath(const char *subpath) return 1; } +#if defined(USE_MAGIC_MIME_TYPE) + +#if !defined(MAGIC_DB) +#define MAGIC_DB "/usr/share/misc/magic.mgc" +#endif + +static magic_t lazy_libmagic() +{ + static int done = 0; + static magic_t result = NULL; + + if (!done) { + done = 1; + /* MAGIC_MIME tells magic to return a mime of the file, + but you can specify different things */ + if (verbosity) + printf("Loading mimetype default magic database\n"); + + result = magic_open(MAGIC_MIME_TYPE); + if (result == NULL) { + fprintf(stderr,"ERROR: unable to initialize magic library\n"); + } + /* Warning: should not use NULL for DB + [libmagic bug wont pass efence check] */ + else if (magic_load(result, MAGIC_DB) != 0) { + fprintf(stderr,"cannot load magic database - %s\n", + magic_error(result)); + magic_close(result); + result = NULL; + } + } + + return result; +} + +static const char *magic_mimetype_fd(int fd) +{ + magic_t lib = lazy_libmagic(); + return lib ? magic_descriptor(lib, fd) : NULL; +} + +#endif + +static const char *mimetype_fd_name(int fd, const char *filename) +{ + const char *result = NULL; + +#if defined(INFER_EXTENSION) + const char *extension = strrchr(filename, '.'); + if (extension) { + static const char *const known[][2] = { + { ".js", "text/javascript" }, + { ".html", "text/html" }, + { NULL, NULL } + }; + int i = 0; + while (known[i][0]) { + if (!strcasecmp(extension, known[i][0])) { + result = known[i][1]; + break; + } + i++; + } + } +#endif +#if defined(USE_MAGIC_MIME_TYPE) + if (result == NULL) + result = magic_mimetype_fd(fd); +#endif + return result; +} + +void afb_hreq_free(struct afb_hreq *hreq) +{ + struct hreq_data *data; + if (hreq != NULL) { + if (hreq->postform != NULL) + MHD_destroy_post_processor(hreq->postform); + for (data = hreq->data; data; data = hreq->data) { + hreq->data = data->next; + free(data->key); + free(data->value); + free(data); + } + ctxClientPut(hreq->context); + free(hreq); + } +} + /* - * Removes the 'prefix' of 'length' frome the tail of 'hreq' + * Removes the 'prefix' of 'length' from the tail of 'hreq' * if and only if the prefix exists and is terminated by a leading * slash */ @@ -175,6 +284,7 @@ int afb_hreq_reply_file_if_exist(struct afb_hreq *hreq, int dirfd, const char *f char etag[1 + 2 * sizeof(int)]; const char *inm; struct MHD_Response *response; + const char *mimetype; /* Opens the file or directory */ if (filename[0]) { @@ -238,7 +348,7 @@ int afb_hreq_reply_file_if_exist(struct afb_hreq *hreq, int dirfd, const char *f if (inm && 0 == strcmp(inm, etag)) { /* etag ok, return NOT MODIFIED */ close(fd); - if (verbose) + if (verbosity) fprintf(stderr, "Not Modified: [%s]\n", filename); response = MHD_create_response_from_buffer(0, empty_string, MHD_RESPMEM_PERSISTENT); status = MHD_HTTP_NOT_MODIFIED; @@ -254,14 +364,10 @@ int afb_hreq_reply_file_if_exist(struct afb_hreq *hreq, int dirfd, const char *f response = MHD_create_response_from_fd((size_t) st.st_size, fd); status = MHD_HTTP_OK; -#if defined(USE_MAGIC_MIME_TYPE) /* set the type */ - if (hreq->session->magic) { - const char *mimetype = magic_descriptor(hreq->session->magic, fd); - if (mimetype != NULL) - MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mimetype); - } -#endif + mimetype = mimetype_fd_name(fd, filename); + if (mimetype != NULL) + MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mimetype); } /* fills the value and send */ @@ -288,7 +394,7 @@ int afb_hreq_redirect_to(struct afb_hreq *hreq, const char *url) MHD_add_response_header(response, MHD_HTTP_HEADER_LOCATION, url); MHD_queue_response(hreq->connection, MHD_HTTP_MOVED_PERMANENTLY, response); MHD_destroy_response(response); - if (verbose) + if (verbosity) fprintf(stderr, "redirect from [%s] to [%s]\n", hreq->url, url); return 1; } @@ -430,17 +536,6 @@ static void req_iterate(struct afb_hreq *hreq, int (*iterator)(void *closure, st MHD_get_connection_values (hreq->connection, MHD_GET_ARGUMENT_KIND, (void*)_iterargs_, &id); } -void afb_hreq_drop_data(struct afb_hreq *hreq) -{ - struct hreq_data *data = hreq->data; - while (data) { - hreq->data = data->next; - free(data->key); - free(data->value); - free(data); - data = hreq->data; - } -} static ssize_t send_json_cb(json_object *obj, uint64_t pos, char *buf, size_t max) { ssize_t len = stpncpy(buf, json_object_to_json_string(obj)+pos, max) - buf; @@ -461,6 +556,10 @@ static void req_reply(struct afb_hreq *hreq, unsigned retcode, const char *statu json_object_object_add(request, "info", json_object_new_string(info)); if (resp) json_object_object_add(root, "response", resp); + if (hreq->context) { + json_object_object_add(request, uuid_arg, json_object_new_string(hreq->context->uuid)); + json_object_object_add(request, token_arg, json_object_new_string(hreq->context->token)); + } response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, SIZE_RESPONSE_BUFFER, (void*)send_json_cb, root, (void*)json_object_put); MHD_queue_response(hreq->connection, retcode, response); @@ -477,3 +576,64 @@ static void req_success(struct afb_hreq *hreq, json_object *obj, const char *inf req_reply(hreq, MHD_HTTP_OK, "success", info, obj); } +struct AFB_clientCtx *afb_hreq_context(struct afb_hreq *hreq) +{ + const char *uuid; + + if (hreq->context == NULL) { + uuid = afb_hreq_get_header(hreq, uuid_header); + if (uuid == NULL) + uuid = afb_hreq_get_argument(hreq, uuid_arg); + if (uuid == NULL) + uuid = afb_hreq_get_cookie(hreq, uuid_cookie); + hreq->context = ctxClientGetForUuid(uuid); + } + return hreq->context; +} + +static int req_session_create(struct afb_hreq *hreq) +{ + struct AFB_clientCtx *context = afb_hreq_context(hreq); + if (context == NULL) + return 0; + if (context->created) + return 0; + return req_session_check(hreq, 1); +} + +static int req_session_check(struct afb_hreq *hreq, int refresh) +{ + const char *token; + + struct AFB_clientCtx *context = afb_hreq_context(hreq); + + if (context == NULL) + return 0; + + token = afb_hreq_get_header(hreq, token_header); + if (token == NULL) + token = afb_hreq_get_argument(hreq, token_arg); + if (token == NULL) + token = afb_hreq_get_cookie(hreq, token_cookie); + if (token == NULL) + return 0; + + if (!ctxTokenCheck (context, token)) + return 0; + + if (refresh) { + ctxTokenNew (context); + } + + return 1; +} + +static void req_session_close(struct afb_hreq *hreq) +{ + struct AFB_clientCtx *context = afb_hreq_context(hreq); + if (context != NULL) + ctxClientClose(context); +} + + +