Added configuration manager

Sat, 21 Jan 2012 16:37:35 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 21 Jan 2012 16:37:35 +0100
changeset 19
d680536f8c2f
parent 18
73aacbf6e492
child 20
7b235fa88008

Added configuration manager

src/server/config/serverconf.c file | annotate | diff | comparison | revisions
src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/config.h file | annotate | diff | comparison | revisions
src/server/daemon/configmanager.c file | annotate | diff | comparison | revisions
src/server/daemon/configmanager.h file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.h file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.h file | annotate | diff | comparison | revisions
src/server/daemon/vserver.c file | annotate | diff | comparison | revisions
src/server/daemon/vserver.h file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
src/server/public/nsapi.h file | annotate | diff | comparison | revisions
--- a/src/server/config/serverconf.c	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/config/serverconf.c	Sat Jan 21 16:37:35 2012 +0100
@@ -41,7 +41,7 @@
     ServerConfig *conf = malloc(sizeof(ServerConfig));
     conf->parser.parse = serverconf_parse;
     conf->file = file;
-    conf->objects = ucx_map_new(8);
+    conf->objects = ucx_map_new(161);
     
     conf->obj = NULL;
 
--- a/src/server/daemon/config.c	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/config.c	Sat Jan 21 16:37:35 2012 +0100
@@ -46,8 +46,6 @@
 #include "vserver.h"
 #include "../util/pblock.h"
 
-VirtualServer *default_vs;
-
 pool_handle_t *cfg_pool;
 
 // TODO: Funktion für ConfigDirective -> directive
@@ -60,7 +58,7 @@
 void load_init_conf(char *file) {
     printf("load_init_conf\n");
 
-    InitConfig *cfg = load_init_config("conf/init.conf");
+    InitConfig *cfg = load_init_config(file);
     if(cfg == NULL) {
         return;
     }
@@ -102,16 +100,17 @@
     free_init_config(cfg);
 }
 
-void load_server_conf(char *file) {
+ServerConfiguration* load_server_conf(char *file) {
     printf("load_server_conf\n");
 
-    init_default_server_conf_handlers();
-
-    ServerConfig *serverconf = load_server_config("conf/server.conf");
+    ServerConfig *serverconf = load_server_config(file);
     if(serverconf == NULL) {
         fprintf(stderr, "Cannot load server.conf\n");
     }
     ServerConfiguration *serverconfig = malloc(sizeof(ServerConfiguration));
+    serverconfig->pool = pool_create();
+    serverconfig->listeners = NULL;
+    serverconfig->host_vs = ucx_map_new(16);
     // TODO: init serverconfig stuff
 
     /* convert ServerConfig to ServerConfiguration */
@@ -127,16 +126,32 @@
                         server_conf_handlers,
                         scfgobj->type);
                 if(handler != NULL) {
+                    void *object_data = NULL;
+                    if(handler->element_start != NULL) {
+                        object_data = handler->element_start(
+                                handler,
+                                serverconfig);
+                    }
+
                     /* process the directives */
                     UcxDlist *dirs = scfgobj->directives;
                     while(dirs != NULL) {
                         handler->process_directive(
                                 handler,
                                 serverconfig,
-                                dirs->data);
+                                dirs->data,
+                                object_data);
                         
                         dirs = dirs->next;
                     }
+
+                    if(handler->element_end != NULL) {
+                        handler->element_end(
+                                handler,
+                                serverconfig,
+                                NULL,
+                                object_data);
+                    }
                 }
 
                 list = list->next;
@@ -145,50 +160,194 @@
             elm = elm->next;
         }
     }
