src/server/daemon/httprequest.c

changeset 20
7b235fa88008
parent 19
d680536f8c2f
child 21
627b09ee74e4
equal deleted inserted replaced
19:d680536f8c2f 20:7b235fa88008
96 96
97 // set default virtual server 97 // set default virtual server
98 rq->vs = request->connection->listener->default_vs.vs; 98 rq->vs = request->connection->listener->default_vs.vs;
99 99
100 /* Pass request line as "clf-request" */ 100 /* Pass request line as "clf-request" */
101 /* TODO: with or without \r\n ? */
101 pblock_kvinsert( 102 pblock_kvinsert(
102 pb_key_clf_request, 103 pb_key_clf_request,
103 request->request_line.ptr, 104 request->request_line.ptr,
104 request->request_line.length, 105 request->request_line.length,
105 rq->rq.reqpb); 106 rq->rq.reqpb);
120 request->httpv.ptr, 121 request->httpv.ptr,
121 request->httpv.length, 122 request->httpv.length,
122 rq->rq.reqpb); 123 rq->rq.reqpb);
123 // TODO: protocol num 124 // TODO: protocol num
124 125
125 /* Pass any query as "query" in reqpb */ 126 /*
126 // TODO: query 127 * get absolute path and query of the request uri
128 */
129 // TODO: check for '#'
130 sstr_t absPath = request->uri;
131 sstr_t query;
132 query.length = 0;
133
134 for(int i=0;i<request->uri.length;i++) {
135 if(request->uri.ptr[i] == '?') {
136 /* split uri in path and query */
137 if(absPath.length > i + 2) {
138 query.length = absPath.length - i - 1;
139 query.ptr = absPath.ptr + i + 1;
140 }
141 absPath.length = i;
142
143 /* Pass any query as 'query' in reqpb */
144 pblock_kvinsert(
145 pb_key_query,
146 query.ptr,
147 query.length,
148 rq->rq.reqpb);
149
150 break;
151 }
152 }
127 153
128 /* Get abs_path part of request URI, and canonicalize the path */ 154 /* Get abs_path part of request URI, and canonicalize the path */
129 sstr_t absPath = request->uri;
130 // TODO: get abs_path
131 absPath.ptr = util_canonicalize_uri( 155 absPath.ptr = util_canonicalize_uri(
132 request->pool, 156 request->pool,
133 absPath.ptr, 157 absPath.ptr,
134 absPath.length, 158 absPath.length,
135 (int*)&absPath.length); 159 (int*)&absPath.length);
136 160
137 /* Decode the abs_path */ 161 /* Decode the abs_path */
138 // TODO: decode abs_path 162 // TODO: decode abs_path
139 163
140 /* Pass the abs_path as "uri" in reqpb */ 164 /* Pass the abs_path as 'uri' in reqpb */
141 // TODO: pass abs_path to reqpb 165 // TODO: pass abs_path to reqpb
142 // TODO: replace this code 166 // TODO: replace this code
143 pblock_kvinsert( 167 pblock_kvinsert(
144 pb_key_uri, 168 pb_key_uri,
145 absPath.ptr, 169 absPath.ptr,
160 } 184 }
161 185
162 if(ha->headers[i].name[0] < 90) { 186 if(ha->headers[i].name[0] < 90) {
163 ha->headers[i].name[0] += 32; 187 ha->headers[i].name[0] += 32;
164 } 188 }
165 pblock_nvinsert(ha->headers[i].name, ha->headers[i].value, rq->rq.headers); 189
190 /* change to lower case */
191 char *header_name = ha->headers[i].name;
192 for(int i=0;header_name[i]!=0;i++) {
193 if(header_name[i] > 64 && header_name[i] < 97) {
194 header_name[i] += 32;
195 }
196 }
197
198 pblock_nvinsert(
199 ha->headers[i].name,
200 ha->headers[i].value,
201 rq->rq.headers);
166 } 202 }
167 203
168 /* check for request body and prepare input buffer */ 204 /* check for request body and prepare input buffer */
169 char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers); 205 char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers);
170 if(ctlen_str) { 206 if(ctlen_str) {
359 printf("docroot too short\n"); 395 printf("docroot too short\n");
360 return REQ_ABORTED; /* docroot too short */ 396 return REQ_ABORTED; /* docroot too short */
361 } 397 }
362 /* if there is a trailing '/', remove it */ 398 /* if there is a trailing '/', remove it */
363 if(docroot.ptr[docroot.length - 1] == '/') { 399 if(docroot.ptr[docroot.length - 1] == '/') {
400 docroot.ptr[docroot.length - 1] = 0; // TODO: can I do this?
364 docroot.length--; 401 docroot.length--;
365 } 402 }
366 403
367 sstr_t uri = sstr(pblock_findkeyval(pb_key_uri, rq->rq.reqpb)); 404 sstr_t uri = sstr(pblock_findkeyval(pb_key_uri, rq->rq.reqpb));
368 405
456 NCX_OI(rq) = objset->pos - 1; 493 NCX_OI(rq) = objset->pos - 1;
457 } 494 }
458 495
459 int ret = rq->context.last_req_code; 496 int ret = rq->context.last_req_code;
460 char *content_type = NULL; 497 char *content_type = NULL;
498 char *method = NULL;
461 for(int i=NCX_OI(rq);i>=0;i--) { 499 for(int i=NCX_OI(rq);i>=0;i--) {
462 httpd_object *obj = objset->obj[i]; 500 httpd_object *obj = objset->obj[i];
463 dtable *dt = object_get_dtable(obj, NSAPIService); 501 dtable *dt = object_get_dtable(obj, NSAPIService);
464 502
465 // execute directives 503 // execute directives
479 if(strcmp(dtp, content_type) != 0) { 517 if(strcmp(dtp, content_type) != 0) {
480 continue; 518 continue;
481 } 519 }
482 } 520 }
483 521
522 /* check method parameter */
523 char *dmt = pblock_findkeyval(pb_key_method, d->param);
524 if(dmt) {
525 if(!method) {
526 method = pblock_findkeyval(pb_key_method, rq->rq.reqpb);
527 }
528
529 if(!method_match(dmt, method)) {
530 continue;
531 }
532 }
533
484 ret = d->func->func(d->param, (Session*)sn, (Request*)rq); 534 ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
535 if(ret != REQ_PROCEED) {
536 fprintf(stderr, "saf not proceed\n");
537 }
485 if(ret != REQ_NOACTION) { 538 if(ret != REQ_NOACTION) {
486 if(ret == REQ_PROCESSING) { 539 if(ret == REQ_PROCESSING) {
487 /* save nsapi context */ 540 /* save nsapi context */
488 rq->context.objset_index = i; 541 rq->context.objset_index = i;
489 542
495 } 548 }
496 } 549 }
497 } 550 }
498 551
499 return ret; 552 return ret;
553 }
554
555
556 /*
557 * checks if the method matches the cmp string
558 * the format of cmp is a single method string or a list of methods
559 * (method1|method2|method3|...)
560 */
561 int method_match(char *cmp, char *method) {
562 if(cmp[0] != '(') {
563 /* not a list of methods, so just compare the 2 strings */
564 if(!strcmp(cmp, method)) {
565 return 1;
566 }
567 } else if(cmp[0] == 0) {
568 /* empty string */
569 return 0;
570 }
571
572 size_t method_len = strlen(method);
573 size_t last_pos = 0;
574 cmp++; /* skip '(' */
575 for(int i=0;cmp[i]!=0;i++) {
576 char c = cmp[i];
577 if(c == '|' || c == ')') {
578 size_t len = i - last_pos;
579 if(len == method_len) {
580 char *cp = cmp + last_pos;
581 if(!memcmp(cp, method, len)) {
582 return 1;
583 }
584 }
585 last_pos = i + 1;
586 }
587 }
588
589 return 0;
500 } 590 }
501 591
502 /* 592 /*
503 * adds objects with specific name or path to the httpd_objset 593 * adds objects with specific name or path to the httpd_objset
504 */ 594 */
521 611
522 for(int i=0;i<objs->nobj;i++) { 612 for(int i=0;i<objs->nobj;i++) {
523 httpd_object *obj = objs->objects[i]; 613 httpd_object *obj = objs->objects[i];
524 614
525 if(obj->name && !strcmp(name, obj->name)) { 615 if(obj->name && !strcmp(name, obj->name)) {
526 printf("name is %s -> add object %s\n", name, obj->name);
527 objset_add_object(sn->sn.pool, os, obj); 616 objset_add_object(sn->sn.pool, os, obj);
528 } 617 }
529 } 618 }
530 619
531 return REQ_PROCEED; 620 return REQ_PROCEED;

mercurial