X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fhttp-svc.c;h=71e0a08f95c4823f4485c359552ebbdb6cb69e83;hb=c2560bd51498fb38e645b60ae638e2e888c74b65;hp=e8f2c0e508854128f2a489fbcd228036a334950c;hpb=accb3215b180f8e386f896ba0368b7188eaa190e;p=src%2Fapp-framework-binder.git diff --git a/src/http-svc.c b/src/http-svc.c index e8f2c0e5..71e0a08f 100644 --- a/src/http-svc.c +++ b/src/http-svc.c @@ -29,22 +29,18 @@ POST https://www.gnu.org/software/libmicrohttpd/manual/html_node/microhttpd_002dpost.html#microhttpd_002dpost */ +#define _GNU_SOURCE #include +#include #include #include "../include/local-def.h" // let's compute fixed URL length only once -static apiUrlLen=0; -static baseUrlLen=0; -static rootUrlLen=0; - -// proto missing from GCC -char *strcasestr(const char *haystack, const char *needle); - -static int rqtcount = 0; // dummy request rqtcount to make each message be different -static int postcount = 0; +static size_t apiUrlLen=0; +static size_t baseUrlLen=0; +static size_t rootUrlLen=0; // try to open libmagic to handle mime types static AFB_error initLibMagic (AFB_session *session) { @@ -70,30 +66,25 @@ static AFB_error initLibMagic (AFB_session *session) { // Because of POST call multiple time requestApi we need to free POST handle here static void endRequest (void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe) { - AFB_HttpPost *posthandle = *con_cls; + AFB_PostHandle *posthandle = *con_cls; // if post handle was used let's free everything - if (posthandle) { - if (verbose) fprintf (stderr, "End Post Request UID=%d\n", posthandle->uid); - free (posthandle->data); - free (posthandle); - } + if (posthandle != NULL) endPostRequest (posthandle); } // Create check etag value -STATIC void computeEtag(char *etag, int maxlen, struct stat *sbuf) { - int time; +STATIC void computeEtag(char *etag, size_t maxlen, struct stat *sbuf) { + long time; time = sbuf->st_mtim.tv_sec; - snprintf(etag, maxlen, "%d", time); + snprintf(etag, maxlen, "%ld", time); } STATIC int servFile (struct MHD_Connection *connection, AFB_session *session, const char *url, AFB_staticfile *staticfile) { const char *etagCache, *mimetype; char etagValue[15]; - struct MHD_Response *response; + struct MHD_Response *response = NULL; struct stat sbuf; - int ret; if (fstat (staticfile->fd, &sbuf) != 0) { fprintf(stderr, "Fail to stat file: [%s] error:%s\n", staticfile->path, strerror(errno)); @@ -107,6 +98,7 @@ STATIC int servFile (struct MHD_Connection *connection, AFB_session *session, co // No trailing '/'. Let's add one and redirect for relative paths to work if (url [strlen (url) -1] != '/') { response = MHD_create_response_from_buffer(0,"", MHD_RESPMEM_PERSISTENT); + strncpy(staticfile->path, url, sizeof (staticfile->path)); strncat(staticfile->path, "/", sizeof (staticfile->path)); MHD_add_response_header (response, "Location", staticfile->path); MHD_queue_response (connection, MHD_HTTP_MOVED_PERMANENTLY, response); @@ -118,7 +110,7 @@ STATIC int servFile (struct MHD_Connection *connection, AFB_session *session, co if (-1 == (staticfile->fd = open(staticfile->path, O_RDONLY)) || (fstat (staticfile->fd, &sbuf) != 0)) { fprintf(stderr, "No Index.html in direcory [%s]\n", staticfile->path); goto abortRequest; - } + } } else if (! S_ISREG (sbuf.st_mode)) { // only standard file any other one including symbolic links are refused. close (staticfile->fd); // nothing useful to do with this file fprintf (stderr, "Fail file: [%s] is not a regular file\n", staticfile->path); @@ -149,7 +141,7 @@ STATIC int servFile (struct MHD_Connection *connection, AFB_session *session, co if (session->magic) { mimetype= magic_descriptor(session->magic, staticfile->fd); if (mimetype != NULL) MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE, mimetype); - } else mimetype="Unknown"; + } else mimetype="application/unknown"; if (verbose) fprintf(stderr, "Serving: [%s] mime=%s\n", staticfile->path, mimetype); response = MHD_create_response_from_fd(sbuf.st_size, staticfile->fd); @@ -170,8 +162,6 @@ abortRequest: // this function return either Index.htlm or a redirect to /#!route to make angular happy STATIC int redirectHTML5(struct MHD_Connection *connection, AFB_session *session, const char* url) { - int fd; - int ret; struct MHD_Response *response; AFB_staticfile staticfile; @@ -189,7 +179,7 @@ STATIC int redirectHTML5(struct MHD_Connection *connection, AFB_session *session // minimal httpd file server for static HTML,JS,CSS,etc... STATIC int requestFile(struct MHD_Connection *connection, AFB_session *session, const char* url) { - int fd, ret, idx; + int ret, idx; AFB_staticfile staticfile; char *requestdir, *requesturl; @@ -252,7 +242,7 @@ STATIC int newRequest(void *cls, } // Nothing respond to this request Files, API, Angular Base - const char *errorstr = "Alsa-Json-Gateway Unknown or Not readable file"; + const char *errorstr = "AFB-Daemon File Not Find file"; response = MHD_create_response_from_buffer(strlen(errorstr), (void*)errorstr, MHD_RESPMEM_PERSISTENT); ret = MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, response); return (MHD_YES); @@ -265,14 +255,17 @@ STATIC int newClient(void *cls, const struct sockaddr * addr, socklen_t addrlen) PUBLIC AFB_error httpdStart(AFB_session *session) { - + // compute fixed URL length at startup time apiUrlLen = strlen (session->config->rootapi); baseUrlLen= strlen (session->config->rootbase); rootUrlLen= strlen (session->config->rootdir); + + // Initialise Client Session Hash Table + ctxStoreInit (CTX_NBCLIENTS); - // TBD open libmagic cache [fail to pass EFENCE check] - // initLibMagic (session); + //TBD open libmagic cache [fail to pass EFENCE check (allocating 0 bytes)] + //initLibMagic (session); if (verbose) { @@ -281,12 +274,16 @@ PUBLIC AFB_error httpdStart(AFB_session *session) { } session->httpd = (void*) MHD_start_daemon( - MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, // use request and not threads - session->config->httpdPort, // port + MHD_USE_EPOLL_LINUX_ONLY + | MHD_USE_TCP_FASTOPEN + | MHD_USE_DEBUG + , + (uint16_t)session->config->httpdPort, // port &newClient, NULL, // Tcp Accept call back + extra attribute &newRequest, session, // Http Request Call back + extra attribute MHD_OPTION_NOTIFY_COMPLETED, &endRequest, NULL, - MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15, MHD_OPTION_END); // 15s + options-end + MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15, // 15 seconds + MHD_OPTION_END); // options-end // TBD: MHD_OPTION_SOCK_ADDR if (session->httpd == NULL) { @@ -298,22 +295,27 @@ PUBLIC AFB_error httpdStart(AFB_session *session) { // infinite loop PUBLIC AFB_error httpdLoop(AFB_session *session) { - static int count = 0; + int count = 0; + const union MHD_DaemonInfo *info; + struct pollfd pfd; + + info = MHD_get_daemon_info(session->httpd, + MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY); + if (info == NULL) { + printf("Error: httpLoop no pollfd"); + goto error; + } + pfd.fd = info->listen_fd; + pfd.events = POLLIN; if (verbose) fprintf(stderr, "AFB:notice entering httpd waiting loop\n"); - if (session->foreground) { - - while (TRUE) { - fprintf(stderr, "AFB:notice Use Ctrl-C to quit\n"); - (void) getc(stdin); - } - } else { - while (TRUE) { - sleep(3600); - if (verbose) fprintf(stderr, "AFB:notice httpd alive [%d]\n", count++); - } + while (TRUE) { + if (verbose) fprintf(stderr, "AFB:notice httpd alive [%d]\n", count++); + poll(&pfd, 1, 15000); // 15 seconds (as above timeout when starting) + MHD_run(session->httpd); } +error: // should never return from here return AFB_FATAL; }