allows connection to upgrade
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 5 Apr 2016 14:10:01 +0000 (16:10 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Tue, 5 Apr 2016 14:10:01 +0000 (16:10 +0200)
Change-Id: I2e174b67ea186180da0d8982fac14f468946dc14
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/afb-hreq.c
src/afb-hreq.h
src/afb-hsrv.c
src/afb-hsrv.h [new file with mode: 0644]
src/local-def.h
src/main.c
src/utils-upoll.c

index b4fe292..087a27c 100644 (file)
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#define USE_MAGIC_MIME_TYPE
 #define _GNU_SOURCE
 
 #include <stdlib.h>
 
 #include <microhttpd.h>
 
+#if defined(USE_MAGIC_MIME_TYPE)
+#include <magic.h>
+#endif
+
 #include "local-def.h"
 #include "afb-method.h"
 #include "afb-req-itf.h"
@@ -136,6 +141,51 @@ static int validsubpath(const char *subpath)
        return 1;
 }
 
+#if defined(USE_MAGIC_MIME_TYPE)
+
+#if !defined(MAGIC_DB)
+#define MAGIC_DB "/usr/share/misc/magic.mgc"
+#endif
+
+static magic_t lazy_libmagic()
+{
+       static int done = 0;
+       static magic_t result = NULL;
+
+       if (!done) {
+               done = 1;
+               /* MAGIC_MIME tells magic to return a mime of the file,
+                        but you can specify different things */
+               if (verbosity)
+                       printf("Loading mimetype default magic database\n");
+
+               result = magic_open(MAGIC_MIME_TYPE);
+               if (result == NULL) {
+                       fprintf(stderr,"ERROR: unable to initialize magic library\n");
+               }
+               /* Warning: should not use NULL for DB
+                               [libmagic bug wont pass efence check] */
+               else if (magic_load(result, MAGIC_DB) != 0) {
+                       fprintf(stderr,"cannot load magic database - %s\n",
+                                       magic_error(result));
+                       magic_close(result);
+                       result = NULL;
+               }
+       }
+
+       return result;
+}
+
+static const char *magic_mimetype_fd(int fd)
+{
+       magic_t lib = lazy_libmagic();
+       return lib ? magic_descriptor(lib, fd) : NULL;
+}
+
+#endif
+
+
+
 void afb_hreq_free(struct afb_hreq *hreq)
 {
        struct hreq_data *data;
@@ -288,8 +338,8 @@ int afb_hreq_reply_file_if_exist(struct afb_hreq *hreq, int dirfd, const char *f
 
 #if defined(USE_MAGIC_MIME_TYPE)
                /* set the type */
-               if (hreq->session->magic) {
-                       const char *mimetype = magic_descriptor(hreq->session->magic, fd);
+               {
+                       const char *mimetype = magic_mimetype_fd(fd);
                        if (mimetype != NULL)
                                MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mimetype);
                }
index cf23638..853190a 100644 (file)
@@ -30,6 +30,7 @@ struct afb_hreq {
        struct MHD_PostProcessor *postform;
        struct AFB_clientCtx *context;
        struct hreq_data *data;
+       int upgrade;
 };
 
 extern void afb_hreq_free(struct afb_hreq *request);
index a358cbd..b5e6887 100644 (file)
@@ -57,33 +57,6 @@ struct afb_diralias {
 
 static struct upoll *upoll = NULL;
 
-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 struct afb_hsrv_handler *new_handler(
                struct afb_hsrv_handler *head,
                const char *prefix,
@@ -141,6 +114,33 @@ int afb_hsrv_add_handler(
        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;
@@ -366,7 +366,8 @@ static void end_handler(void *cls, struct MHD_Connection *connection, void **rec
        struct afb_hreq *hreq;
 
        hreq = *recordreq;
-
+       if (hreq->upgrade)
+               MHD_suspend_connection (connection);
        afb_hreq_free(hreq);
 }
 
@@ -375,36 +376,6 @@ static int new_client_handler(void *cls, const struct sockaddr *addr, socklen_t
        return MHD_YES;
 }
 
-#if defined(USE_MAGIC_MIME_TYPE)
-
-#if !defined(MAGIC_DB)
-#define MAGIC_DB "/usr/share/misc/magic.mgc"
-#endif
-
-static int init_lib_magic (AFB_session *session)
-{
-       /* MAGIC_MIME tells magic to return a mime of the file, but you can specify different things */
-       if (verbosity)
-               printf("Loading mimetype default magic database\n");
-
-       session->magic = magic_open(MAGIC_MIME_TYPE);
-       if (session->magic == NULL) {
-               fprintf(stderr,"ERROR: unable to initialize magic library\n");
-               return 0;
-       }
-
-       /* Warning: should not use NULL for DB [libmagic bug wont pass efence check] */
-       if (magic_load(session->magic, MAGIC_DB) != 0) {
-               fprintf(stderr,"cannot load magic database - %s\n", magic_error(session->magic));
-               magic_close(session->magic);
-               session->magic = NULL;
-               return 0;
-       }
-
-       return 1;
-}
-#endif
-
 static int my_default_init(AFB_session * session)
 {
        int idx;
@@ -425,11 +396,6 @@ static int my_default_init(AFB_session * session)
        if (!afb_hsrv_add_handler(session, session->config->rootbase, afb_hreq_one_page_api_redirect, NULL, -20))
                return 0;
 
-#if defined(USE_MAGIC_MIME_TYPE)
-       /*TBD open libmagic cache [fail to pass EFENCE check (allocating 0 bytes)] */
-       init_lib_magic (session);
-#endif
-
        return 1;
 }
 
diff --git a/src/afb-hsrv.h b/src/afb-hsrv.h
new file mode 100644 (file)
index 0000000..da4fe09
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ Copyright 2016 IoT.bzh
+
+ author: José Bollo <jose.bollo@iot.bzh>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+int afb_hsrv_start(AFB_session * session);
+void afb_hsrv_stop(AFB_session * session);
index c21918c..5735f6a 100644 (file)
@@ -22,7 +22,6 @@
 #define LOCAL_DEF_H
 
 #include <json.h>
-#include <magic.h>
 #include <microhttpd.h>
 
 /* other definitions --------------------------------------------------- */
@@ -104,7 +103,6 @@ struct AFB_session
   struct MHD_Daemon *httpd;            // structure for httpd handler
   int  fakemod;           // respond to GET/POST request without interacting with sndboard
   int  readyfd;           // a #fd to signal when ready to serve
-  magic_t  magic;         // Mime type file magic lib
   struct afb_hsrv_handler *handlers;
 };
 
index 41296e2..4ea70f9 100644 (file)
@@ -26,7 +26,6 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <stdint.h>
 
 #include "afb-plugin.h"
 
index eb0e967..6db2246 100644 (file)
@@ -99,8 +99,8 @@ struct upoll *upoll_open(int fd, void *closure)
 static int update(struct upoll *upoll)
 {
        struct epoll_event e;
-       e.events = (upoll->read != NULL ? EPOLLIN : 0 )
-                | (upoll->write != NULL ? EPOLLOUT : 0);
+       e.events = (uint32_t)((upoll->read != NULL ? EPOLLIN : 0 )
+                | (upoll->write != NULL ? EPOLLOUT : 0));
        e.data.ptr = upoll;
        return epoll_ctl(pollfd, EPOLL_CTL_MOD, upoll->fd, &e);
 }