-    
-    
-    ListenerConfig *conf = malloc(sizeof(ListenerConfig));
-    conf->port = 9090;
-    conf->nacceptors = 1;
-    conf->name = "default";
+
+    /* set VirtualServer for all listeners */
+    UcxList *ls = serverconfig->listeners;
+    while(ls) {
+        HttpListener *listener = ls->data;
+
+        sstr_t vsname = sstr(listener->default_vs.vs_name);
+
+        /* search for VirtualServer */
+        int b = 0;
+        for(int i=0;i<serverconfig->host_vs->size;i++) {
+            UcxMapElement *elm = &serverconfig->host_vs->map[i];
+            while(elm != NULL && elm->data != NULL) {
+                VirtualServer *vs = elm->data;
 
-    http_listener_new(conf);
+                if(!sstrcmp(vsname, vs->name)) {
+                    b = 1;
+                    listener->default_vs.vs = vs;
+                    break;
+                }
 
-    // virtual server
-    default_vs = vs_new();
-    // load obj.conf
-    default_vs->objects = load_obj_conf("conf/obj.conf");
-    default_vs->default_obj_name = "default";
-    
+                elm = elm->next;
+            }
+            if(b) {
+                break;
+            }
+        }
+
+        ls = ls->next;
+    }
+
+    return serverconfig;
 }
 
-void init_default_server_conf_handlers() {
+
+void init_server_config_parser() {
     /* create handler map */
     server_conf_handlers = ucx_map_new(8);
 
     /* create and add default handlers */
 
-    ServerConfigHandler *runtime = malloc(sizeof(ServerConfigHandler));
+    ServerConfigHandler *runtime = calloc(1, sizeof(ServerConfigHandler));
     runtime->init = NULL;
     runtime->process_directive = handle_runtime_directive;
 
     ucx_map_cstr_put(server_conf_handlers, "Runtime", runtime);
+
+
+    ServerConfigHandler *listener = calloc(1, sizeof(ServerConfigHandler));
+    listener->init = NULL;
+    listener->element_start = handle_listener_start;
+    listener->element_end = handle_listener_end;
+    listener->process_directive = handle_listener_directive;
+
+    ucx_map_cstr_put(server_conf_handlers, "Listener", listener);
+
+
+    ServerConfigHandler *vserver = calloc(1, sizeof(ServerConfigHandler));
+    vserver->init = NULL;
+    vserver->element_start = handle_vserver_start;
+    vserver->element_end = handle_vserver_end;
+    vserver->process_directive = handle_vserver_directive;
+
+    ucx_map_cstr_put(server_conf_handlers, "VirtualServer", vserver);
+
+
 }
 
+/*
+ *  server.conf handlers
+ */
 int handle_runtime_directive(
         ServerConfigHandler *h,
         ServerConfiguration *conf,
-        ConfigDirective *dir)
+        ConfigDirective *dir,
+        void *data)
 {
     
 
     return 0;
 }
 
