diff -r d680536f8c2f -r 7b235fa88008 src/server/daemon/httprequest.c --- 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;iuri.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); } }