Some fixes for mod_jk

Sat, 28 Jan 2012 16:01:07 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 28 Jan 2012 16:01:07 +0100
changeset 20
7b235fa88008
parent 19
d680536f8c2f
child 21
627b09ee74e4

Some fixes for mod_jk

src/server/config/conf.c file | annotate | diff | comparison | revisions
src/server/config/serverconf.c file | annotate | diff | comparison | revisions
src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/func.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httpparser.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.h file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/safs/init.c file | annotate | diff | comparison | revisions
src/server/safs/init.h file | annotate | diff | comparison | revisions
src/server/safs/objecttype.c file | annotate | diff | comparison | revisions
src/server/safs/service.c file | annotate | diff | comparison | revisions
src/server/safs/service.h file | annotate | diff | comparison | revisions
src/server/util/io.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
--- a/src/server/config/conf.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/config/conf.c	Sat Jan 28 16:01:07 2012 +0100
@@ -291,10 +291,17 @@
         if(pname.length <= 0) {
             break;
         }
+        
 
         // create param object
         ConfigParam *param = OBJ_NEW(mp, ConfigParam);
-        param->name = sstrdub_mp(mp, pname);
+        /*
+         * TODO:
+         * Wenn man sstrdub_mp statt sstrdub nimmt, wird der Inhalt von pname
+         * verunstaltet. Warum?
+         */
+        param->name = sstrdub(pname); // TODO: use mempool!
+
         if(pvalue.length > 0) {
             param->value = sstrdub_mp(mp, pvalue);
         } else {
@@ -303,6 +310,7 @@
         }
 
         // add param to list
+        
         directive->param = ucx_list_append(directive->param, param);
     }
 
--- a/src/server/config/serverconf.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/config/serverconf.c	Sat Jan 28 16:01:07 2012 +0100
@@ -87,6 +87,7 @@
             sstr_t tag = cfg_get_end_tag_name(line);
             if(sstrcmp(tag, conf->obj->type) != 0) {
                 fprintf(stderr, "syntax error: wrong close tag\n");
+                fprintf(stderr, "open tag: %s   close tag: %s\n", sstrdub(tag).ptr, sstrdub(conf->obj->type).ptr);
                 exit(-1);
             }
             conf->obj = NULL;
--- a/src/server/daemon/config.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/daemon/config.c	Sat Jan 28 16:01:07 2012 +0100
@@ -80,6 +80,7 @@
                     p->value.ptr,
                     p->value.length,
                     d->param);
+            
             param = param->next;
         }
 
@@ -88,6 +89,7 @@
         d->func = get_function(func_name);
         if(d->func == NULL) {
             free(d);
+            dirs = dirs->next;
             continue;
         }
 
--- a/src/server/daemon/func.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/daemon/func.c	Sat Jan 28 16:01:07 2012 +0100
@@ -38,18 +38,17 @@
 UcxMap *function_map;
 
 void func_init() {
-    function_map = ucx_map_new(128);
+    function_map = ucx_map_new(1337);
 }
 