-VirtualServer* conf_get_default_vs() {
-    return default_vs;
+
+void* handle_listener_start(ServerConfigHandler *h, ServerConfiguration *cfg) {
+    /* free this in handle_listener_end */
+    ListenerConfig *listener = calloc(1, sizeof(ListenerConfig));
+    listener->nacceptors = 1;
+    listener->port = 0;
+    //printf("<Listener>\n");
+    return listener;
+}
+
+int handle_listener_directive(
+        ServerConfigHandler *h,
+        ServerConfiguration *conf,
+        ConfigDirective *dir,
+        void *data)
+{
+    ListenerConfig *listener = data;
+    ConfigParam *param = dir->param->data;
+
+    if(!sstrcmp(dir->directive_type, sstr("Name"))) {
+        listener->name = sstrdub(param->name);
+        //printf("Name        %s\n", listener->name.ptr);
+    } else if(!sstrcmp(dir->directive_type, sstr("Port"))) {
+        listener->port = atoi(param->name.ptr);
+        //printf("Port        %d\n", listener->port);
+    } else if(!sstrcmp(dir->directive_type, sstr("DefaultVS"))) {
+        listener->vs = sstrdub(param->name);
+        //printf("DefaultVS   %s\n", param->name.ptr);
+    }
+
+    return 0;
+}
+
+int handle_listener_end(
+        ServerConfigHandler *h,
+        ServerConfiguration *conf,
+        ConfigDirective *dir,
+        void *data)
+{
+    //printf("</Listener>\n\n");
+    /* add listener to server configuration */
+    ListenerConfig *lc = data;
+    HttpListener *listener = http_listener_new(lc);
+    listener->default_vs.vs_name = lc->vs.ptr;
+    //free(lc);
+    conf->listeners = ucx_list_append(conf->listeners, listener);
+
+    return 0;
 }
 
+
+void* handle_vserver_start(ServerConfigHandler *h, ServerConfiguration *cfg) {
+    //printf("<VirtualServer>\n");
+    VirtualServer *vs = vs_new();
+    return vs;
+}
+
+int handle_vserver_directive(
+        ServerConfigHandler *h,
+        ServerConfiguration *conf,
+        ConfigDirective *dir,
+        void *data)
+{
+    VirtualServer *vs = data;
+    ConfigParam *param = dir->param->data;
+
+    if(!sstrcmp(dir->directive_type, sstr("Name"))) {
+        vs->name = sstrdub(param->name);
+        //printf("Name        %s\n", vs->name.ptr);
+    } else if(!sstrcmp(dir->directive_type, sstr("Host"))) {
+        vs->host = sstrdub(param->name);
+        //printf("Host        %s\n", vs->host.ptr);
+    } else if(!sstrcmp(dir->directive_type, sstr("ObjectFile"))) {
+        sstr_t base = sstr("conf/");
+        sstr_t file;
+        file.length = base.length + param->name.length + 1;
+        file.ptr = alloca(file.length);
+        file.ptr[file.length] = 0;
+        file = sstrncat(2, file, base, param->name);
+        //printf("ObjectFile  %s\n", file.ptr);
+
+        vs->objects = load_obj_conf(file.ptr);
+        
+    } else if(!sstrcmp(dir->directive_type, sstr("DocRoot"))) {
+        vs->document_root = sstrdub(param->name);
+    }
+    // TODO: Listener, ACLFile, DAVFile, DocRoot, ...
+
+    return 0;
+}
+
+int handle_vserver_end(
+        ServerConfigHandler *h,
+        ServerConfiguration *conf,
+        ConfigDirective *dir,
+        void *data)
+{
+    //printf("</VirtualServer>\n\n");
+    VirtualServer *vs = data;
+
+    ucx_map_sstr_put(conf->host_vs, vs->host, vs);
+
+    return 0;
+}
+
+
 HTTPObjectConfig* load_obj_conf(char *file) {
     printf("load_obj_conf\n");
 
@@ -200,7 +359,7 @@
 
     /* create object config */
     HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1);
-    conf->pool = cfg_pool;
+    conf->pool = pool_create();
 
     /* convert ObjectConfig to HTTPObjectConfig */
 
--- a/src/server/daemon/config.h	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/config.h	Sat Jan 21 16:37:35 2012 +0100
@@ -64,36 +64,57 @@
 typedef struct _server_conf_handler ServerConfigHandler;
 
 typedef void(*cfg_handler_init_f)(ServerConfigHandler*, ServerConfiguration*);
+typedef void*(*cfg_element_start_f)(
+        ServerConfigHandler*,
+        ServerConfiguration*);
 typedef int(*cfg_process_directive_f)(
         ServerConfigHandler*,
         ServerConfiguration*,
-        ConfigDirective*);
+        ConfigDirective*,
+        void*); /* element object created in element_start */
 
 struct _server_conf_handler {
     cfg_handler_init_f      init;
+    cfg_element_start_f     element_start;
     cfg_process_directive_f process_directive;
+    cfg_process_directive_f element_end;
 };
 
 void load_init_conf(char *file);
 
-void load_server_conf(char *file);
+void init_server_config_parser();
 
-void init_default_server_conf_handlers();
+ServerConfiguration* load_server_conf(char *file);
 
 int handle_runtime_directive(
         ServerConfigHandler *h,
         ServerConfiguration *conf,
-        ConfigDirective *dir);
+        ConfigDirective *dir,
+        void *data);
+
+void* handle_listener_start(ServerConfigHandler *h, ServerConfiguration *cfg);
 int handle_listener_directive(
         ServerConfigHandler *h,
         ServerConfiguration *conf,
-        ConfigDirective *dir);
+        ConfigDirective *dir,
+        void *data);
+int handle_listener_end(
+        ServerConfigHandler *h,
+        ServerConfiguration *conf,
+        ConfigDirective *dir,
+        void *data);
+
+void* handle_vserver_start(ServerConfigHandler *h, ServerConfiguration *cfg);
 int handle_vserver_directive(
         ServerConfigHandler *h,
         ServerConfiguration *conf,
-        ConfigDirective *dir);
-
-VirtualServer* conf_get_default_vs();
+        ConfigDirective *dir,
+        void *data);
+int handle_vserver_end(
+        ServerConfigHandler *h,
+        ServerConfiguration *conf,
+        ConfigDirective *dir,
+        void *data);
 
 HTTPObjectConfig* load_obj_conf(char *file);
 
