Added parser for obj.conf

Mon, 26 Dec 2011 15:48:32 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 26 Dec 2011 15:48:32 +0100
changeset 5
dbc01588686e
parent 4
998844b5ed25
child 6
ce8fecc9847d

Added parser for obj.conf

Makefile file | annotate | diff | comparison | revisions
doc/development/mod_jk nsapi.txt file | annotate | diff | comparison | revisions
src/server/conf.c file | annotate | diff | comparison | revisions
src/server/conf.h file | annotate | diff | comparison | revisions
src/server/httprequest.c file | annotate | diff | comparison | revisions
src/server/object.c file | annotate | diff | comparison | revisions
src/server/object.h file | annotate | diff | comparison | revisions
src/server/pblock.cpp file | annotate | diff | comparison | revisions
src/server/pblock.h file | annotate | diff | comparison | revisions
src/server/webserver.c file | annotate | diff | comparison | revisions
templates/conf/obj.conf file | annotate | diff | comparison | revisions
--- a/Makefile	Sun Nov 13 13:43:01 2011 +0100
+++ b/Makefile	Mon Dec 26 15:48:32 2011 +0100
@@ -42,6 +42,7 @@
 	mkdir -p $(WS_INSTALL_DIR)bin
 	mkdir -p $(WS_INSTALL_DIR)lib
 	mkdir -p $(WS_INSTALL_DIR)conf
+	mkdir -p $(WS_INSTALL_DIR)docs
 	mkdir -p $(WS_INSTALL_DIR)include
 	@echo "copy config"
 	cp templates/conf/init.conf $(WS_INSTALL_DIR)conf/init.conf
--- a/doc/development/mod_jk nsapi.txt	Sun Nov 13 13:43:01 2011 +0100
+++ b/doc/development/mod_jk nsapi.txt	Mon Dec 26 15:48:32 2011 +0100
@@ -6,6 +6,7 @@
 http_status                     line 155: protocol_status
 http_start_response             line 157: protocol_start_response
 netbuf_next                     line 188: netbuf_getc
+netbuf_getbytes
 net_write                       line 226
 pblock_findval                  line 439
 systhread_start                 line 303
--- a/src/server/conf.c	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/conf.c	Mon Dec 26 15:48:32 2011 +0100
@@ -31,10 +31,20 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "sstring.h"
+
 #include "httplistener.h"
 #include "conf.h"
+#include "func.h"
 
 #include "vserver.h"
+#include "pblock.h"
 
 VirtualServer *default_vs;
 
@@ -114,3 +124,291 @@
 VirtualServer* conf_get_default_vs() {
     return default_vs;
 }