-void add_function(struct FuncStruct *func) {
-    printf("add function: %s\n", func->name);
-
+void add_function(FuncStruct *func) {
+    printf("add_function %s\n", func->name);
     struct FuncStruct *f = malloc(sizeof(FuncStruct));
     *f = *func;
-    ucx_map_cstr_put(function_map, (char*)f->name, func);
+    ucx_map_cstr_put(function_map, (char*)f->name, f);
 }
 
-void add_functions(struct FuncStruct *funcs) {
+void add_functions(FuncStruct *funcs) {
     int i = 0;
     while(funcs[i].func != NULL) {  
         add_function(&funcs[i]);
--- a/src/server/daemon/httplistener.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/daemon/httplistener.c	Sat Jan 28 16:01:07 2012 +0100
@@ -96,6 +96,7 @@
     /* bind server socket to address */
     if(bind(listener->server_socket, (struct sockaddr*)&servaddr, sizeof(servaddr))){
         perror("Error: http_listener_new: bind");
+        printf("port: %d\n", conf->port);
         return NULL;
     }
 
--- a/src/server/daemon/httpparser.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/daemon/httpparser.c	Sat Jan 28 16:01:07 2012 +0100
@@ -121,6 +121,9 @@
                 parser->offset = buf->pos;
                 if(parser->value.ptr != NULL) {
                     buf->inbuf[buf->pos-1] = 0;
+                    if(buf->inbuf[buf->pos-2] == '\r') {
+                        buf->inbuf[buf->pos-2] = 0;
+                    }
                     // add header
                     header_add(
                             parser->request->headers,
--- a/src/server/daemon/httprequest.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/daemon/httprequest.c	Sat Jan 28 16:01:07 2012 +0100
@@ -98,6 +98,7 @@
     rq->vs = request->connection->listener->default_vs.vs;
 
     /* Pass request line as "clf-request" */
+    /* TODO: with or without \r\n ? */
     pblock_kvinsert(
             pb_key_clf_request,
             request->request_line.ptr,
@@ -122,12 +123,35 @@
             rq->rq.reqpb);
     // TODO: protocol num
 
-    /* Pass any query as "query" in reqpb */
-    // TODO: query
+    /*
+     * get absolute path and query of the request uri
+     */
+    // TODO: check for '#'
+    sstr_t absPath = request->uri;
+    sstr_t query;
+    query.length = 0;
+    
+    for(int i=0;i<request->uri.length;i++) {
+        if(request->uri.ptr[i] == '?') {
+            /* split uri in path and query */
+            if(absPath.length > i + 2) {
+                query.length = absPath.length - i - 1;
+                query.ptr = absPath.ptr + i + 1;
+            }
+            absPath.length = i;
+
+            /* Pass any query as 'query' in reqpb */
+            pblock_kvinsert(
+                    pb_key_query,
+                    query.ptr,
+                    query.length,
+                    rq->rq.reqpb);
+
+            break;
+        }
+    }
 
     /* Get abs_path part of request URI, and canonicalize the path */
-    sstr_t absPath = request->uri;
-    // TODO: get abs_path
     absPath.ptr = util_canonicalize_uri(
             request->pool,
             absPath.ptr,
@@ -137,7 +161,7 @@
     /* Decode the abs_path */
     // TODO: decode abs_path
 
-    /* Pass the abs_path as "uri" in reqpb */
+    /* Pass the abs_path as 'uri' in reqpb */
     // TODO: pass abs_path to reqpb
     // TODO: replace this code
     pblock_kvinsert(
@@ -162,7 +186,19 @@
         if(ha->headers[i].name[0] < 90) {
             ha->headers[i].name[0] += 32;
         }
-        pblock_nvinsert(ha->headers[i].name, ha->headers[i].value, rq->rq.headers);
+
+        /* change to lower case */
+        char *header_name = ha->headers[i].name;
+        for(int i=0;header_name[i]!=0;i++) {
+            if(header_name[i] > 64 && header_name[i] < 97) {
+                header_name[i] += 32;
+            }
+        }
+
+        pblock_nvinsert(
+                ha->headers[i].name,
+                ha->headers[i].value,
+                rq->rq.headers);
     }
 
     /* check for request body and prepare input buffer */
@@ -361,6 +397,7 @@
         }
         /* if there is a trailing '/', remove it */
         if(docroot.ptr[docroot.length - 1] == '/') {
+            docroot.ptr[docroot.length - 1] = 0; // TODO: can I do this?
             docroot.length--;
         }
 
@@ -458,6 +495,7 @@
 
     int ret = rq->context.last_req_code;
     char *content_type = NULL;
+    char *method = NULL;
     for(int i=NCX_OI(rq);i>=0;i--) {
         httpd_object *obj = objset->obj[i];   
         dtable *dt = object_get_dtable(obj, NSAPIService);
@@ -481,7 +519,22 @@
                 }
             }
 
+            /* check method parameter */
+            char *dmt = pblock_findkeyval(pb_key_method, d->param);
+            if(dmt) {
+                if(!method) {
+                    method = pblock_findkeyval(pb_key_method, rq->rq.reqpb);
+                }
+
+                if(!method_match(dmt, method)) {
+                    continue;
+                }
+            }
+
             ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+            if(ret != REQ_PROCEED) {
+                fprintf(stderr, "saf not proceed\n");
+            }
             if(ret != REQ_NOACTION) {
                 if(ret == REQ_PROCESSING) {
                     /* save nsapi context */
@@ -499,6 +552,43 @@
     return ret;
 }
 
+
+/*
+ * checks if the method matches the cmp string
+ * the format of cmp is a single method string or a list of methods
+ * (method1|method2|method3|...)
+ */
+int method_match(char *cmp, char *method) {
+    if(cmp[0] != '(') {
+        /* not a list of methods, so just compare the 2 strings */
+        if(!strcmp(cmp, method)) {
+            return 1;
+        }
+    } else if(cmp[0] == 0) {
+        /* empty string */
+        return 0;
+    }
+
+    size_t method_len = strlen(method);
+    size_t last_pos = 0;
+    cmp++; /* skip '(' */
+    for(int i=0;cmp[i]!=0;i++) {
+        char c = cmp[i];
+        if(c == '|' || c == ')') {
+            size_t len = i - last_pos;
+            if(len == method_len) {
+                char *cp = cmp + last_pos;
+                if(!memcmp(cp, method, len)) {
+                    return 1;
+                }
+            }
+            last_pos = i + 1;
+        }
+    }
+
+    return 0;
+}
+
 /*
  * adds objects with specific name or path to the httpd_objset
  */
@@ -523,7 +613,6 @@
         httpd_object *obj = objs->objects[i];
 
         if(obj->name && !strcmp(name, obj->name)) {
-            printf("name is %s -> add object %s\n", name, obj->name);
             objset_add_object(sn->sn.pool, os, obj);
         }
     } 
--- a/src/server/daemon/httprequest.h	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/daemon/httprequest.h	Sat Jan 28 16:01:07 2012 +0100
@@ -92,6 +92,8 @@
         char *name,
         char *path);
 
+int method_match(char *cmp, char *method);
+
 /* request.h functions */
 int request_initialize(
         pool_handle_t *pool,
--- a/src/server/daemon/ws-fn.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/daemon/ws-fn.c	Sat Jan 28 16:01:07 2012 +0100
@@ -36,12 +36,14 @@
 
 struct FuncStruct webserver_funcs[] = {
     { "init-test", init_test, NULL, 0 },
+    { "load-modules", load_modules, NULL, 0},
     { "test-nametrans", test_nametrans, NULL, 0 },
     { "assign-name", assign_name, NULL, 0},
     { "type-by-extension", object_type_by_extension, NULL, 0},
     { "send-file", send_file, NULL, 0},
     { "common-index", service_index, NULL, 0},
     { "service-hello", service_hello, NULL, 0},
+    { "send-options", send_options, NULL, 0},
     { "webdav-service", webdav_service, NULL, 0},
     {NULL, NULL, NULL, 0}
 };
--- a/src/server/safs/init.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/safs/init.c	Sat Jan 28 16:01:07 2012 +0100
@@ -26,9 +26,63 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <dlfcn.h> 
+
 #include "init.h"
+#include "../ucx/string.h"
+#include "../daemon/func.h"
 
 int init_test(pblock *pb, Session *sn, Request *rq) {
     printf("init-test\n");
     return REQ_PROCEED;
 }
+
+int load_modules(pblock *pb, Session *sn, Request *rq) {
+    printf("load_modules\n");
+
+    char *shlib = pblock_findval("shlib", pb);
+    char *funcs = pblock_findval("funcs", pb);
+
+    if(shlib == NULL || funcs == NULL) {
+        fprintf(stderr, "load-modules: missing parameter\n");
+    }
+
+    /* load lib */
+    void *lib = dlopen(shlib, RTLD_GLOBAL | RTLD_NOW);
+    if(lib == NULL) {
+        fprintf(stderr, "Cannot load library %s\n", shlib);
+        return REQ_ABORTED;
+    }
+
+    /* load function symbols */
+    int b = 0;
+    for(int i=0;;i++) {
+        if(funcs[i] == ','  || funcs[i] == 0) {
+            if(funcs[i] == 0) {
+                b = 1;
+            }
+
+            funcs[i] = 0;
+
+            /* we have a function name */
+            void *sym = dlsym(lib, funcs);
+            if(sym == NULL) {
+                fprintf(stderr, "Cannot load symbol %s\n", funcs);
+                return REQ_ABORTED;
+            }
+            struct FuncStruct fc;
+            fc.func = (FuncPtr)sym;
+            fc.name = sstrdub(sstr(funcs)).ptr;
+            add_function(&fc);
+
+            if(b) {
+                break;
+            }
+
+            funcs += i + 1;
+            i = 0;
+        }
+    }
+
+    return REQ_PROCEED;
+}
--- a/src/server/safs/init.h	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/safs/init.h	Sat Jan 28 16:01:07 2012 +0100
@@ -37,6 +37,8 @@
 
 int init_test(pblock *pb, Session *sn, Request *rq);
 
+int load_modules(pblock *pb, Session *sn, Request *rq);
+
 
 #ifdef	__cplusplus
 }
--- a/src/server/safs/objecttype.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/safs/objecttype.c	Sat Jan 28 16:01:07 2012 +0100
@@ -34,7 +34,7 @@
 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);
+    //printf("\nobject_type_by_extension: {%s}[%d]\n\n", ppath);
 
     sstr_t ct;
     if(ppath.ptr[ppath.length - 1] == '/') {
@@ -65,7 +65,7 @@
         } else if(!sstrcmp(ext, sstrn("xml", 3))) {
             ct = sstr("text/xml");
         } else {
-            return REQ_ABORTED;
+            return REQ_NOACTION;
         }
     }
 
--- a/src/server/safs/service.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/safs/service.c	Sat Jan 28 16:01:07 2012 +0100
@@ -141,6 +141,8 @@
 }
 
 int service_hello(pblock *pb, Session *sn, Request *rq) {
+    pblock_removekey(pb_key_content_type, rq->srvhdrs);
+    pblock_nvinsert("content-type", "text/plain", rq->srvhdrs);
     pblock_nninsert("content-length", 13, rq->srvhdrs);
     protocol_status(sn, rq, 200, NULL);
     http_start_response(sn, rq);
@@ -225,3 +227,18 @@
 
     return REQ_PROCEED;
 }
+
+int send_options(pblock *pb, Session *sn, Request *rq) {
+    char *allow = "HEAD, GET, PUT, DELETE, TRACE, OPTIONS, MOVE, COPY, "
+            "PROPFIND, PROPPATCH, MKCOL, LOCK, UNLOCK, ACL, REPORT";
+    char *dav = "1,2,access-control";
+
+    pblock_removekey(pb_key_content_type, rq->srvhdrs);
+    pblock_nvinsert("allow", allow, rq->srvhdrs);
+    pblock_nvinsert("dav", dav, rq->srvhdrs);
+    pblock_nninsert("content-length", 0, rq->srvhdrs);
+    protocol_status(sn, rq, 200, NULL);
+    http_start_response(sn, rq);
+
+    return REQ_PROCEED;
+}
--- a/src/server/safs/service.h	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/safs/service.h	Sat Jan 28 16:01:07 2012 +0100
@@ -41,6 +41,8 @@
 
 int service_index(pblock *pb, Session *sn, Request *rq);
 
+int send_options(pblock *pb, Session *sn, Request *rq);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/src/server/util/io.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/util/io.c	Sat Jan 28 16:01:07 2012 +0100
@@ -95,7 +95,7 @@
     ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes);
     if(r < 0) {
         return IO_ERROR;
-    }
+    }  
     return r;
 }
 
--- a/src/server/webdav/webdav.c	Sat Jan 21 16:37:35 2012 +0100
+++ b/src/server/webdav/webdav.c	Sat Jan 28 16:01:07 2012 +0100
@@ -56,6 +56,7 @@
         xml_len = atoi(ctlen);
     } else {
         /* invalid request */
+        printf("invalid request\n");
         return REQ_ABORTED;
     }
 
@@ -63,6 +64,7 @@
     xml_body[xml_len] = 0;
     if(!xml_body) {
         /* server error */
+        printf("server error\n");
         return REQ_ABORTED;
     }
 

mercurial