Sun, 30 Dec 2012 15:49:44 +0100
added mime type configuration file
--- a/Makefile Sat Dec 29 18:08:23 2012 +0100 +++ b/Makefile Sun Dec 30 15:49:44 2012 +0100 @@ -41,14 +41,15 @@ @echo "install Webserver to $(WS_INSTALL_DIR)" mkdir -p $(WS_INSTALL_DIR)bin mkdir -p $(WS_INSTALL_DIR)lib - mkdir -p $(WS_INSTALL_DIR)conf + mkdir -p $(WS_INSTALL_DIR)config mkdir -p $(WS_INSTALL_DIR)docs mkdir -p $(WS_INSTALL_DIR)logs mkdir -p $(WS_INSTALL_DIR)include @echo "copy config" - cp templates/conf/init.conf $(WS_INSTALL_DIR)conf/init.conf - cp templates/conf/obj.conf $(WS_INSTALL_DIR)conf/obj.conf - cp templates/conf/server.conf $(WS_INSTALL_DIR)conf/server.conf + cp templates/config/init.conf $(WS_INSTALL_DIR)config/init.conf + cp templates/config/obj.conf $(WS_INSTALL_DIR)config/obj.conf + cp templates/config/server.conf $(WS_INSTALL_DIR)config/server.conf + cp templates/config/mime.types $(WS_INSTALL_DIR)config/mime.types @echo "copy binaries" mv work/bin/webservd work/bin/webservd.bin cp work/bin/webservd.bin $(WS_INSTALL_DIR)bin/webservd
--- a/src/server/config/conf.c Sat Dec 29 18:08:23 2012 +0100 +++ b/src/server/config/conf.c Sun Dec 30 15:49:44 2012 +0100 @@ -229,8 +229,15 @@ break; // end of value } } - value->length = i - name->length - 2; - i++; + + if(quote) { + // if the value is quoted, i points to the last quote char + value->length = i - name->length - 2; // subtract the quotes + i++; // set i behind the last quote + } else { + // i points to a white space char, which must be subtraced + value->length = i - name->length - 1; + } if(value->length <= 0) { value->length = 0; @@ -333,7 +340,6 @@ if(pname.length <= 0) { break; } - // create param object ConfigParam *param = OBJ_NEW(mp, ConfigParam);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/server/config/mimeconf.c Sun Dec 30 15:49:44 2012 +0100 @@ -0,0 +1,97 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "mimeconf.h" + +MimeConfig *load_mime_config(char *file) { + FILE *in = fopen(file, "r"); + if(in == NULL) { + return NULL; + } + + MimeConfig *conf = malloc(sizeof(MimeConfig)); + conf->parser.parse = mimeconf_parse; + conf->file = file; + conf->directives = NULL; + conf->ntypes = 0; + + int r = cfg_parse_basic_file((ConfigParser*)conf, in); + if(r != 0) { + // TODO: free + return NULL; + } + + return conf; +} + +void free_mime_config(MimeConfig *conf) { + if(conf->directives != NULL) { + ucx_list_free(conf->directives); + } + if(conf->parser.lines != NULL) { + ucx_dlist_free(conf->parser.lines); + } + ucx_mempool_free(conf->parser.mp); + free(conf); +} + +int mimeconf_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line) { + MimeConfig *conf = p; + UcxMempool *mp = conf->parser.mp; + + // parse mime directive + MimeDirective *dir = ucx_mempool_calloc(mp, 1, sizeof(MimeDirective)); + + UcxList *params = cfg_param_list(line, mp); + UCX_FOREACH(UcxList*, params, pl) { + ConfigParam *param = pl->data; + + if(!sstrcmp(param->name, sstr("type"))) { + dir->type = param->value; + } else if(!sstrcmp(param->name, sstr("exts"))) { + // comma-separated file extensions + + size_t nx = 0; + sstr_t *exts = sstrsplit(param->value, sstrn(",", 1), &nx); + for(int i=0;i<nx;i++) { + dir->exts = ucx_list_append(dir->exts, exts[i].ptr); + } + + free(exts); + } + } + + conf->directives = ucx_list_append(conf->directives, dir); + conf->ntypes++; + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/server/config/mimeconf.h Sun Dec 30 15:49:44 2012 +0100 @@ -0,0 +1,61 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MIMECONF_H +#define MIMECONF_H + +#include "conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _mime_conf { + ConfigParser parser; + char *file; + UcxList *directives; // MimeDirective list + int ntypes; +} MimeConfig; + +typedef struct _mime_dir { + sstr_t type; + UcxList *exts; // char* +} MimeDirective; + +MimeConfig *load_mime_config(char *file); + +void free_mime_config(MimeConfig *conf); + +int mimeconf_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line); + +#ifdef __cplusplus +} +#endif + +#endif /* MIMECONF_H */ +
--- a/src/server/config/objs.mk Sat Dec 29 18:08:23 2012 +0100 +++ b/src/server/config/objs.mk Sun Dec 30 15:49:44 2012 +0100 @@ -34,6 +34,7 @@ CONFOBJ += conf.o CONFOBJ += initconf.o CONFOBJ += serverconf.o +CONFOBJ += mimeconf.o CONFOBJS = $(CONFOBJ:%=$(CONF_OBJPRE)%) CONFSOURCE = $(CONFOBJ:%.o=config/%.c)
--- a/src/server/daemon/config.c Sat Dec 29 18:08:23 2012 +0100 +++ b/src/server/daemon/config.c Sun Dec 30 15:49:44 2012 +0100 @@ -246,7 +246,30 @@ cfg->tmp = sstrdup(cfg_directivelist_get_str( obj->directives, sstr("Temp"))); - + + // mime file + sstr_t mf = cfg_directivelist_get_str(obj->directives, sstr("MimeFile")); + + sstr_t base = sstr("config/"); + sstr_t file; + file.length = base.length + mf.length + 1; + file.ptr = alloca(file.length); + file.ptr[file.length] = 0; + file = sstrncat(2, file, base, mf); + + ConfigFile *f = cfgmgr_get_file(file); + if(f == NULL) { + f = malloc(sizeof(ConfigFile)); + f->file = sstrdup(file); + f->reload = mime_conf_reload; + + // load the file content + f->reload(f, cfg); + cfgmgr_attach_file(f); + } + + cfg->mimetypes = f->data; // TODO: ref + return 0; } @@ -453,7 +476,7 @@ sstr_t objfile = cfg_directivelist_get_str( obj->directives, sstr("ObjectFile")); - sstr_t base = sstr("conf/"); + sstr_t base = sstr("config/"); sstr_t file; file.length = base.length + objfile.length + 1; file.ptr = alloca(file.length); @@ -572,3 +595,23 @@ return conf; } + +int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { + MimeConfig *mimecfg = load_mime_config(file->file.ptr); + + UcxMap *mimemap = ucx_map_new((mimecfg->ntypes * 3) / 2); + + // add ext type pairs + UCX_FOREACH(UcxList*, mimecfg->directives, md) { + MimeDirective *d = md->data; + // add the type for each extension to the map + UCX_FOREACH(UcxList*, d->exts, xl) { + sstr_t ext = sstr(xl->data); + sstr_t value = sstrdup(d->type); + ucx_map_sstr_put(mimemap, ext, value.ptr); + } + } + + file->data = mimemap; + return 0; +}
--- a/src/server/daemon/config.h Sat Dec 29 18:08:23 2012 +0100 +++ b/src/server/daemon/config.h Sun Dec 30 15:49:44 2012 +0100 @@ -36,6 +36,7 @@ #include "../config/objconf.h" #include "../config/initconf.h" #include "../config/serverconf.h" +#include "../config/mimeconf.h" #include "../ucx/list.h" #include "../ucx/dlist.h" @@ -54,6 +55,7 @@ UcxList *listeners; // list of all listeners UcxList *logfiles; UcxMap *authdbs; + UcxMap *mimetypes; sstr_t tmp; sstr_t user; uint32_t ref; // reference counter @@ -98,6 +100,8 @@ HTTPObjectConfig* load_obj_conf(char *file); +int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg); + #ifdef __cplusplus
--- a/src/server/daemon/configmanager.c Sat Dec 29 18:08:23 2012 +0100 +++ b/src/server/daemon/configmanager.c Sun Dec 30 15:49:44 2012 +0100 @@ -118,8 +118,8 @@ } struct stat s; - if(stat("conf/server.conf", &s) != 0) { - perror("stat(\"conf/server.conf\")"); + if(stat("config/server.conf", &s) != 0) { + perror("stat(\"config/server.conf\")"); return -1; } @@ -128,7 +128,7 @@ printf("cfgmgr load server.conf\n"); config = load_server_conf( current_config, - "conf/server.conf"); + "config/server.conf"); if(config == NULL) { fprintf(stderr, "Cannot load server.conf\n"); @@ -144,7 +144,7 @@ /* config = load_server_conf( current_config, - "conf/server.conf"); + "config/server.conf"); */ config = malloc(sizeof(ServerConfiguration)); config->ref = 1; @@ -152,7 +152,7 @@ config->user = sstrdup_pool(config->pool, current_config->user); config->tmp = sstrdup_pool(config->pool, current_config->tmp); - // copy configuration + // copy configuration config->host_vs = ucx_map_clone( current_config->host_vs, copy_vs, @@ -163,7 +163,9 @@ (copy_func)copy_listener, config); - + // TODO: we need to get the mime map from the configfile data + config->mimetypes = current_config->mimetypes; + if(config == NULL) { fprintf(stderr, "Cannot load server.conf\n"); return -1;
--- a/src/server/daemon/webserver.c Sat Dec 29 18:08:23 2012 +0100 +++ b/src/server/daemon/webserver.c Sun Dec 30 15:49:44 2012 +0100 @@ -55,7 +55,7 @@ add_functions(webserver_funcs); // load init.conf - load_init_conf("conf/init.conf"); + load_init_conf("config/init.conf"); // load server.conf init_configuration_manager();
--- a/src/server/safs/objecttype.c Sat Dec 29 18:08:23 2012 +0100 +++ b/src/server/safs/objecttype.c Sun Dec 30 15:49:44 2012 +0100 @@ -30,6 +30,9 @@ #include "../util/pblock.h" #include "../ucx/string.h" +#include "../ucx/map.h" +#include "../daemon/config.h" +#include "../daemon/session.h" int object_type_by_extension(pblock *pb, Session *sn, Request *rq) { sstr_t ppath = sstr(pblock_findkeyval(pb_key_ppath, rq->vars)); @@ -55,18 +58,16 @@ return REQ_NOACTION; } - /* TODO: we need a map for extensions/types */ - if(!sstrcmp(ext, sstrn("txt", 3))) { - ct = sstr("text/plain"); - } else if(!sstrcmp(ext, sstrn("htm", 3))) { - ct = sstr("text/html"); - } else if(!sstrcmp(ext, sstrn("html", 4))) { - ct = sstr("text/html"); - } else if(!sstrcmp(ext, sstrn("xml", 3))) { - ct = sstr("text/xml"); - } else { + /* get the mime type for the ext from the server configuration */ + ServerConfiguration *config = session_get_config(sn); + char *type = ucx_map_sstr_get(config->mimetypes, ext); + + if(!type) { return REQ_NOACTION; } + + ct.ptr = type; + ct.length = strlen(type); } pblock_kvinsert(pb_key_content_type, ct.ptr, ct.length, rq->srvhdrs);
--- a/templates/conf/init.conf Sat Dec 29 18:08:23 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -# -# init.conf -# - -Init fn="init-test" -
--- a/templates/conf/mime.types Sat Dec 29 18:08:23 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -type=image/png exts=png -type=image/x-icon exts=ico -type=image/gif exts=gif -type=image/jpeg exts=jpeg,jpg,jpe,jfif,pjpeg,pjp -type=image/tiff exts=tiff,tif -type=image/bmp exts=bmp -type=application/pdf exts=pdf -type=application/postscript exts=ai,eps,ps -type=application/x-sh exts=sh -type=text/css exts=css -type=text/html exts=htm,html -type=text/plain exts=txt -type=text/xml exts=xml -type=application/x-javascript exts=js -type=application/x-javascript;charset=UTF-8 exts=jsu -type=application/x-tex exts=tex
--- a/templates/conf/obj.conf Sat Dec 29 18:08:23 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -# -# obj.conf -# -# NSAPI configuration -# - -<Object name="default"> -NameTrans fn="assign-name" from="/hello" name="hello" -ObjectType fn="type-by-extension" -Service fn="send-options" method="OPTIONS" -Service fn="common-index" type="internal/directory" -Service fn="send-file" -</Object> - -<Object name="hello"> -Service fn="service-hello" -</Object> -
--- a/templates/conf/server.conf Sat Dec 29 18:08:23 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -# -# server.conf -# - -<Runtime> - Temp /tmp/webserver-rw6pgl8b/ - User webservd -</Runtime> - -<LogFile> - File logs/errors - Level INFO -</LogFile> - -<EventHandler> - Name default - Threads 1 - Default true -</EventHandler> - -<Threadpool> - Name default - MinThreads 4 - MaxThreads 32 -</Threadpool> - -<AuthDB> - Name keyfile - Type keyfile -</AuthDB> - -<Listener> - Name http-listener-1 - Port 9090 - DefaultVS x4 -</Listener> - -<Listener> - Name http-listener-2 - Port 9091 - DefaultVS x4 -</Listener> - -<VirtualServer> - Name x4 - Host x4 - Listener http-listener-1 - Listener http-listener-2 - ObjectFile obj.conf - ACLFile acl.conf - DAVFile dav.conf - DocRoot docs/ -</VirtualServer> - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/config/init.conf Sun Dec 30 15:49:44 2012 +0100 @@ -0,0 +1,6 @@ +# +# init.conf +# + +Init fn="init-test" +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/config/mime.types Sun Dec 30 15:49:44 2012 +0100 @@ -0,0 +1,16 @@ +type=image/png exts=png +type=image/x-icon exts=ico +type=image/gif exts=gif +type=image/jpeg exts=jpeg,jpg,jpe,jfif,pjpeg,pjp +type=image/tiff exts=tiff,tif +type=image/bmp exts=bmp +type=application/pdf exts=pdf +type=application/postscript exts=ai,eps,ps +type=application/x-sh exts=sh +type=text/css exts=css +type=text/html exts=htm,html +type=text/plain exts=txt +type=text/xml exts=xml +type=application/x-javascript exts=js +type=application/x-javascript;charset=UTF-8 exts=jsu +type=application/x-tex exts=tex
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/config/obj.conf Sun Dec 30 15:49:44 2012 +0100 @@ -0,0 +1,18 @@ +# +# obj.conf +# +# NSAPI configuration +# + +<Object name="default"> +NameTrans fn="assign-name" from="/hello" name="hello" +ObjectType fn="type-by-extension" +Service fn="send-options" method="OPTIONS" +Service fn="common-index" type="internal/directory" +Service fn="send-file" +</Object> + +<Object name="hello"> +Service fn="service-hello" +</Object> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/config/server.conf Sun Dec 30 15:49:44 2012 +0100 @@ -0,0 +1,56 @@ +# +# server.conf +# + +<Runtime> + Temp /tmp/webserver-rw6pgl8b/ + User webservd + MimeFile mime.types +</Runtime> + +<LogFile> + File logs/errors + Level INFO +</LogFile> + +<EventHandler> + Name default + Threads 1 + Default true +</EventHandler> + +<Threadpool> + Name default + MinThreads 4 + MaxThreads 32 +</Threadpool> + +<AuthDB> + Name keyfile + Type keyfile +</AuthDB> + +<Listener> + Name http-listener-1 + Port 9090 + DefaultVS x4 +</Listener> + +<Listener> + Name http-listener-2 + Port 9091 + DefaultVS x4 +</Listener> + +<VirtualServer> + Name x4 + Host x4 + Listener http-listener-1 + Listener http-listener-2 + ObjectFile obj.conf + ACLFile acl.conf + DAVFile dav.conf + DocRoot docs/ +</VirtualServer> + +