*/
#define _GNU_SOURCE
-#include <microhttpd.h>
+
+#include <stdio.h>
+#include <string.h>
#include <assert.h>
#include <poll.h>
+#include <fcntl.h>
#include <sys/stat.h>
-#include "../include/local-def.h"
+#include <microhttpd.h>
+
+#include "local-def.h"
#include "afb-method.h"
#include "afb-hreq.h"
#include "afb-websock.h"
+#include "afb-apis.h"
+#include "afb-req-itf.h"
#define JSON_CONTENT "application/json"
#define FORM_CONTENT MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA
+
struct afb_hsrv_handler {
struct afb_hsrv_handler *next;
const char *prefix;
return 1;
}
-static int relay_to_doRestApi(struct afb_hreq *hreq, void *data)
+static int afb_hreq_websocket_switch(struct afb_hreq *hreq, void *data)
{
int later;
- if (hreq->lentail == 0 && afb_websock_check(hreq, &later)) {
- if (!later) {
- struct afb_websock *ws = afb_websock_create(hreq->connection);
+
+ 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->connection);
+ if (ws == NULL) {
+ /* TODO */
+ } else {
+ /* TODO */
}
- return 1;
}
+ return 1;
+}
-return 0;
-/*
- return doRestApi(hreq->connection, hreq->session, &hreq->tail[1], get_method_name(hreq->method),
- post->upload_data, post->upload_data_size, (void **)hreq->recorder);
-*/
+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)
size_t *upload_data_size,
void **recordreq)
{
+ int rc;
struct afb_hreq *hreq;
enum afb_method method;
AFB_session *session;
/* get the method */
method = get_method(methodstr);
method &= afb_method_get | afb_method_post;
- if (method == afb_method_none) {
- afb_hsrv_reply_error(connection, MHD_HTTP_BAD_REQUEST);
- return MHD_YES;
- }
+ if (method == afb_method_none)
+ goto bad_request;
/* init the request */
hreq->session = cls;
/* flush the data */
afb_hreq_post_end(hreq);
+ if (hreq->postform != NULL) {
+ rc = MHD_destroy_post_processor(hreq->postform);
+ hreq->postform = NULL;
+ if (rc == MHD_NO)
+ goto bad_request;
+ }
/* search an handler for the request */
iter = session->handlers;
afb_hreq_reply_error(hreq, MHD_HTTP_NOT_FOUND);
return MHD_YES;
+bad_request:
+ afb_hsrv_reply_error(connection, MHD_HTTP_BAD_REQUEST);
+ return MHD_YES;
+
internal_error:
afb_hsrv_reply_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR);
return MHD_YES;
static void end_handler(void *cls, struct MHD_Connection *connection, void **recordreq,
enum MHD_RequestTerminationCode toe)
{
- AFB_session *session;
struct afb_hreq *hreq;
- session = cls;
hreq = *recordreq;
- if (hreq != NULL) {
- if (hreq->postform != NULL)
- MHD_destroy_post_processor(hreq->postform);
- }
+ afb_hreq_free(hreq);
}
static int new_client_handler(void *cls, const struct sockaddr *addr, socklen_t addrlen)
{
int idx;
- if (!afb_hsrv_add_handler(session, session->config->rootapi, relay_to_doRestApi, NULL, 1))
+ if (!afb_hsrv_add_handler(session, session->config->rootapi, afb_hreq_websocket_switch, NULL, 20))
+ return 0;
+
+ if (!afb_hsrv_add_handler(session, session->config->rootapi, afb_hreq_rest_api, NULL, 10))
return 0;
for (idx = 0; session->config->aliasdir[idx].url != NULL; idx++)