--- a/src/server/daemon/configmanager.c	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/configmanager.c	Sat Jan 21 16:37:35 2012 +0100
@@ -33,8 +33,26 @@
 
 #include "configmanager.h"
 
-
+ServerConfiguration *current_config = NULL;
 
 void init_configuration_manager() {
-    
+    /* init parser */
+    init_server_config_parser();
 }
+
+int cfgmgr_load_config() {
+    ServerConfiguration *config = load_server_conf("conf/server.conf");
+    if(config == NULL) {
+        fprintf(stderr, "Cannot load server.conf\n");
+        return -1;
+    }
+
+    current_config = config;
+    return 0;
+}
+
+ServerConfiguration *cfgmgr_get_server_config() {
+    return current_config;
+}
+
+
--- a/src/server/daemon/configmanager.h	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/configmanager.h	Sat Jan 21 16:37:35 2012 +0100
@@ -45,6 +45,8 @@
 
 
 void init_configuration_manager();
+int cfgmgr_load_config();
+ServerConfiguration* cfgmgr_get_server_config();
 
 
 #ifdef	__cplusplus
--- a/src/server/daemon/httplistener.c	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/httplistener.c	Sat Jan 21 16:37:35 2012 +0100
@@ -50,24 +50,25 @@
 #include "httplistener.h"
 
 #include "session.h"
-
-UcxMap *listener_map = NULL;
+#include "configmanager.h"
 
 
 int start_all_listener() {
-    HttpListener *listener = get_http_listener("default");
-    http_listener_start(listener); 
+    ServerConfiguration *conf = cfgmgr_get_server_config();
+    UcxList *ls = conf->listeners;
+    while(ls) {
+        HttpListener *listener = ls->data;
+        http_listener_start(listener);
+        ls = ls->next;
+    }
 
     return 0;
 }
 
-HttpListener* get_http_listener(char *name) {
-    return ucx_map_cstr_get(listener_map, name);
-}
-
 
 HttpListener* http_listener_new(ListenerConfig *conf) {
     HttpListener *listener = malloc(sizeof(HttpListener));
+    listener->name = conf->name;
     listener->session_handler = create_basic_session_handler();
     listener->nacceptors = conf->nacceptors;
 
@@ -104,10 +105,6 @@
         listener->acceptors[i] = acceptor_new(listener);
     }
 
-    if(listener_map == NULL) {
-        listener_map = ucx_map_new(8);
-    }
-    ucx_map_cstr_put(listener_map, conf->name, listener);
     return listener;
 }
 
@@ -123,6 +120,8 @@
     for (int i=0;i<listener->nacceptors;i++) {
         acceptor_start(listener->acceptors[i]);
     }
+
+    return 0;
 }
 
 
@@ -167,6 +166,7 @@
         Connection *conn = malloc(sizeof(Connection));
         conn->address = ca;
         conn->fd = clientfd;
