Tue, 25 Jun 2013 15:45:13 +0200
some fixes
--- a/src/server/daemon/auth.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/auth.c Tue Jun 25 15:45:13 2013 +0200 @@ -41,8 +41,8 @@ printf("auth_cache_init\n"); // TODO: config parameters //pthread_mutex_init(&auth_cache_mutex, NULL); - cache.map = calloc(64, sizeof(UserCacheElm)); - cache.size = 96; + cache.map = calloc(80, sizeof(UserCacheElm)); + cache.size = 80; cache.count = 0; cache.max_users = 64; cache.head = NULL;
--- a/src/server/daemon/config.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/config.c Tue Jun 25 15:45:13 2013 +0200 @@ -434,12 +434,23 @@ return 0; } sstr_t format; - format.ptr = NULL; + format.ptr = NULL; + format.length = 0; - AccessLog *log = get_access_log(file, format); - if(log) { - // access logs are only stored in the server config to free them - cfg->logfiles = ucx_list_append(cfg->logfiles, log); + //AccessLog *log = get_access_log(file, format); + LogFile *log_file = get_access_log_file(file); + if(!log_file) { + // TODO: error/warning + return 0; + } + AccessLog *log = pool_malloc(cfg->pool, sizeof(AccessLog)); + log->file = sstrdup_pool(cfg->pool, file); + log->format = format; + log->log = log_file; + cfg->logfiles = ucx_list_append(cfg->logfiles, log); + + if(!cfg->default_log) { + cfg->default_log = log; } return 0; @@ -632,7 +643,7 @@ // set the access log for the virtual server // TODO: don't use always the default - vs->log = get_default_access_log(); + vs->log = cfg->default_log; ucx_map_sstr_put(cfg->host_vs, vs->host, vs);
--- a/src/server/daemon/config.h Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/config.h Tue Jun 25 15:45:13 2013 +0200 @@ -42,6 +42,7 @@ #include "acldata.h" #include "keyfile_auth.h" +#include "log.h" #include "../ucx/list.h" #include "../ucx/dlist.h" @@ -60,6 +61,7 @@ UcxMap *host_vs; // map of all vservers. key is the host name UcxList *listeners; // list of all listeners UcxList *logfiles; + AccessLog *default_log; UcxMap *authdbs; MimeMap *mimetypes; sstr_t tmp;
--- a/src/server/daemon/configmanager.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/configmanager.c Tue Jun 25 15:45:13 2013 +0200 @@ -63,37 +63,6 @@ return ucx_map_sstr_get(config_files, name); } -// copy functions -static void* copy_listener(HttpListener *ls, ServerConfiguration *cfg) { - /* - * we reuse the old listener, but change the - * ServerConfiguration and VirtualServer - */ - http_listener_ref(ls); - - // TODO: this is non atomar - sstr_t vsname = ls->default_vs.vs->name; - ls->default_vs.vs = ucx_map_sstr_get(cfg->host_vs, vsname); - ls->cfg = cfg; - - return ls; -} - -static void* copy_vs(void *vserver, void *pool) { - VirtualServer *vs = vs_copy(vserver, pool); - - /* - * this function is executed on configuration reload, so some - * VS configs may be changed - * - * vs - * objects - */ - ConfigFile *objectfile = cfgmgr_get_file(vs->objectfile); - vs->objects = objectfile->data; - return vs; -} - int cfgmgr_reload_file(ConfigFile *f, ServerConfiguration *conf, int *reload) { struct stat s; if(stat(f->file.ptr, &s) != 0) { @@ -152,41 +121,6 @@ } sc_last_modified = s.st_mtime; - } else if(0) { - /* copy configuration */ - printf("cfgmgr copy server.conf\n"); - - /* TODO: copy */ - /* - config = load_server_conf( - current_config, - "config/server.conf"); - */ - config = malloc(sizeof(ServerConfiguration)); - config->ref = 1; - config->pool = pool_create(); - config->user = sstrdup_pool(config->pool, current_config->user); - config->tmp = sstrdup_pool(config->pool, current_config->tmp); - - // copy configuration - config->host_vs = ucx_map_clone( - current_config->host_vs, - copy_vs, - config->pool); - - config->listeners = ucx_list_clone( - current_config->listeners, - (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; - } - } else { printf("no reconfig required!\n"); config = current_config;
--- a/src/server/daemon/httprequest.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/httprequest.c Tue Jun 25 15:45:13 2013 +0200 @@ -500,7 +500,6 @@ } /* if there is a trailing '/', remove it */ if(docroot.ptr[docroot.length - 1] == '/') { - //docroot.ptr[docroot.length - 1] = 0; // TODO: can I do this? No!! docroot.length--; }
--- a/src/server/daemon/log.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/log.c Tue Jun 25 15:45:13 2013 +0200 @@ -41,6 +41,7 @@ #include "../util/strbuf.h" #include "../util/io.h" #include "../ucx/map.h" +#include "../util/atomic.h" static int is_initialized = 0; @@ -53,10 +54,9 @@ static sbuf_t *ui_buffer = NULL; /* - * access logfile map + * access log file map */ -static UcxMap *access_log_files; // map of AccessLog* -static AccessLog *default_access_log; +static UcxMap *access_log_files; // map of LogFile* static char *log_date_month[] = { @@ -248,7 +248,7 @@ * This source file only manages access log files. IO is performed directly * by AddLog safs. */ -AccessLog* get_access_log(sstr_t file, sstr_t format) { +LogFile* get_access_log_file(sstr_t file) { if(!access_log_files) { access_log_files = ucx_map_new(4); } @@ -257,41 +257,27 @@ return NULL; } - AccessLog *log = ucx_map_sstr_get(access_log_files, file); + LogFile *log = ucx_map_sstr_get(access_log_files, file); if(log != NULL) { - // TODO: ref + ws_atomic_inc32(&log->ref); return log; } // the log file is not opened // check first if we can open it - sstr_t path = sstrdup(file); - FILE *out = fopen(path.ptr, "a"); + FILE *out = fopen(file.ptr, "a"); if(out == NULL) { - free(path.ptr); return NULL; } - // create access log object - log = calloc(1, sizeof(AccessLog)); - log->file = path; - if(format.ptr != NULL) { - log->format = sstrdup(format); - } - log->log = out; - // TODO: log->ref = 1; + // create LogFile object + log = calloc(1, sizeof(LogFile)); + log->file = out; + log->ref = 1; // add access log to the map ucx_map_sstr_put(access_log_files, file, log); - if(!default_access_log) { - default_access_log = log; - } - return log; } -AccessLog* get_default_access_log() { - // TODO: ref - return default_access_log; -}
--- a/src/server/daemon/log.h Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/log.h Tue Jun 25 15:45:13 2013 +0200 @@ -46,10 +46,14 @@ } LogConfig; typedef struct { + FILE *file; + uint32_t ref; +} LogFile; + +typedef struct { sstr_t file; sstr_t format; // unused - FILE *log; - uint32_t ref; + LogFile *log; } AccessLog; // server logging @@ -64,10 +68,7 @@ int log_ereport(int degree, const char *format, ...); // access logging -AccessLog* get_access_log(sstr_t file, sstr_t format); -AccessLog* get_default_access_log(); - -// TODO: ref/unref +LogFile* get_access_log_file(sstr_t file); #ifdef __cplusplus }
--- a/src/server/daemon/protocol.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/protocol.c Tue Jun 25 15:45:13 2013 +0200 @@ -261,13 +261,22 @@ char *name = p->param->name; char *value = p->param->value; - /* make first char of name uppercase */ - // TODO: don't modify the headers + // make first char of name uppercase + size_t name_len = strlen(name); if(name[0] > 90) { - name[0] -= 32; + /* + * make first char uppercase and write the remaining chars + * unmodified to the buffer + */ + sbuf_put(out, name[0]-32); + if(name_len > 1) { + sbuf_write(out, name+1, name_len-1); + } + } else { + // first char is already uppercase so just write the name + sbuf_write(out, name, name_len); } - sbuf_write(out, name, strlen(name)); sbuf_write(out, ": ", 2); sbuf_write(out, value, strlen(value)); sbuf_write(out, "\r\n", 2);
--- a/src/server/daemon/threadpools.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/daemon/threadpools.c Tue Jun 25 15:45:13 2013 +0200 @@ -41,16 +41,20 @@ threadpool_t *last_thrpool_c = NULL; -int create_threadpool(sstr_t name, ThreadPoolConfig *cfg) { - // TODO: use ThreadPoolConfig - +int create_threadpool(sstr_t name, ThreadPoolConfig *cfg) { if(thread_pool_map == NULL) { thread_pool_map = ucx_map_new(16); } threadpool_t *pool = ucx_map_sstr_get(thread_pool_map, name); if(pool) { - /* TODO: reconfig thread pool */ + if(pool->min_threads > cfg->max_threads) { + pool->min_threads = cfg->min_threads; + pool->max_threads = cfg->max_threads; + } else { + pool->max_threads = cfg->max_threads; + pool->min_threads = cfg->min_threads; + } return 0; } else { threadpool_t *tp = threadpool_new(cfg->min_threads, cfg->max_threads);
--- a/src/server/safs/addlog.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/safs/addlog.c Tue Jun 25 15:45:13 2013 +0200 @@ -72,7 +72,7 @@ tmstr = sstrdup_pool(sn->pool, tmstr); fprintf( - log->log, + log->log->file, "%s - %s [%s] \"%s\" %d %s\n", ip, user, @@ -80,7 +80,7 @@ req, rq->status_num, len); - fflush(log->log); + fflush(log->log->file); return REQ_PROCEED;
--- a/src/server/safs/auth.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/safs/auth.c Tue Jun 25 15:45:13 2013 +0200 @@ -175,9 +175,7 @@ grpfn = pblock_findval("groupfn", param); if((!type) || (!pwfile) || (!pwfn) || (grpfile && !grpfn)) { - // TODO: log error - //log_error(LOG_MISCONFIG, "basic-auth", sn, rq, - // XP_GetAdminStr(DBT_authError1)); + log_ereport(LOG_MISCONFIG, "basic-auth: missing parameter"); protocol_status(sn, rq, PROTOCOL_SERVER_ERROR, NULL); return REQ_ABORTED; } @@ -233,8 +231,7 @@ if(!db) { // TODO: log error - //log_error(LOG_MISCONFIG, "basic-auth", sn, rq, - // XP_GetAdminStr(DBT_authError1)); + log_ereport(LOG_MISCONFIG, "basic-auth: missing db parameter"); protocol_status(sn, rq, PROTOCOL_SERVER_ERROR, NULL); return REQ_ABORTED; }
--- a/src/server/safs/init.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/safs/init.c Tue Jun 25 15:45:13 2013 +0200 @@ -43,8 +43,7 @@ char *funcs = pblock_findval("funcs", pb); if(shlib == NULL || funcs == NULL) { - fprintf(stderr, "load-modules: missing parameter\n"); - //log_ereport(LOG_MISCONFIG, "load-modules: missing parameters"); + log_ereport(LOG_MISCONFIG, "load-modules: missing parameters"); if(!shlib && funcs) { log_ereport( LOG_MISCONFIG, @@ -60,7 +59,7 @@ } } - /* load lib */ + // load lib void *lib = dlopen(shlib, RTLD_GLOBAL | RTLD_NOW); if(lib == NULL) { char *dlerr = dlerror(); @@ -71,7 +70,7 @@ return REQ_ABORTED; } - /* load function symbols */ + // load function symbols int b = 0; for(int i=0;;i++) { if(funcs[i] == ',' || funcs[i] == 0) { @@ -81,7 +80,7 @@ funcs[i] = 0; - /* we have a function name */ + // we have a function name void *sym = dlsym(lib, funcs); if(sym == NULL) { fprintf(stderr, "Cannot load symbol %s\n", funcs);
--- a/src/server/safs/nametrans.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/safs/nametrans.c Tue Jun 25 15:45:13 2013 +0200 @@ -28,6 +28,7 @@ #include "nametrans.h" +#include "../daemon/log.h" #include "../util/pblock.h" int test_nametrans(pblock *pb, Session *sn, Request *rq) { @@ -57,7 +58,7 @@ char *from = pblock_findkeyval(pb_key_from, pb); if(!name) { - /* TODO: add log */ + log_ereport(LOG_MISCONFIG, "assign-name: missing name parameter"); protocol_status(sn, rq, 500, NULL); return REQ_ABORTED; } @@ -74,7 +75,7 @@ } } - /* add object to rq->vars */ + // add object to rq->vars pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars); return REQ_NOACTION;
--- a/src/server/safs/objecttype.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/safs/objecttype.c Tue Jun 25 15:45:13 2013 +0200 @@ -36,12 +36,11 @@ int object_type_by_extension(pblock *pb, Session *sn, Request *rq) { sstr_t ppath = sstr(pblock_findkeyval(pb_key_ppath, rq->vars)); - //printf("\nobject_type_by_extension: {%s}[%d]\n\n", ppath); sstr_t ct; if(ppath.ptr[ppath.length - 1] == '/') { - /* directory */ + // directory ct = sstrn("internal/directory", 18); } else { sstr_t ext; @@ -54,11 +53,11 @@ } if(ext.length == 0) { - /* no extension, no type */ + // no extension, no type return REQ_NOACTION; } - /* get the mime type for the ext from the server configuration */ + // 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->map, ext);
--- a/src/server/safs/pathcheck.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/safs/pathcheck.c Tue Jun 25 15:45:13 2013 +0200 @@ -57,8 +57,8 @@ int require_access(pblock *pb, Session *sn, Request *rq) { char *mask_str = pblock_findval("mask", rq->vars); if(!mask_str) { - // misconfig - // TODO: log + log_ereport(LOG_MISCONFIG, "require-access: missing mask parameter"); + protocol_status(sn, rq, 500, NULL); return REQ_ABORTED; } @@ -80,8 +80,10 @@ if(aclname) { ACLList *acl = acl_get(vs->acls, aclname); if(!acl) { - // TODO: error - fprintf(stderr, "acl %s not found\n", aclname); + log_ereport( + LOG_MISCONFIG, + "append-acl: acl %s not found", aclname); + protocol_status(sn, rq, 500, NULL); return REQ_ABORTED; }
--- a/src/server/safs/service.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/safs/service.c Tue Jun 25 15:45:13 2013 +0200 @@ -52,7 +52,7 @@ SYS_FILE prepare_service_file(Session *sn, Request *rq, struct stat *s) { char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars); - /* open the file */ + // open the file VFSContext *vfs = vfs_request_context(sn, rq); SYS_FILE fd = vfs_open(vfs, ppath, O_RDONLY); if(!fd) { @@ -60,7 +60,7 @@ return NULL; } - /* get stat */ + // get stat if(vfs_fstat(vfs, fd, s) != 0) { //perror("prepare_service_file: stat"); protocol_status(sn, rq, 500, NULL); @@ -84,13 +84,13 @@ return fd; } - /* add content-length header*/ + // add content-length header char contentLength[32]; int len = snprintf(contentLength, 32, "%lld", s->st_size); pblock_kvinsert(pb_key_content_length, contentLength, len, rq->srvhdrs); - /* start response */ + // start response protocol_status(sn, rq, 200, NULL); http_start_response(sn, rq); @@ -140,23 +140,23 @@ sstr_t r_uri = sstr(uri); - /* open the file */ + // open the file VFSContext *vfs = vfs_request_context(sn, rq); VFS_DIR dir = vfs_opendir(vfs, ppath); if(!dir) { return REQ_ABORTED; } - sbuf_t *out = sbuf_new(1024); /* output buffer */ + sbuf_t *out = sbuf_new(1024); // output buffer - /* write html header */ + // write html header sbuf_puts(out, "<html>\n<head>\n<title>Index of "); sbuf_puts(out, uri); sbuf_puts(out, "</title>\n</head><body>\n<h1>Index of "); sbuf_puts(out, uri); sbuf_puts(out, "</h1><hr>\n\n"); - //struct dirent *f; + // list directory VFS_ENTRY f; while(vfs_readdir(dir, &f)) { sstr_t filename = sstr(f.name); @@ -171,7 +171,7 @@ sbuf_puts(out, "\n</body>\n</html>\n"); - /* send stuff to client */ + // send stuff to client pblock_removekey(pb_key_content_type, rq->srvhdrs); pblock_kvinsert(pb_key_content_type, "text/html", 9, rq->srvhdrs); pblock_nninsert("content-length", out->length, rq->srvhdrs); @@ -180,7 +180,7 @@ net_write(sn->csd, out->ptr, out->length); - /* close */ + // close vfs_closedir(dir); sbuf_free(out);
--- a/src/server/util/pblock.cpp Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/util/pblock.cpp Tue Jun 25 15:45:13 2013 +0200 @@ -1145,8 +1145,6 @@ if (ppval[i]) ++nval; } - // TODO: implement util_env_create and util_env_str - /* env = util_env_create(env, nval, &pos); for (i = 0; i < pl->pl_initpi; ++i) { @@ -1156,7 +1154,6 @@ } } env[pos] = NULL; - */ return env; }
--- a/src/server/util/util.c Mon Jun 24 14:41:32 2013 +0200 +++ b/src/server/util/util.c Tue Jun 25 15:45:13 2013 +0200 @@ -108,17 +108,152 @@ return nbytesdecoded; } -/* -NSAPI_PUBLIC int util_getboolean(const char *v, int def) { - if(v[0] == 'T' || v[0] == 't') { - return 1; + +/* --------------------------- util_env_create ---------------------------- */ + + +NSAPI_PUBLIC char **util_env_create(char **env, int n, int *pos) +{ + int x; + + if(!env) { + *pos = 0; + return (char **) MALLOC((n + 1)*sizeof(char *)); + } + else { + for(x = 0; (env[x]); x++); + env = (char **) REALLOC(env, (n + x + 1)*(sizeof(char *))); + *pos = x; + return env; + } +} + + +/* ---------------------------- util_env_free ----------------------------- */ + + +NSAPI_PUBLIC void util_env_free(char **env) +{ + register char **ep = env; + + for(ep = env; *ep; ep++) + FREE(*ep); + FREE(env); +} + +/* ----------------------------- util_env_str ----------------------------- */ + + +NSAPI_PUBLIC char *util_env_str(const char *name, const char *value) { + char *t; + + t = (char *) MALLOC(strlen(name)+strlen(value)+2); /* 2: '=' and '\0' */ + + sprintf(t, "%s=%s", name, value); + + return t; +} + + +/* --------------------------- util_env_replace --------------------------- */ + + +NSAPI_PUBLIC void util_env_replace(char **env, const char *name, const char *value) +{ + int x, y, z; + char *i; + + for(x = 0; env[x]; x++) { + i = strchr(env[x], '='); + *i = '\0'; + if(!strcmp(env[x], name)) { + y = strlen(env[x]); + z = strlen(value); + + env[x] = (char *) REALLOC(env[x], y + z + 2); + util_sprintf(&env[x][y], "=%s", value); + return; + } + *i = '='; } - if(v[0] == 'F' || v[0] == 'f') { - return 0; +} + + +/* ---------------------------- util_env_find ----------------------------- */ + + +NSAPI_PUBLIC char *util_env_find(char **env, const char *name) +{ + char *i; + int x, r; + + for(x = 0; env[x]; x++) { + i = strchr(env[x], '='); + *i = '\0'; + r = !strcmp(env[x], name); + *i = '='; + if(r) + return i + 1; } - return def; + return NULL; +} + + +/* ---------------------------- util_env_copy ----------------------------- */ + + +NSAPI_PUBLIC char **util_env_copy(char **src, char **dst) +{ + char **src_ptr; + int src_cnt; + int index; + + if (!src) + return NULL; + + for (src_cnt = 0, src_ptr = src; *src_ptr; src_ptr++, src_cnt++); + + if (!src_cnt) + return NULL; + + dst = util_env_create(dst, src_cnt, &index); + + for (src_ptr = src; *src_ptr; index++, src_ptr++) + dst[index] = STRDUP(*src_ptr); + dst[index] = NULL; + + return dst; } -*/ + +/* ----------------------------- util_sprintf ----------------------------- */ + +NSAPI_PUBLIC int util_vsnprintf(char *s, int n, register const char *fmt, + va_list args) +{ + return vsnprintf(s, n, fmt, args); +} + +NSAPI_PUBLIC int util_snprintf(char *s, int n, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + return vsnprintf(s, n, fmt, args); +} + +NSAPI_PUBLIC int util_vsprintf(char *s, register const char *fmt, va_list args) +{ + return vsprintf(s, fmt, args); +} + +NSAPI_PUBLIC int util_sprintf(char *s, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + return vsprintf(s, fmt, args); +} + +// TODO: asprintf + NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def) { if(v[0] == 'T' || v[0] == 't') {