aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2016-04-05 16:10:01 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2016-04-05 16:10:01 +0200
commitf113d2b31333538f5784de5ee5f02bc19cc603e4 (patch)
treeb91d53c8a559e315a5ca2ac4ac8ebbca70871fe8
parent13549775092afa9215de8468e34f6d194c2fd8db (diff)
allows connection to upgrade
Change-Id: I2e174b67ea186180da0d8982fac14f468946dc14 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/afb-hreq.c54
-rw-r--r--src/afb-hreq.h1
-rw-r--r--src/afb-hsrv.c92
-rw-r--r--src/afb-hsrv.h20
-rw-r--r--src/local-def.h2
-rw-r--r--src/main.c1
-rw-r--r--src/utils-upoll.c4
7 files changed, 104 insertions, 70 deletions
diff --git a/src/afb-hreq.c b/src/afb-hreq.c
index b4fe2925..087a27ce 100644
--- a/src/afb-hreq.c
+++ b/src/afb-hreq.c
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#define USE_MAGIC_MIME_TYPE
#define _GNU_SOURCE
#include <stdlib.h>
@@ -27,6 +28,10 @@
#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);
}
diff --git a/src/afb-hreq.h b/src/afb-hreq.h
index cf236380..853190a8 100644
--- a/src/afb-hreq.h
+++ b/src/afb-hreq.h
@@ -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);
diff --git a/src/afb-hsrv.c b/src/afb-hsrv.c
index a358cbd7..b5e6887b 100644
--- a/src/afb-hsrv.c
+++ b/src/afb-hsrv.c
@@ -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
index 00000000..da4fe09a
--- /dev/null
+++ b/src/afb-hsrv.h
@@ -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);
diff --git a/src/local-def.h b/src/local-def.h
index c21918cd..5735f6a2 100644
--- a/src/local-def.h
+++ b/src/local-def.h
@@ -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;
};
diff --git a/src/main.c b/src/main.c
index 41296e2c..4ea70f96 100644
--- a/src/main.c
+++ b/src/main.c
@@ -26,7 +26,6 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <stdint.h>
#include "afb-plugin.h"
diff --git a/src/utils-upoll.c b/src/utils-upoll.c
index eb0e9674..6db2246d 100644
--- a/src/utils-upoll.c
+++ b/src/utils-upoll.c
@@ -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);
}