+
+HTTPObjectConfig* load_obj_conf(char *file) {
+    printf("load_obj_conf\n");
+
+    /* create object config */
+    ObjectConfParser parser;
+    HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1);
+    conf->pool = pool_create();
+    parser.conf = conf;
+
+    FILE *in = fopen("conf/obj.conf", "r");
+    if(in == NULL) {
+        fprintf(stderr, "Cannot open conf/obj.conf\n");
+        return NULL;
+    }
+
+    char buf[512];
+    int  len = 512;
+
+    while(!feof(in)) {
+        fgets(buf, len, in);
+
+        if(*buf == 0) {
+            continue;
+        }
+
+        char *ptr;
+        if((ptr = strrchr(buf, '\n'))) {
+            ptr[0] = 0;
+        }
+
+        sstr_t line = string_trim(sstr(buf));
+        if(line.length > 0) {
+            obj_conf_parse_line(&parser, line);
+        }
+    }
+
+    
+
+    return conf;
+}
+
+void obj_conf_parse_line(ObjectConfParser *parser, sstr_t line) {
+    //printf("{%s}[%d]\n", line.ptr, line.length);
+    if(line.ptr[0] == '#') {
+        return;
+    }
+
+    if(line.length < 3) {
+        // to short for everything
+        fprintf(stderr, "obj.conf: line to short \"%s\"\n", line.ptr);
+        return;
+    }
+
+    // TODO: ersetzen
+    if(line.ptr[0] == '<') {
+        if(line.ptr[1] == '/') {
+            // end tag
+            if(line.ptr[2] == 'O' && parser->obj != NULL) {
+                // end of Object
+                httpobjconf_add_object(parser->conf, parser->obj);
+                parser->obj = NULL;
+                return;
+            }
+        } else {
+            // new tag
+            httpd_object *obj = parse_new_object_tag(line);
+            parser->obj = obj;
+        }
+    } else {
+        // directive
+        parse_directive(parser, line);
+    }
+}
+
+
+/* utils */
+
+sstr_t string_trim(sstr_t string) {
+    sstr_t newstr = string;
+    int nsoff = 0;
+    int l = 1;
+    for(int i=0;i<string.length;i++) {
+        char c = string.ptr[i];
+        if(l) {
+            /* leading whitespace */
+            if(c > 32) {
+                l = 0;
+                nsoff = i;
+                newstr.ptr = &string.ptr[i];
+                newstr.length = string.length - nsoff;
+            }
+        } else {
+            /* trailing whitespace */
+            if(c > 32) {
+                newstr.length = (i - nsoff) + 1;
+            }
+        }
+    }
+    return newstr;
+}
+
+httpd_object* parse_new_object_tag(sstr_t line) {
+    int i = 0;
+    int b = 0;
+    sstr_t name;
+    sstr_t value;
+
+    char *obj_name = NULL;
+    char *obj_ppath = NULL;
+    
+    for(;i<line.length;i++) {
+        if(line.ptr[i] < 33) {
+            b = 1;
+        } else if(b == 1) {
+            break;
+        }
+    }
+    if(!b || line.ptr[i] < 33) {
+        printf("1\n");
+        return NULL;
+    }
+    b = 0;
+    
+    /* parse name=value params */
+    for(;i<line.length;i++) {
+        if(line.ptr[i] == '>') {
+            break;
+        }
+        
+        /* get name */
+        name.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            if(line.ptr[i] == '=') {
+                b = 1;
+                i++;
+                break;
+            }
+        }
+        if(!b) {
+            printf("2\n");
+            return NULL;
+        }
+        name.length = line.ptr + i - name.ptr - 1;
+
+        if(line.ptr[i] == '\"') {
+            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
+        }
+        value.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            char c = line.ptr[i];
+            if(c < 33 || c == '\"' || c == '>') {
+                b = 1;
+                break;
+            }
+        }
+        if(!b) {
+            printf("3\n");
+            return NULL;
+        }
+        value.length = line.ptr + i - value.ptr;
+
+        if(sstrcmp(name, sstrn("name", 4)) == 0) {
+            obj_name = sstrdub(value).ptr;
+        } else if (sstrcmp(name, sstrn("ppath", 5)) == 0) {
+            obj_ppath = sstrdub(value).ptr;
+        }
+
+        /*
+        printf("name: [%d]{", name.length);
+        fwrite(name.ptr, 1, name.length, stdout);
+        printf("}\n");
+        printf("value: [%d]{", value.length);
+        fwrite(value.ptr, 1, value.length, stdout);
+        printf("}\n");
+        */
+
+        char c = line.ptr[i];
+        if(c == '>') {
+            break;
+        } else {
+            i++;
+        }
+    }
+
+    if(obj_name != NULL || obj_ppath != NULL) {
+        httpd_object *o = object_new(obj_name);
+        o->path = obj_ppath;
+        return o;
+    }
+
+    return NULL;
+}
+
+void parse_directive(ObjectConfParser *parser, sstr_t line) {
+    int i = 0;
+    int b = 0;
+
+    sstr_t directive_type = line;
+    
+    directive *directive = malloc(sizeof(directive));
+    directive->cond = NULL;
+    directive->param = pblock_create_pool(parser->conf->pool, 8);
+
+    for(;i<line.length;i++) {
+        if(line.ptr[i] < 33) {
+            b = 1;
+            directive_type.length = i;
+            if(directive_type.length <= 0) {
+                fprintf(stderr, "parse error: cannot parse directive\n");
+                return;
+            }
+        } else if(b == 1) {
+            break;
+        }
+    }
+    
+    /* parse name=value params */
+    sstr_t name;
+    sstr_t value;
+    for(;i<line.length;i++) {
+        /* get name */
+        name.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            if(line.ptr[i] == '=') {
+                b = 1;
+                i++;
+                break;
+            }
+        }
+        if(!b) {
+            printf("2\n");
+            return;
+        }
+        name.length = line.ptr + i - name.ptr - 1;
+
+        if(line.ptr[i] == '\"') {
+            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
+        }
+        value.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            char c = line.ptr[i];
+            if(c < 33 || c == '\"') {
+                b = 1;
+                break;
+            }
+        }
+        if(!b) {
+            printf("3\n");
+            return;
+        }
+        value.length = line.ptr + i - value.ptr;
+
+        name = string_trim(name);
+        value = string_trim(value);
+
+        /* insert name and value into directive pblock */
+        pblock_nvlinsert(
+                name.ptr,
+                name.length,
+                value.ptr,
+                value.length,
+                directive->param);
+    }
+
+    /* get function */
+    char *func_name = pblock_findval("fn", directive->param);
+    directive->func = get_function(func_name);
+
+    /* get nsapi function type */
+    int dt = -1;
+    if(sstrcmp(directive_type, sstr("AuthTrans")) == 0) {
+        dt = 0;
+    } else if(sstrcmp(directive_type, sstr("NameTrans")) == 0) {
+        dt = 1;
+    } else if(sstrcmp(directive_type, sstr("PathCheck")) == 0) {
+        dt = 2;
+    } else if(sstrcmp(directive_type, sstr("ObjectType")) == 0) {
+        dt = 3;
+    } else if(sstrcmp(directive_type, sstr("Service")) == 0) {
+        dt = 4;
+    } else if(sstrcmp(directive_type, sstr("AddLog")) == 0) {
+        //dt = 5;
+        return;
+    }
+
+    object_add_directive(parser->obj, directive, dt);
+}
--- a/src/server/conf.h	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/conf.h	Mon Dec 26 15:48:32 2011 +0100
@@ -29,10 +29,19 @@
 #ifndef CONF_H
 #define	CONF_H
 
