#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"
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)
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"},
- { NULL, NULL }
+ /* keep it sorted for dichotomic search */
+ { ".css", "text/css" },
+ { ".gif", "image/gif" },
+ { ".html", "text/html" },
+ { ".htm", "text/html" },
+ { ".ico", "image/x-icon"},
+ { ".jpeg", "image/jpeg" },
+ { ".jpg", "image/jpeg" },
+ { ".js", "text/javascript" },
+ { ".json", "application/json" },
+ { ".mp3", "audio/mpeg" },
+ { ".png", "image/png" },
+ { ".svg", "image/svg+xml" },
+ { ".ttf", "application/x-font-ttf"},
+ { ".txt", "text/plain" },
+ { ".wav", "audio/x-wav" },
+ { ".xht", "application/xhtml+xml" },
+ { ".xhtml", "application/xhtml+xml" },
+ { ".xml", "application/xml" }
};
- int i = 0;
- while (known[i][0]) {
- if (!strcasecmp(extension, known[i][0])) {
+ int i, c, l = 0, u = sizeof known / sizeof *known;
+ while (l < u) {
+ i = (l + u) >> 1;
+ c = strcasecmp(extension, known[i][0]);
+ if (!c) {
result = known[i][1];
break;
}
- i++;
+ if (c < 0)
+ u = i;
+ else
+ l = i + 1;
}
}
#endif
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)
}
afb_context_disconnect(&hreq->xreq.context);
json_object_put(hreq->json);
- free((char*)hreq->xreq.api);
- free((char*)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);
}
/*
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){
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) {
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)
{
- 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)
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;