X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fhttp-svc.c;h=034753f461eeb962b34b76fbd206a4594029f310;hb=8e61a22b3d7219c59f3925ac8e173b9b74fbcf30;hp=d638f6e93b58f7b22885a1f751191f6ad3996873;hpb=c2bda43c447016a20ed061078b0dff3e64d09940;p=src%2Fapp-framework-binder.git diff --git a/src/http-svc.c b/src/http-svc.c index d638f6e9..034753f4 100644 --- a/src/http-svc.c +++ b/src/http-svc.c @@ -38,6 +38,7 @@ // 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); @@ -45,27 +46,25 @@ 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; -// try to open libmagic to handle mine types +// try to open libmagic to handle mime types static AFB_error initLibMagic (AFB_session *session) { - const char *magic_full; /*MAGIC_MIME tells magic to return a mime of the file, but you can specify different things*/ if (verbose) printf("Loading mimetype default magic database\n"); - session->magic = magic_open(MAGIC_MIME); + session->magic = magic_open(MAGIC_MIME_TYPE); if (session->magic == NULL) { fprintf(stderr,"ERROR: unable to initialize magic library\n"); return AFB_FAIL; } - if (magic_load(session->magic, NULL) != 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); return AFB_FAIL; } - - //usage - //magic_full = magic_file(magic_cookie, actual_file); - //printf("%s\n", magic_full); + return AFB_SUCCESS; } @@ -98,28 +97,40 @@ STATIC int servFile (struct MHD_Connection *connection, AFB_session *session, co if (fstat (staticfile->fd, &sbuf) != 0) { fprintf(stderr, "Fail to stat file: [%s] error:%s\n", staticfile->path, strerror(errno)); - return (FAILED); + goto abortRequest; } + + + + // if url is a directory let's add index.html and redirect client if (S_ISDIR (sbuf.st_mode)) { - if (url [strlen (url) -1] != '/') strncat (staticfile->path, "/", sizeof (staticfile->path)); - strncat (staticfile->path, "index.html", sizeof (staticfile->path)); - close (staticfile->fd); // close directory try to open index.html + close (staticfile->fd); // close directory check for Index + + // 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); + strncat(staticfile->path, "/", sizeof (staticfile->path)); + MHD_add_response_header (response, "Location", staticfile->path); + MHD_queue_response (connection, MHD_HTTP_MOVED_PERMANENTLY, response); + if (verbose) fprintf (stderr,"Adding trailing '/' [%s]\n",staticfile->path); + goto sendRequest; + } + + strncat (staticfile->path, OPA_INDEX, sizeof (staticfile->path)); 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); - return (FAILED); - } - - } else if (! S_ISREG (sbuf.st_mode)) { // only standard file any other one including symbolic links are refused. - + 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); - const char *errorstr = "Alsa-Json-Gateway Invalid file type"; + const char *errorstr = "Application Framework Binder Invalid file type"; response = MHD_create_response_from_buffer (strlen (errorstr), (void *) errorstr, MHD_RESPMEM_PERSISTENT); MHD_queue_response (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, response); - goto finishJob; - + goto sendRequest; } // https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=fr @@ -139,83 +150,80 @@ STATIC int servFile (struct MHD_Connection *connection, AFB_session *session, co } else { // it's a new file, we need to upload it to client // if we have magic let's try to guest mime type - if (session->magic) { - mimetype="Unknown"; + if (session->magic) { mimetype= magic_descriptor(session->magic, staticfile->fd); if (mimetype != NULL) MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE, mimetype); - }; - if (verbose) fprintf(stderr, "Serving: [%s] mine=%s\n", staticfile->path, mimetype); + } else mimetype="Unknown"; + + if (verbose) fprintf(stderr, "Serving: [%s] mime=%s\n", staticfile->path, mimetype); response = MHD_create_response_from_fd(sbuf.st_size, staticfile->fd); MHD_add_response_header(response, MHD_HTTP_HEADER_CACHE_CONTROL, session->cacheTimeout); // default one hour cache MHD_add_response_header(response, MHD_HTTP_HEADER_ETAG, etagValue); MHD_queue_response(connection, MHD_HTTP_OK, response); } -finishJob: +sendRequest: MHD_destroy_response(response); return (MHD_YES); + +abortRequest: + return (FAILED); } -// minimal httpd file server for static HTML,JS,CSS,etc... -STATIC int requestFile(struct MHD_Connection *connection, AFB_session *session, const char* url) { + +// 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; - // build full path from rootdir + url + // Url match /opa/xxxx should redirect to "/opa/#!page" to force index.html reload + strncpy(staticfile.path, session->config->rootbase, sizeof (staticfile.path)); + strncat(staticfile.path, "/#!", sizeof (staticfile.path)); + strncat(staticfile.path, &url[1], sizeof (staticfile.path)); + response = MHD_create_response_from_buffer(0,"", MHD_RESPMEM_PERSISTENT); + MHD_add_response_header (response, "Location", staticfile.path); + MHD_queue_response (connection, MHD_HTTP_MOVED_PERMANENTLY, response); + if (verbose) fprintf (stderr,"checkHTML5 redirect to [%s]\n",staticfile.path); + return (MHD_YES); +} - strncpy(staticfile.path, session->config->rootdir, sizeof (staticfile.path)); - strncat(staticfile.path, url, sizeof (staticfile.path)); +// 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; + AFB_staticfile staticfile; + char *requestdir, *requesturl; + + // default search for file is rootdir base + requestdir= session->config->rootdir; + requesturl=(char*)url; + + // Check for optional aliases + for (idx=0; session->config->aliasdir[idx].url != NULL; idx++) { + if (0 == strncmp(url, session->config->aliasdir[idx].url, session->config->aliasdir[idx].len)) { + requestdir = session->config->aliasdir[idx].path; + requesturl=(char*)&url[session->config->aliasdir[idx].len]; + break; + } + } + + // build full path from rootdir + url + strncpy(staticfile.path, requestdir, sizeof (staticfile.path)); + strncat(staticfile.path, requesturl, sizeof (staticfile.path)); // try to open file and get its size if (-1 == (staticfile.fd = open(staticfile.path, O_RDONLY))) { fprintf(stderr, "Fail to open file: [%s] error:%s\n", staticfile.path, strerror(errno)); return (FAILED); - } // open file is OK let use it ret = servFile (connection, session, url, &staticfile); return ret; } -// this function return either Index.htlm or a redirect to /#!route to make angular happy -STATIC int checkHTML5(struct MHD_Connection *connection, AFB_session *session, const char* url) { - - int fd; - int ret; - struct MHD_Response *response; - AFB_staticfile staticfile; - - // Any URL prefixed with /rootbase is served with index.html ex: /opa,/opa/,/opa/#!xxxxxx - if ( url[0] == '\0' || url[1] == '\0' || url[1] == '#') { - strncpy(staticfile.path, session->config->rootdir, sizeof (staticfile.path)); - strncat(staticfile.path, "/index.html", sizeof (staticfile.path)); - // try to open file and get its size - if (-1 == (staticfile.fd = open(staticfile.path, O_RDONLY))) { - fprintf(stderr, "Fail to open file: [%s] error:%s\n", staticfile.path, strerror(errno)); - // Nothing respond to this request Files, API, Angular Base - const char *errorstr = "Application Framework OPA/index.html Not found"; - response = MHD_create_response_from_buffer(strlen(errorstr),(void *)errorstr, MHD_RESPMEM_PERSISTENT); - MHD_queue_response(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, response); - return (MHD_YES); - } else { - ret = servFile (connection, session, url, &staticfile); - return ret; - } - } - - // Url match /opa/xxxx but not /opa#!xxxx we redirect the URL to /opa#!/xxxx to force index.html reload - strncpy(staticfile.path, session->config->rootbase, sizeof (staticfile.path)); - strncat(staticfile.path, "#!", sizeof (staticfile.path)); - strncat(staticfile.path, url, sizeof (staticfile.path)); - response = MHD_create_response_from_buffer(0,"", MHD_RESPMEM_PERSISTENT); - MHD_add_response_header (response, "Location", staticfile.path); - MHD_queue_response (connection, MHD_HTTP_MOVED_PERMANENTLY, response); - if (verbose) fprintf (stderr,"checkHTML5 redirect to [%s]\n",staticfile.path); - return (MHD_YES); -} - // Check and Dispatch HTTP request STATIC int newRequest(void *cls, struct MHD_Connection *connection, @@ -230,7 +238,7 @@ STATIC int newRequest(void *cls, // this is a REST API let's check for plugins if (0 == strncmp(url, session->config->rootapi, apiUrlLen)) { - ret = doRestApi(connection, session, method, &url[apiUrlLen+1]); + ret = doRestApi(connection, session, &url[apiUrlLen+1], method, upload_data, upload_data_size, con_cls); return ret; } @@ -241,9 +249,9 @@ STATIC int newRequest(void *cls, ret = requestFile(connection, session, url); if (ret != FAILED) return ret; - // no static was served let check for Angular redirect + // no static was served let's try HTML5 OPA redirect if (0 == strncmp(url, session->config->rootbase, baseUrlLen)) { - ret = checkHTML5(connection, session, &url[baseUrlLen]); + ret = redirectHTML5(connection, session, &url[baseUrlLen]); return ret; } @@ -265,9 +273,10 @@ PUBLIC AFB_error httpdStart(AFB_session *session) { // compute fixed URL length at startup time apiUrlLen = strlen (session->config->rootapi); baseUrlLen= strlen (session->config->rootbase); - - // open libmagic cache - initLibMagic (session); + rootUrlLen= strlen (session->config->rootdir); + + // TBD open libmagic cache [fail to pass EFENCE check] + // initLibMagic (session); if (verbose) { @@ -299,7 +308,7 @@ PUBLIC AFB_error httpdLoop(AFB_session *session) { if (session->foreground) { while (TRUE) { - fprintf(stderr, "AFB:notice Use Ctrl-C to quit"); + fprintf(stderr, "AFB:notice Use Ctrl-C to quit\n"); (void) getc(stdin); } } else {