refactoring (in progress, tbf)
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 31 Mar 2016 21:15:45 +0000 (23:15 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 31 Mar 2016 21:15:45 +0000 (23:15 +0200)
Change-Id: Id9a98da85bb838b9401dad48a6652207ab4db191
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
12 files changed:
plugins/CMakeLists.txt
plugins/samples/CMakeLists.txt
src/afb-apis.c
src/afb-hreq.c
src/afb-req-itf.h
src/helper-api.c
src/http-svc.c
test/client-ctx.html [new file with mode: 0644]
test/hello-world.html [new file with mode: 0644]
test/index.html [new file with mode: 0644]
test/sample-post.html [new file with mode: 0644]
test/websock.html [new file with mode: 0644]

index ba3432b..5d8b26a 100644 (file)
@@ -1,6 +1,6 @@
-ADD_SUBDIRECTORY(afm-main-plugin)
+#ADD_SUBDIRECTORY(afm-main-plugin)
 ADD_SUBDIRECTORY(session)
 ADD_SUBDIRECTORY(samples)
-ADD_SUBDIRECTORY(audio)
-ADD_SUBDIRECTORY(radio)
-ADD_SUBDIRECTORY(media)
+#ADD_SUBDIRECTORY(audio)
+#ADD_SUBDIRECTORY(radio)
+#ADD_SUBDIRECTORY(media)
index c3c305c..24ffd91 100644 (file)
@@ -6,11 +6,11 @@ TARGET_LINK_LIBRARIES(helloWorld-api ${link_libraries})
 INSTALL(TARGETS helloWorld-api
         LIBRARY DESTINATION ${plugin_install_dir})
 
-ADD_LIBRARY(samplePost-api MODULE SamplePost.c)
-SET_TARGET_PROPERTIES(samplePost-api PROPERTIES PREFIX "")
-TARGET_LINK_LIBRARIES(samplePost-api ${link_libraries})
-INSTALL(TARGETS samplePost-api
-        LIBRARY DESTINATION ${plugin_install_dir})
+#ADD_LIBRARY(samplePost-api MODULE SamplePost.c)
+#SET_TARGET_PROPERTIES(samplePost-api PROPERTIES PREFIX "")
+#TARGET_LINK_LIBRARIES(samplePost-api ${link_libraries})
+#INSTALL(TARGETS samplePost-api
+#        LIBRARY DESTINATION ${plugin_install_dir})
 
 ADD_LIBRARY(clientCtx-api MODULE ClientCtx.c)
 SET_TARGET_PROPERTIES(clientCtx-api PROPERTIES PREFIX "")
index ca42743..856e3f5 100644 (file)
@@ -345,12 +345,15 @@ int afb_apis_handle(struct afb_req req, const char *api, size_t lenapi, const ch
        const struct api_desc *a;
        const struct AFB_restapi *v;
 
+//fprintf(stderr,"afb_apis_handle prefix:%.*s verb:%.*s\n",(int)lenapi,api,(int)lenverb,verb);
        a = apis_array;
        for (i = 0 ; i < apis_count ; i++, a++) {
-               if (a->prefixlen == lenapi && !strcasecmp(a->prefix, api)) {
+               if (a->prefixlen == lenapi && !strncasecmp(a->prefix, api, lenapi)) {
+//fprintf(stderr,"afb_apis_handle found prefix:%.*s -> %s\n",(int)lenapi,api,a->prefix);
                        v = a->plugin->apis;
                        for (j = 0 ; v->name ; j++, v++) {
                                if (!strncasecmp(v->name, verb, lenverb) && !v->name[lenverb]) {
+//fprintf(stderr,"afb_apis_handle found prefix:%.*s verb:%.*s -> %s/%s\n",(int)lenapi,api,(int)lenverb,verb,a->prefix,v->name);
                                        handle(req, a, v);
                                        return 1;
                                }
index 1611467..506091c 100644 (file)
@@ -36,10 +36,12 @@ struct hreq_data {
        char *value;
 };
 
+static struct afb_arg getarg(struct afb_hreq *hreq, const char *name);
+static void iterargs(struct afb_hreq *hreq, int (*iterator)(void *closure, struct afb_arg arg), void *closure);
+
 static const struct afb_req_itf afb_hreq_itf = {
-       .argument = (void*)afb_hreq_get_argument,
-       .is_argument_file = (void*)afb_hreq_is_argument_a_file,
-       .iterate_arguments = (void*)afb_hreq_iterate_arguments
+       .get = (void*)getarg,
+       .iterate = (void*)iterargs
 };
 
 static struct hreq_data *get_data(struct afb_hreq *hreq, const char *key, int create)
@@ -378,6 +380,60 @@ void afb_hreq_iterate_arguments(struct afb_hreq *hreq, int (*iterator)(void *clo
        MHD_get_connection_values (hreq->connection, MHD_GET_ARGUMENT_KIND, (void*)itargs, &id);
 }
 
+static struct afb_arg getarg(struct afb_hreq *hreq, const char *name)
+{
+       struct hreq_data *hdat = get_data(hreq, name, 0);
+       if (hdat)
+               return (struct afb_arg){
+                       .name = hdat->key,
+                       .value = hdat->value,
+                       .size = hdat->length,
+                       .is_file = (hdat->file != 0)
+               };
+               
+       return (struct afb_arg){
+               .name = name,
+               .value = MHD_lookup_connection_value(hreq->connection, MHD_GET_ARGUMENT_KIND, name),
+               .size = 0,
+               .is_file = 0
+       };
+}
+
+struct iterdata
+{
+       struct afb_hreq *hreq;
+       int (*iterator)(void *closure, struct afb_arg arg);
+       void *closure;
+};
+
+static int _iterargs_(struct iterdata *id, enum MHD_ValueKind kind, const char *key, const char *value)
+{
+       if (get_data(id->hreq, key, 0))
+               return 1;
+       return id->iterator(id->closure, (struct afb_arg){
+               .name = key,
+               .value = value,
+               .size = 0,
+               .is_file = 0
+       });
+}
+
+static void iterargs(struct afb_hreq *hreq, int (*iterator)(void *closure, struct afb_arg arg), void *closure)
+{
+       struct iterdata id = { .hreq = hreq, .iterator = iterator, .closure = closure };
+       struct hreq_data *hdat = hreq->data;
+       while (hdat) {
+               if (!iterator(closure, (struct afb_arg){
+                       .name = hdat->key,
+                       .value = hdat->value,
+                       .size = hdat->length,
+                       .is_file = (hdat->file != 0)}))
+                       return;
+               hdat = hdat->next;
+       }
+       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;
index d747d0b..ab72a5c 100644 (file)
  * limitations under the License.
  */
 
+struct afb_arg {
+       const char *name;
+       const char *value;
+       size_t size;
+       int is_file;
+};
 
 struct afb_req_itf {
-       const char *(*argument)(void *data, const char *name);
-       int (*is_argument_file)(void *data, const char *name);
-       int (*iterate_arguments)(void *data, int (*iterator)(void *closure, const char *key, const char *value, int isfile), void *closure);
+       struct afb_arg (*get)(void *data, const char *name);
+       void (*iterate)(void *data, int (*iterator)(void *closure, struct afb_arg arg), void *closure);
 };
 
 struct afb_req {
@@ -27,21 +32,23 @@ struct afb_req {
        void *data;
 };
 
-static inline const char *afb_req_argument(struct afb_req req, const char *name)
+static inline struct afb_arg afb_req_get(struct afb_req req, const char *name)
 {
-       return req.itf->argument(req.data, name);
+       return req.itf->get(req.data, name);
 }
 
-static inline int afb_req_argument_file(struct afb_req req, const char *name)
+static inline const char *afb_req_argument(struct afb_req req, const char *name)
 {
-       return req.itf->is_argument_file(req.data, name);
+       return afb_req_get(req, name).value;
 }
 
-static inline int afb_req_iterate_arguments(struct afb_req req, int (*iterator)(void *closure, const char *key, const char *value, int isfile), void *closure)
+static inline int afb_req_is_argument_file(struct afb_req req, const char *name)
 {
-       return req.itf->iterate_arguments(req.data, iterator, closure);
+       return afb_req_get(req, name).is_file;
 }
 
-
-
+static inline void afb_req_iterate(struct afb_req req, int (*iterator)(void *closure, struct afb_arg arg), void *closure)
+{
+       req.itf->iterate(req.data, iterator, closure);
+}
 
index 58015d1..fd42c48 100644 (file)
@@ -53,10 +53,10 @@ const char* getQueryValue(const AFB_request * request, const char *name) {
     return afb_req_argument(*request->areq, name);
 }
 
-static int getQueryCB (queryHandleT *query, const char *key, const char *value, int isfile) {
+static int getQueryCB (queryHandleT *query, struct afb_arg arg) {
     if (query->idx >= query->len)
        return 0;
-    query->idx += snprintf (&query->msg[query->idx], query->len-query->idx, " %s: %s\'%s\',", key, isfile?"FILE=":"", value);
+    query->idx += snprintf (&query->msg[query->idx], query->len-query->idx, " %s: %s\'%s\',", arg.name, arg.is_file?"FILE=":"", arg.value);
     return 1; /* continue to iterate */
 }
 
@@ -68,7 +68,7 @@ int getQueryAll(AFB_request * request, char *buffer, size_t len) {
     query.len = len;
     query.idx = 0;
 
-    afb_req_iterate_arguments(*request->areq, getQueryCB, &query);
+    afb_req_iterate(*request->areq, getQueryCB, &query);
     buffer[len-1] = 0;
     return query.idx >= len ? len - 1 : query.idx;
 }
index 9fa6e84..706abbc 100644 (file)
@@ -175,11 +175,11 @@ static int afb_hreq_rest_api(struct afb_hreq *hreq, void *data)
        const char *api, *verb;
        size_t lenapi, lenverb;
 
-       api = hreq->tail;
-       lenapi = strspn(api, "/");
-       verb = &hreq->tail[lenapi];
-       verb = &verb[strcspn(verb, "/")];
-       lenverb = strspn(verb, "/");
+       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;
diff --git a/test/client-ctx.html b/test/client-ctx.html
new file mode 100644 (file)
index 0000000..26f4bcf
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+  <head>
+    <title>Client Ctx test</title>
+  <body>
+    <h1>Client Ctx test</h1>
+    <ol>
+     <li><a href="api/context/create">create</a>
+     <li><a href="api/context/action">check</a>
+     <li><a href="api/context/close">close</a>
diff --git a/test/hello-world.html b/test/hello-world.html
new file mode 100644 (file)
index 0000000..88f2c95
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+  <head>
+    <title>Hello world test</title>
+  <body>
+    <h1>Hello world test</h1>
+    <ol>
+     <li><a href="api/hello/ping?toto=1">ping</a>
+     <li><a href="api/hello/pingnull">ping null</a>
+     <li><a href="api/hello/pingbug">ping bug</a>
+     <li><a href="api/hello/pingJson?toto&tata&titi=u">ping json</a>
+     <li><a href="api/hello/none">not a verb</a>
+     <li><a href="api/none/none">not an api</a>
diff --git a/test/index.html b/test/index.html
new file mode 100644 (file)
index 0000000..66b3619
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+  <head>
+    <title>afb-daemon test</title>
+  <body>
+    <h1>afb-daemon test</h1>
+    <ol>
+     <li><a href="hello-world.html">Hello World!</a>
+     <li><a href="client-ctx.html">client context</a>
+     <li><a href="sample-post.html">Sample post</a>
+     <li><a href="websock.html">websockets</a>
diff --git a/test/sample-post.html b/test/sample-post.html
new file mode 100644 (file)
index 0000000..c9decdc
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+  <head>
+    <title>Sample Post test</title>
+  <body>
+    <h1>Sample Post test</h1>
+    <ol>
+     <li><a href="api/post/upload-json">upload json</a>
+     <li><a href="api/post/upload-image">upload json</a>
+     <li><a href="api/post/upload-music">upload json</a>
+     <li><a href="api/post/upload-appli">upload json</a>
diff --git a/test/websock.html b/test/websock.html
new file mode 100644 (file)
index 0000000..1db33b2
--- /dev/null
@@ -0,0 +1,47 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+  <head>
+    <title>WebSocket Echo</title>
+    <script type="text/javascript">
+    <!--
+      var ws;
+
+      if ((typeof(WebSocket) == 'undefined') &&
+          (typeof(MozWebSocket) != 'undefined')) {
+        WebSocket = MozWebSocket;
+      }
+
+      function init() {
+        ws = new WebSocket("ws://localhost:1234/api/");
+        ws.onopen = function(event) {
+          document.getElementById("main").style.visibility = "visible";
+          document.getElementById("connected").innerHTML = "Connected to WebSocket server";
+        };
+        ws.onmessage = function(event) {
+          document.getElementById("output").innerHTML = event.data;
+        };
+        ws.onerror = function(event) { alert("Received error"); };
+        ws.onclose = function(event) {
+          ws = null;
+          document.getElementById("main").style.visibility = "hidden";
+          document.getElementById("connected").innerHTML = "Connection Closed";
+        }
+      }
+
+      function send(message) {
+        if (ws) {
+          ws.send(message);
+        }
+      }
+    // -->
+    </script>
+  </head>
+  <body onload="init();">
+    <h1>WebSocket Echo</h1>
+    <div id="connected">Not Connected</div>
+    <div id="main" style="visibility:hidden">
+    Enter Message: <input type="text" name="message" value="" size="80" onchange="send(this.value)"/><br/>
+    Server says... <div id="output"></div>
+    </div>
+  </body>
+</html>