Sat, 28 Jan 2012 16:01:07 +0100
Some fixes for mod_jk
--- 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; }