+#include "object.h"
+
+#include "sstring.h"
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
+typedef struct {
+    HTTPObjectConfig *conf;
+    httpd_object     *obj;
+} ObjectConfParser;
+
 void load_init_conf(char *file);
 
 void load_server_conf(char *file);
@@ -40,6 +49,18 @@
 VirtualServer* conf_get_default_vs();
 
 
+HTTPObjectConfig* load_obj_conf(char *file);
+
+void obj_conf_parse_line(ObjectConfParser *parser, sstr_t line);
+
+
+/* utils */
+sstr_t string_trim(sstr_t string);
+
+httpd_object* parse_new_object_tag(sstr_t line);
+
+void parse_directive(ObjectConfParser *parser, sstr_t line);
+
 
 #ifdef	__cplusplus
 }
--- a/src/server/httprequest.c	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/httprequest.c	Mon Dec 26 15:48:32 2011 +0100
@@ -189,6 +189,9 @@
                 printf(">>> PathCheck\n");
                 rq->phase++;
             }
+            case NSAPIObjectType: {
+                rq->phase++;
+            }
             case NSAPIService: {
                 printf(">>> Service\n");
                 r = nsapi_service(sn, rq);
@@ -225,7 +228,7 @@
 
         // execute directives
         for(int j=0;j<dt->ndir;j++) {
-            directive *d = dt->directive[j];
+            directive *d = dt->dirs[j];
 
             printf("execute [%s]\n", d->func->name);
             ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
@@ -257,7 +260,7 @@
 
         // execute directives
         for(int j=0;j<dt->ndir;j++) {
-            directive *d = dt->directive[j];
+            directive *d = dt->dirs[j];
 
             ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
             if(ret == REQ_PROCEED || ret == REQ_PROCESSING) {
--- a/src/server/object.c	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/object.c	Mon Dec 26 15:48:32 2011 +0100
@@ -38,6 +38,7 @@
     // TODO: Speicherverwaltung
     httpd_object *obj = malloc(sizeof(httpd_object));
     obj->name = name;
+    obj->path = NULL;
 
     // create directive table
     obj->dt = calloc(sizeof(struct dtable), NUM_NSAPI_TYPES - 1);
@@ -56,9 +57,9 @@
 void object_add_directive(httpd_object *obj, directive *dir, int dt) {
     dtable *l = object_get_dtable(obj, dt);
     // allocate space for the new directive
-    l->directive = realloc(l->directive, (l->ndir+1)*sizeof(directive*));
+    l->dirs = realloc(l->dirs, (l->ndir+1)*sizeof(directive*));
     // add directive
-    l->directive[l->ndir] = dir;
+    l->dirs[l->ndir] = dir;
     l->ndir++;
 }
 
@@ -86,3 +87,9 @@
     return objset;
 }
 
+
+void httpobjconf_add_object(HTTPObjectConfig *conf, httpd_object *obj) {
+    conf->nobj++;
+    conf->objects = realloc(conf->objects, conf->nobj * sizeof(void*));
+    conf->objects[conf->nobj - 1] = obj;
+}
--- a/src/server/object.h	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/object.h	Mon Dec 26 15:48:32 2011 +0100
@@ -30,6 +30,7 @@
 #define	OBJECT_H
 
 #include "nsapi.h"
+#include "pool.h"
 
 #ifdef	__cplusplus
 extern "C" {
@@ -40,25 +41,33 @@
     NSAPIAuthTrans = 0,
     NSAPINameTrans,
     NSAPIPathCheck,
+    NSAPIObjectType,
     NSAPIService,
     REQ_FINISH,
     NUM_NSAPI_TYPES
 };
 typedef enum RequestPhase RequestPhase;
 
+typedef struct Condition          Condition;
+typedef int8_t                    ConditionResult;
+
+typedef struct NSAPIContext       NSAPIContext;
+typedef struct HTTPObjectConfig   HTTPObjectConfig;
+
 struct directive {
     FuncStruct *func;
     pblock     *param;
+    Condition  *cond;
 };
 
 struct dtable {
-    directive **directive;
-    int ndir;
+    directive **dirs;
+    int       ndir;
 };
 
 struct httpd_object {
-    char  *name;
-
+    char   *name;
+    char   *path;
     dtable *dt;
     int    nd;
 };
@@ -68,9 +77,30 @@
     int pos;
 };
 
+struct Condition {
+    Condition  *parent;
+    int        expression;
+    int        index; /* used by NSAPIContext to link expression with result */
+};
+
+
+struct NSAPIContext{
+    HTTPObjectConfig  *conf;
+
+    ConditionResult   **results;
+    int               nres;
+
+    httpd_objset      *objset;
+};
+
+struct HTTPObjectConfig {
+    httpd_object  **objects;
+    int           nobj;
+    pool_handle_t *pool;
+};
 
 /*
- * create a new httpd_object
+ * creates a new httpd_object
  */
 httpd_object* object_new(char *name);
 
@@ -80,7 +110,7 @@
 void object_free(httpd_object *obj);
 
 /*
- * adds a directive to the object with the type dt (enum DirectiveType)
+ * adds a directive to the object with the type dt (enum RequestPhase)
  */
 void object_add_directive(httpd_object *obj, directive *dir, int dt);
 
@@ -90,6 +120,17 @@
 #define object_get_dtable(obj,type) &obj->dt[type];
 
 
+/*
+ * creates a new HTTPObjectConfig
+ */
+// TODO
+
+/*
+ * adds an object to the object configuration
+ */
+void httpobjconf_add_object(HTTPObjectConfig *conf, httpd_object *obj);
+
+
 
 httpd_objset* create_test_objset();
 
--- a/src/server/pblock.cpp	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/pblock.cpp	Mon Dec 26 15:48:32 2011 +0100
@@ -659,6 +659,22 @@
 }
 
 
+/* ---------------------------pblock_nvlinsert ---------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+
+    pb_param *pp = _param_create(pl->pl_mempool, name, namelen, value, valuelen);
+
+    if(pp) {
+        pblock_kpinsert(NULL, pp, pb);
+    }
+
+    return pp;
+}
+
+
 /* ---------------------------- pblock_findkey ---------------------------- */
 
 NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb)
