-static struct upoll *upoll = NULL;
-
-static struct afb_hsrv_handler *new_handler(
- struct afb_hsrv_handler *head,
- const char *prefix,
- int (*handler) (struct afb_hreq *, void *),
- void *data,
- int priority)
-{
- struct afb_hsrv_handler *link, *iter, *previous;
- size_t length;
-
- /* get the length of the prefix without its leading / */
- length = strlen(prefix);
- while (length && prefix[length - 1] == '/')
- length--;
-
- /* allocates the new link */
- link = malloc(sizeof *link);
- if (link == NULL)
- return NULL;
-
- /* initialize it */
- link->prefix = prefix;
- link->length = length;
- link->handler = handler;
- link->data = data;
- link->priority = priority;
-
- /* adds it */
- previous = NULL;
- iter = head;
- while (iter && (priority < iter->priority || (priority == iter->priority && length <= iter->length))) {
- previous = iter;
- iter = iter->next;
- }
- link->next = iter;
- if (previous == NULL)
- return link;
- previous->next = link;
- return head;
-}
-
-int afb_hsrv_add_handler(
- AFB_session * session,
- const char *prefix,
- int (*handler) (struct afb_hreq *, void *),
- void *data,
- int priority)
-{
- struct afb_hsrv_handler *head;
-
- head = new_handler(session->handlers, prefix, handler, data, priority);
- if (head == NULL)
- return 0;
- session->handlers = head;
- return 1;
-}
-
-int afb_hreq_one_page_api_redirect(
- struct afb_hreq *hreq,
- void *data)
-{
- size_t plen;
- char *url;
-
- if (hreq->lentail >= 2 && hreq->tail[1] == '#')
- return 0;
- /*
- * Here we have for example:
- * url = "/pre/dir/page" lenurl = 13
- * tail = "/dir/page" lentail = 9
- *
- * We will produce "/pre/#!dir/page"
- *
- * Let compute plen that include the / at end (for "/pre/")
- */
- plen = hreq->lenurl - hreq->lentail + 1;
- url = alloca(hreq->lenurl + 3);
- memcpy(url, hreq->url, plen);
- url[plen++] = '#';
- url[plen++] = '!';
- memcpy(&url[plen], &hreq->tail[1], hreq->lentail);
- return afb_hreq_redirect_to(hreq, url);
-}
-
-static int afb_hreq_websocket_switch(struct afb_hreq *hreq, void *data)
-{
- int later;
-
- afb_hreq_context(hreq);
- if (hreq->lentail != 0 || !afb_websock_check(hreq, &later))
- return 0;
-
- if (!later) {
- struct afb_websock *ws = afb_websock_create(hreq);
- if (ws == NULL) {
- /* TODO */
- } else {
- /* TODO */
- }
- }
- return 1;
-}
-
-static int afb_hreq_rest_api(struct afb_hreq *hreq, void *data)
-{
- const char *api, *verb;
- size_t lenapi, lenverb;
- struct AFB_clientCtx *context;
-
- api = &hreq->tail[strspn(hreq->tail, "/")];
- lenapi = strcspn(api, "/");
- verb = &api[lenapi];
- verb = &verb[strspn(verb, "/")];
- lenverb = strcspn(verb, "/");
-
- if (!(*api && *verb && lenapi && lenverb))
- return 0;
-
- context = afb_hreq_context(hreq);
- return afb_apis_handle(afb_hreq_to_req(hreq), context, api, lenapi, verb, lenverb);
-}
-
-static int handle_alias(struct afb_hreq *hreq, void *data)
-{
- struct afb_diralias *da = data;
-
- if (hreq->method != afb_method_get) {
- afb_hreq_reply_error(hreq, MHD_HTTP_METHOD_NOT_ALLOWED);
- return 1;
- }
-
- if (!afb_hreq_valid_tail(hreq)) {
- afb_hreq_reply_error(hreq, MHD_HTTP_FORBIDDEN);
- return 1;
- }
-
- return afb_hreq_reply_file(hreq, da->dirfd, &hreq->tail[1]);
-}
-
-int afb_hsrv_add_alias(AFB_session * session, const char *prefix, const char *alias, int priority)
-{
- struct afb_diralias *da;
- int dirfd;
-
- dirfd = open(alias, O_PATH|O_DIRECTORY);
- if (dirfd < 0) {
- /* TODO message */
- return 0;
- }
- da = malloc(sizeof *da);
- if (da != NULL) {
- da->alias = prefix;
- da->directory = alias;
- da->lendir = strlen(da->directory);
- da->dirfd = dirfd;
- if (afb_hsrv_add_handler(session, prefix, handle_alias, da, priority))
- return 1;
- free(da);
- }
- close(dirfd);
- return 0;
-}