afb-hreq: Add predefined mime-types
[src/app-framework-binder.git] / src / afb-hreq.c
index 8e3230d..5f44cba 100644 (file)
 #endif
 
 #include "afb-method.h"
-#include <afb/afb-req-itf.h>
 #include "afb-msg-json.h"
 #include "afb-context.h"
 #include "afb-hreq.h"
-#include "afb-subcall.h"
 #include "afb-session.h"
+#include "afb-cred.h"
 #include "verbose.h"
 #include "locale-root.h"
 
@@ -72,19 +71,18 @@ struct hreq_data {
        char *path;             /* path of the file saved */
 };
 
-static struct json_object *req_json(struct afb_hreq *hreq);
-static struct afb_arg req_get(struct afb_hreq *hreq, const char *name);
-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 void afb_hreq_destroy(struct afb_hreq *hreq);
+static struct json_object *req_json(struct afb_xreq *xreq);
+static struct afb_arg req_get(struct afb_xreq *xreq, const char *name);
+static void req_fail(struct afb_xreq *xreq, const char *status, const char *info);
+static void req_success(struct afb_xreq *xreq, json_object *obj, const char *info);
+static void req_destroy(struct afb_xreq *xreq);
 
 const struct afb_xreq_query_itf afb_hreq_xreq_query_itf = {
-       .json = (void*)req_json,
-       .get = (void*)req_get,
-       .success = (void*)req_success,
-       .fail = (void*)req_fail,
-       .unref = (void*)afb_hreq_destroy
+       .json = req_json,
+       .get = req_get,
+       .success = req_success,
+       .fail = req_fail,
+       .unref = req_destroy
 };
 
 static struct hreq_data *get_data(struct afb_hreq *hreq, const char *key, int create)
@@ -273,13 +271,24 @@ static const char *mimetype_fd_name(int fd, const char *filename)
        const char *extension = strrchr(filename, '.');
        if (extension) {
                static const char *const known[][2] = {
-                       { ".js",   "text/javascript" },
-                       { ".html", "text/html" },
-                       { ".css",  "text/css" },
-                       { ".ico",  "image/x-icon"},
-                       { ".png",  "image/png" },
-                       { ".svg",  "image/svg+xml" },
-                       { ".ttf",  "application/x-font-ttf"},
+                       { ".js",        "text/javascript" },
+                       { ".html",      "text/html" },
+                       { ".css",       "text/css" },
+                       { ".ico",       "image/x-icon"},
+                       /* TODO: CHECK ME { ".ico",     "image/vnd.microsoft.icon" }, */
+                       { ".jpg",       "image/jpeg" },
+                       { ".png",       "image/png" },
+                       { ".svg",       "image/svg+xml" },
+                       { ".ttf",       "application/x-font-ttf"},
+                       { ".htm",       "text/html" },
+                       { ".xml",       "application/xml" },
+                       { ".txt",       "text/plain" },
+                       { ".wav",       "audio/x-wav" },
+                       { ".xhtml",     "application/xhtml+xml" },
+                       { ".xht",       "application/xhtml+xml" },
+                       { ".gif",       "image/gif" },
+                       { ".png",       "image/png" },
+                       { ".mp3",       "audio/mpeg" },
                        { NULL, NULL }
                };
                int i = 0;
@@ -299,8 +308,9 @@ static const char *mimetype_fd_name(int fd, const char *filename)
        return result;
 }
 
-static void afb_hreq_destroy(struct afb_hreq *hreq)
+static void req_destroy(struct afb_xreq *xreq)
 {
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        struct hreq_data *data;
 
        if (hreq->postform != NULL)
@@ -317,19 +327,22 @@ static void afb_hreq_destroy(struct afb_hreq *hreq)
        }
        afb_context_disconnect(&hreq->xreq.context);
        json_object_put(hreq->json);
