From f113d2b31333538f5784de5ee5f02bc19cc603e4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Tue, 5 Apr 2016 16:10:01 +0200 Subject: [PATCH] allows connection to upgrade MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I2e174b67ea186180da0d8982fac14f468946dc14 Signed-off-by: José Bollo --- src/afb-hreq.c | 54 ++++++++++++++++++++++++++++++-- src/afb-hreq.h | 1 + src/afb-hsrv.c | 92 ++++++++++++++++++------------------------------------- src/afb-hsrv.h | 20 ++++++++++++ src/local-def.h | 2 -- src/main.c | 1 - src/utils-upoll.c | 4 +-- 7 files changed, 104 insertions(+), 70 deletions(-) create mode 100644 src/afb-hsrv.h 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 @@ -27,6 +28,10 @@ #include +#if defined(USE_MAGIC_MIME_TYPE) +#include +#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 + + 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 -#include #include /* 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 #include #include -#include #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); } -- 2.16.6