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; |