--- a/src/server/pblock.h	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/pblock.h	Mon Dec 26 15:48:32 2011 +0100
@@ -85,6 +85,8 @@
 
 NSAPI_PUBLIC pb_param *INTpblock_nvinsert(const char *name, const char *value, pblock *pb);
 
+NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb);
+
 NSAPI_PUBLIC pb_param *INTpblock_nninsert(const char *name, int value, pblock *pb);
 
 NSAPI_PUBLIC void INTpblock_pinsert(pb_param *pp, pblock *pb);
--- a/src/server/webserver.c	Sun Nov 13 13:43:01 2011 +0100
+++ b/src/server/webserver.c	Mon Dec 26 15:48:32 2011 +0100
@@ -56,6 +56,7 @@
     load_server_conf(NULL);
 
     // load obj.conf
+    HTTPObjectConfig *obj_conf = load_obj_conf("conf/obj.conf");
 
     // init NSAPI functions
 
--- a/templates/conf/obj.conf	Sun Nov 13 13:43:01 2011 +0100
+++ b/templates/conf/obj.conf	Mon Dec 26 15:48:32 2011 +0100
@@ -0,0 +1,15 @@
+#
+# obj.conf
+#
+# NSAPI configuration
+#
+
+<Object name="default">
+NameTrans fn="docroot" path="docs/"
+Service fn="test-service"
+</Object>
+
+<Object ppath="/hello">
+Service fn="service-hello"
+</Object>
+

mercurial