+        conn->listener = listener;
 
         /* enqueue the connection */
         listener->session_handler->enqueue_connection(
--- a/src/server/daemon/httplistener.h	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/httplistener.h	Sat Jan 21 16:37:35 2012 +0100
@@ -35,12 +35,18 @@
 extern "C" {
 #endif
 
-typedef struct _http_listener    HttpListener;
+/* HttpListener typedef in nsapi.h */
 typedef struct _acceptor         Acceptor;
 typedef struct _listener_config  ListenerConfig;
 
+
+union vs {
+    VirtualServer    *vs;
+    char             *vs_name;
+};
 struct _listener_config {
-    char           *name;
+    sstr_t         name;
+    sstr_t         vs;
     char           *address;
     int            port;
     int            nacceptors;
@@ -52,6 +58,9 @@
 };
 
 struct _http_listener {
+    sstr_t           name;
+    union vs         default_vs;
+    int              port;
     int              server_socket;
     Acceptor         **acceptors;
     int              nacceptors;
@@ -59,14 +68,11 @@
 };
 
 int start_all_listener();
-HttpListener* get_http_listener(char *name);
-
 
 HttpListener* http_listener_new(ListenerConfig *conf);
 
 int http_listener_start(HttpListener *listener);
 
-
 Acceptor* acceptor_new(HttpListener *listener);
 
 void acceptor_start(Acceptor *a);
--- a/src/server/daemon/httprequest.c	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/httprequest.c	Sat Jan 21 16:37:35 2012 +0100
@@ -38,6 +38,7 @@
 #include "httprequest.h"
 #include "config.h"
 #include "vserver.h"
+#include "httplistener.h"
 
 HTTPRequest *http_request_new() {
     HTTPRequest *req = malloc(sizeof(HTTPRequest));
@@ -94,8 +95,7 @@
     }
 
     // set default virtual server
-    rq->vs = conf_get_default_vs();
-
+    rq->vs = request->connection->listener->default_vs.vs;
 
     /* Pass request line as "clf-request" */
     pblock_kvinsert(
--- a/src/server/daemon/sessionhandler.h	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/sessionhandler.h	Sat Jan 21 16:37:35 2012 +0100
@@ -40,9 +40,10 @@
 typedef struct _connection        Connection;
 
 struct _connection {
-    int fd;
-    struct sockaddr_in address;
-    SessionHandler *session_handler;
+    int                  fd;
+    struct sockaddr_in   address;
+    HttpListener         *listener;
+    SessionHandler       *session_handler;
 };
 
 typedef void(*enqueue_connection_f)(SessionHandler*, Connection*);
--- a/src/server/daemon/vserver.c	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/vserver.c	Sat Jan 21 16:37:35 2012 +0100
@@ -30,7 +30,6 @@
 
 VirtualServer* vs_new() {
     VirtualServer *vs = malloc(sizeof(VirtualServer));
-    vs->default_obj_name = NULL;
     vs->objects = NULL;
     vs->document_root = sstr("docs");
     return vs;
--- a/src/server/daemon/vserver.h	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/vserver.h	Sat Jan 21 16:37:35 2012 +0100
@@ -39,7 +39,10 @@
 #endif
 
 struct VirtualServer {
-    char              *default_obj_name;
+    sstr_t            name;
+    sstr_t            host;
+    // TODO: list of listeners, check listener of vs
+    
     HTTPObjectConfig  *objects;
 
     sstr_t            document_root;
--- a/src/server/daemon/webserver.c	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/daemon/webserver.c	Sat Jan 21 16:37:35 2012 +0100
@@ -35,6 +35,7 @@
 
 #include "func.h"
 #include "config.h"
+#include "configmanager.h"
 #include "httplistener.h"
 #include "webserver.h"
 
@@ -51,10 +52,14 @@
     add_functions(webserver_funcs);
 
     // load init.conf
-    load_init_conf(NULL);
+    load_init_conf("conf/init.conf");
 
     // load server.conf
-    load_server_conf(NULL);
+    init_configuration_manager();
+    if(cfgmgr_load_config() != 0) {
+        fprintf(stderr, "Cannot load configuration\n");
+        return -1;
+    }
 
     // init NSAPI functions
 
--- a/src/server/public/nsapi.h	Mon Jan 16 14:06:52 2012 +0100
+++ b/src/server/public/nsapi.h	Sat Jan 21 16:37:35 2012 +0100
@@ -700,6 +700,11 @@
     unsigned pool_resolved;
 };
 
+////// new
+
+typedef struct _http_listener HttpListener;
+
+//////
 /*
  * VSInitFunc, VSDestroyFunc, VSDirectiveInitFunc and VSDirectiveDestroyFunc
  */

mercurial