src/server/daemon/httprequest.c

changeset 37
360b9aabe17e
parent 36
450d2d5f4735
child 38
d07810b02147
equal deleted inserted replaced
36:450d2d5f4735 37:360b9aabe17e
55 req->headers = hd; 55 req->headers = hd;
56 56
57 return req; 57 return req;
58 } 58 }
59 59
60 int handle_request(HTTPRequest *request) { 60 int handle_request(HTTPRequest *request, threadpool_t *thrpool) {
61 // handle nsapi request 61 // handle nsapi request
62 62
63 // create pool 63 // create pool
64 request->pool = pool_create(); 64 request->pool = pool_create();
65 65
248 } 248 }
249 } else { 249 } else {
250 sn->sn.inbuf = NULL; 250 sn->sn.inbuf = NULL;
251 } 251 }
252 252
253 253 //
254 // Send the request to the NSAPI system 254 // Send the request to the NSAPI system
255 nsapi_handle_request(sn, rq); 255 //
256
257 // compare current and listener thread pool
258 threadpool_t *lstp = request->connection->listener->threadpool;
259 sn->defaultpool = lstp;
260 if(lstp == thrpool) {
261 sn->currentpool = thrpool;
262 nsapi_handle_request(sn, rq);
263 } else {
264 // execute nsapi functions on a different thread pool
265 nsapi_change_threadpool(sn, rq, lstp);
266 }
256 267
257 return 0; 268 return 0;
258 } 269 }
259 270
260 271
281 * NSAPI Processing 292 * NSAPI Processing
282 * TODO: add this to new file 293 * TODO: add this to new file
283 */ 294 */
284 295
285 int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq) { 296 int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq) {
286 // TODO: threadpool
287
288 int r = REQ_NOACTION; 297 int r = REQ_NOACTION;
289 298
290 do { 299 do {
291 switch(rq->phase) { 300 switch(rq->phase) {
292 case NSAPIAuthTrans: { 301 case NSAPIAuthTrans: {
348 nsapi_error_request(sn, rq); 357 nsapi_error_request(sn, rq);
349 } 358 }
350 359
351 } while (r == REQ_RESTART); 360 } while (r == REQ_RESTART);
352 361
353 r = nsapi_finish_request(sn, rq); 362 if(r != REQ_PROCESSING) {
363 r = nsapi_finish_request(sn, rq);
364 }
354 365
355 return r; 366 return r;
356 } 367 }
357 368
358 int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq) { 369 int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq) {
373 httpd_object *obj = objconf->objects[0]; 384 httpd_object *obj = objconf->objects[0];
374 dtable *dt = object_get_dtable(obj, NSAPIAuthTrans); 385 dtable *dt = object_get_dtable(obj, NSAPIAuthTrans);
375 386
376 int ret = rq->context.last_req_code; 387 int ret = rq->context.last_req_code;
377 for(int i=NCX_DI(rq);i<dt->ndir;i++) { 388 for(int i=NCX_DI(rq);i<dt->ndir;i++) {
378 directive *d = dt->dirs[i]; 389 if(ret == REQ_NOACTION) {
379 390 directive *d = dt->dirs[i];
380 ret = d->func->func(d->param, (Session*)sn, (Request*)rq); 391 ret = nsapi_exec(d, sn, rq);
392 }
393
381 if(ret != REQ_NOACTION) { 394 if(ret != REQ_NOACTION) {
382 /* 395 /*
383 * if a saf is still processing, we need to save the context, to 396 * if a saf is still processing, we need to save the context, to
384 * process this object at a later time 397 * process this object at a later time
385 */ 398 */
411 /* execute directives */ 424 /* execute directives */
412 int ret = rq->context.last_req_code; 425 int ret = rq->context.last_req_code;
413 char *name = NULL; 426 char *name = NULL;
414 char *ppath = NULL; 427 char *ppath = NULL;
415 for(int i=NCX_DI(rq);i<dt->ndir;i++) { 428 for(int i=NCX_DI(rq);i<dt->ndir;i++) {
416 directive *d = dt->dirs[i]; 429 if(ret == REQ_NOACTION) {
417 430 directive *d = dt->dirs[i];
418 ret = d->func->func(d->param, (Session*)sn, (Request*)rq); 431 ret = nsapi_exec(d, sn, rq);
432 }
419 433
420 /* check for name or ppath */ 434 /* check for name or ppath */
421 name = pblock_findkeyval(pb_key_name, rq->rq.vars); 435 name = pblock_findkeyval(pb_key_name, rq->rq.vars);
422 ppath = pblock_findkeyval(pb_key_ppath, rq->rq.vars); 436 ppath = pblock_findkeyval(pb_key_ppath, rq->rq.vars);
423 437
484 for(int i=NCX_OI(rq);i>=0;i--) { 498 for(int i=NCX_OI(rq);i>=0;i--) {
485 httpd_object *obj = objset->obj[i]; 499 httpd_object *obj = objset->obj[i];
486 dtable *dt = object_get_dtable(obj, NSAPIPathCheck); 500 dtable *dt = object_get_dtable(obj, NSAPIPathCheck);
487 501
488 // execute directives 502 // execute directives
489 for(int j=0;j<dt->ndir;j++) { 503 for(int j=NCX_DI(rq);j<dt->ndir;j++) {
490 directive *d = dt->dirs[j]; 504 if(ret == REQ_NOACTION) {
491 505 directive *d = dt->dirs[j];
492 /* execute the saf */ 506 ret = nsapi_exec(d, sn, rq);
493 ret = d->func->func(d->param, (Session*)sn, (Request*)rq); 507 }
508
494 if(ret != REQ_NOACTION) { 509 if(ret != REQ_NOACTION) {
495 if(ret == REQ_PROCESSING) { 510 if(ret == REQ_PROCESSING) {
496 /* save nsapi context */ 511 /* save nsapi context */
497 rq->context.objset_index = i; 512 rq->context.objset_index = i;
498 513
526 for(int i=NCX_OI(rq);i>=0;i--) { 541 for(int i=NCX_OI(rq);i>=0;i--) {
527 httpd_object *obj = objset->obj[i]; 542 httpd_object *obj = objset->obj[i];
528 dtable *dt = object_get_dtable(obj, NSAPIObjectType); 543 dtable *dt = object_get_dtable(obj, NSAPIObjectType);
529 544
530 // execute directives 545 // execute directives
531 for(int j=0;j<dt->ndir;j++) { 546 for(int j=NCX_DI(rq);j<dt->ndir;j++) {
532 directive *d = dt->dirs[j]; 547 if(ret == REQ_NOACTION) {
533 548 directive *d = dt->dirs[j];
534 ret = d->func->func(d->param, (Session*)sn, (Request*)rq); 549 ret = nsapi_exec(d, sn, rq);
550 }
551
535 switch(ret) { 552 switch(ret) {
536 case REQ_PROCEED: { 553 case REQ_PROCEED: {
537 char *type = pblock_findkeyval( 554 char *type = pblock_findkeyval(
538 pb_key_content_type, 555 pb_key_content_type,
539 rq->rq.srvhdrs); 556 rq->rq.srvhdrs);
594 for(int i=NCX_OI(rq);i>=0;i--) { 611 for(int i=NCX_OI(rq);i>=0;i--) {
595 httpd_object *obj = objset->obj[i]; 612 httpd_object *obj = objset->obj[i];
596 dtable *dt = object_get_dtable(obj, NSAPIService); 613 dtable *dt = object_get_dtable(obj, NSAPIService);
597 614
598 // execute directives 615 // execute directives
599 for(int j=0;j<dt->ndir;j++) { 616 for(int j=NCX_DI(rq);j<dt->ndir;j++) {
600 directive *d = dt->dirs[j]; 617 if(ret == REQ_NOACTION) {
601 618 directive *d = dt->dirs[j];
602 /* check type parameter */ 619
603 char *dtp = pblock_findkeyval(pb_key_type, d->param); 620 /* check type parameter */
604 if(dtp) { 621 char *dtp = pblock_findkeyval(pb_key_type, d->param);
605 /* type parameter for directive */ 622 if(dtp) {
606 if(!content_type) { 623 /* type parameter for directive */
607 content_type = pblock_findkeyval( 624 if(!content_type) {
608 pb_key_content_type, 625 content_type = pblock_findkeyval(
609 rq->rq.srvhdrs); 626 pb_key_content_type,
610 } 627 rq->rq.srvhdrs);
611 /* compare types */ 628 }
612 if(strcmp(dtp, content_type) != 0) { 629 /* compare types */
613 continue; 630 if(strcmp(dtp, content_type) != 0) {
614 } 631 continue;
615 } 632 }
616 633 }
617 /* check method parameter */ 634
618 char *dmt = pblock_findkeyval(pb_key_method, d->param); 635 /* check method parameter */
619 if(dmt) { 636 char *dmt = pblock_findkeyval(pb_key_method, d->param);
620 if(!method) { 637 if(dmt) {
621 method = pblock_findkeyval(pb_key_method, rq->rq.reqpb); 638 if(!method) {
622 } 639 method = pblock_findkeyval(pb_key_method, rq->rq.reqpb);
623 640 }
624 if(!method_match(dmt, method)) { 641
625 continue; 642 if(!method_match(dmt, method)) {
626 } 643 continue;
627 } 644 }
628 645 }
629 /* execute the saf */ 646
630 ret = d->func->func(d->param, (Session*)sn, (Request*)rq); 647 /* execute the saf */
648 ret = nsapi_exec(d, sn, rq);
649 }
650
651
631 if(ret != REQ_PROCEED) { 652 if(ret != REQ_PROCEED) {
632 fprintf(stderr, "saf not proceed\n"); 653 fprintf(stderr, "saf not proceed\n");
633 } 654 }
634 if(ret != REQ_NOACTION) { 655 if(ret != REQ_NOACTION) {
635 if(ret == REQ_PROCESSING) { 656 if(ret == REQ_PROCESSING) {
644 } 665 }
645 } 666 }
646 } 667 }
647 668
648 return ret; 669 return ret;
670 }
671
672 struct _tpd_data {
673 NSAPISession *sn;
674 NSAPIRequest *rq;
675 directive *directive;
676 threadpool_t *threadpool;
677 };
678
679 int nsapi_exec(directive *d, NSAPISession *sn, NSAPIRequest *rq) {
680 // TODO: condition
681
682 char *poolname = pblock_findkeyval(pb_key_pool, d->param);
683 if(poolname) {
684 threadpool_t *pool = get_threadpool(sstr(poolname));
685 if(pool && pool != sn->currentpool) {
686 // execute directive in different thread pool
687 return nsapi_exec_tp(d, sn, rq, pool);
688 }
689 } else if(sn->currentpool != sn->defaultpool) {
690 // if no pool is set, use always the default thread pool
691 return nsapi_exec_tp(d, sn, rq, sn->defaultpool);
692 }
693
694 return d->func->func(d->param, (Session*)sn, (Request*)rq);
695 }
696
697 int nsapi_exec_tp(
698 directive *d,
699 NSAPISession *sn,
700 NSAPIRequest *rq,
701 threadpool_t *pool)
702 {
703 struct _tpd_data *data = malloc(sizeof(struct _tpd_data));
704 if(data == NULL) {
705 // TODO: set error
706 return REQ_ABORTED;
707 }
708 data->sn = sn;
709 data->rq = rq;
710 data->directive = d;
711 data->threadpool = pool;
712
713 sn->currentpool = pool;
714 threadpool_run(pool, thrpool_exec, data);
715
716 return REQ_PROCESSING;
717 }
718
719 void nsapi_function_return(Session *session, Request *request, int ret) {
720 NSAPISession *sn = (NSAPISession*)session;
721 NSAPIRequest *rq = (NSAPIRequest*)request;
722
723 rq->context.last_req_code = ret;
724
725 if(sn->currentpool != sn->defaultpool) {
726 nsapi_change_threadpool(sn, rq, sn->defaultpool);
727 } else {
728 nsapi_handle_request(sn, rq);
729 }
730 }
731
732 void nsapi_change_threadpool(
733 NSAPISession *sn,
734 NSAPIRequest *rq,
735 threadpool_t *thrpool)
736 {
737 struct _tpd_data *data = malloc(sizeof(struct _tpd_data));
738 data->sn = sn;
739 data->rq = rq;
740 data->threadpool = thrpool;
741
742 threadpool_run(thrpool, thrpool_change, data);
743 }
744
745 void* thrpool_exec(void *d) {
746 struct _tpd_data *data = d;
747
748 data->sn->currentpool = data->threadpool;
749 int r = data->directive->func->func(
750 data->directive->param,
751 (Session*)data->sn,
752 (Request*)data->rq);
753
754 free(data);
755
756 nsapi_function_return((Session*)data->sn, (Request*)data->rq, r);
757
758 return NULL;
759 }
760
761 void* thrpool_change(void *d) {
762 struct _tpd_data *data = d;
763
764 data->sn->currentpool = data->threadpool;
765 nsapi_handle_request(data->sn, data->rq);
766
767 free(data);
768 return NULL;
649 } 769 }
650 770
651 771
652 /* 772 /*
653 * checks if the method matches the cmp string 773 * checks if the method matches the cmp string

mercurial