-       free(hreq->xreq.api);
-       free(hreq->xreq.verb);
+       free((char*)hreq->xreq.request.api);
+       free((char*)hreq->xreq.request.verb);
+       afb_cred_unref(hreq->xreq.cred);
        free(hreq);
 }
 
 void afb_hreq_addref(struct afb_hreq *hreq)
 {
-       afb_xreq_addref(&hreq->xreq);
+       afb_xreq_unhooked_addref(&hreq->xreq);
 }
 
 void afb_hreq_unref(struct afb_hreq *hreq)
 {
-       afb_xreq_unref(&hreq->xreq);
+       if (hreq->replied)
+               hreq->xreq.replied = 1;
+       afb_xreq_unhooked_unref(&hreq->xreq);
 }
 
 /*
@@ -820,9 +833,10 @@ int afb_hreq_post_add_file(struct afb_hreq *hreq, const char *key, const char *f
        return !size;
 }
 
-static struct afb_arg req_get(struct afb_hreq *hreq, const char *name)
+static struct afb_arg req_get(struct afb_xreq *xreq, const char *name)
 {
        const char *value;
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        struct hreq_data *hdat = get_data(hreq, name, 0);
        if (hdat)
                return (struct afb_arg){
@@ -845,10 +859,11 @@ static int _iterargs_(struct json_object *obj, enum MHD_ValueKind kind, const ch
        return 1;
 }
 
-static struct json_object *req_json(struct afb_hreq *hreq)
+static struct json_object *req_json(struct afb_xreq *xreq)
 {
        struct hreq_data *hdat;
        struct json_object *obj, *val;
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
 
        obj = hreq->json;
        if (obj == NULL) {
@@ -896,28 +911,31 @@ static void req_reply(struct afb_hreq *hreq, unsigned retcode, const char *statu
        afb_hreq_reply(hreq, retcode, response, NULL);
 }
 
-static void req_fail(struct afb_hreq *hreq, const char *status, const char *info)
+static void req_fail(struct afb_xreq *xreq, const char *status, const char *info)
 {
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        req_reply(hreq, MHD_HTTP_OK, status, info, NULL);
 }
 
-static void req_success(struct afb_hreq *hreq, json_object *obj, const char *info)
+static void req_success(struct afb_xreq *xreq, json_object *obj, const char *info)
 {
+       struct afb_hreq *hreq = CONTAINER_OF_XREQ(struct afb_hreq, xreq);
        req_reply(hreq, MHD_HTTP_OK, "success", info, obj);
 }
 
-int afb_hreq_init_req_call(struct afb_hreq *hreq, const char *api, size_t lenapi, const char *verb, size_t lenverb)
+void afb_hreq_call(struct afb_hreq *hreq, struct afb_apiset *apiset, const char *api, size_t lenapi, const char *verb, size_t lenverb)
 {
-       free(hreq->xreq.api);
-       free(hreq->xreq.verb);
-       hreq->xreq.api = strndup(api, lenapi);
-       hreq->xreq.verb = strndup(verb, lenverb);
-       if (hreq->xreq.api == NULL || hreq->xreq.verb == NULL) {
+       hreq->xreq.request.api = strndup(api, lenapi);
+       hreq->xreq.request.verb = strndup(verb, lenverb);
+       if (hreq->xreq.request.api == NULL || hreq->xreq.request.verb == NULL) {
                ERROR("Out of memory");
-               errno = ENOMEM;
-               return -1;
+               afb_hreq_reply_error(hreq, MHD_HTTP_INTERNAL_SERVER_ERROR);
+       } else if (afb_hreq_init_context(hreq) < 0) {
+               afb_hreq_reply_error(hreq, MHD_HTTP_INTERNAL_SERVER_ERROR);
+       } else {
+               afb_xreq_unhooked_addref(&hreq->xreq);
+               afb_xreq_process(&hreq->xreq, apiset);
        }
-       return afb_hreq_init_context(hreq);
 }
 
 int afb_hreq_init_context(struct afb_hreq *hreq)
@@ -975,9 +993,7 @@ struct afb_hreq *afb_hreq_create()
        struct afb_hreq *hreq = calloc(1, sizeof *hreq);
        if (hreq) {
                /* init the request */
-               hreq->xreq.refcount = 1;
-               hreq->xreq.query = hreq;
-               hreq->xreq.queryitf = &afb_hreq_xreq_query_itf;
+               afb_xreq_init(&hreq->xreq, &afb_hreq_xreq_query_itf);
                hreq->reqid = ++global_reqids;
        }
        return hreq;