diff -r 6b15a094d996 -r 74a81d9e19d0 src/server/daemon/httprequest.c --- a/src/server/daemon/httprequest.c Mon Oct 14 13:36:28 2013 +0200 +++ b/src/server/daemon/httprequest.c Sun Nov 03 16:41:42 2013 +0100 @@ -319,7 +319,6 @@ int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq) { int r = REQ_NOACTION; - do { switch(rq->phase) { case NSAPIAuthTrans: { @@ -363,29 +362,50 @@ if(r != REQ_PROCEED) { break; } - rq->phase++; + rq->phase = NSAPIAddLog; // skip NSAPIError nsapi_context_next_stage(&rq->context); } case NSAPIAddLog: { //printf(">>> AddLog\n"); r = nsapi_addlog(sn, rq); - if(r != REQ_PROCESSING && r != REQ_ABORTED) { + if(r == REQ_PROCESSING) { break; } - rq->phase++; - nsapi_context_next_stage(&rq->context); + // finish request + r = REQ_PROCEED; + break; } default: // should not happen, but when it does, finish the req case REQ_FINISH: { //printf(">>> Finish\n"); - r = nsapi_finish_request(sn, rq); + //r = nsapi_finish_request(sn, rq); + r = REQ_PROCEED; + break; + } + case NSAPIError: { + //printf(">>> Error\n"); + r = nsapi_error(sn, rq); + if(r == REQ_PROCEED) { + // restart the loop to switch to AddLog directive + r = REQ_RESTART; + rq->phase = NSAPIAddLog; + nsapi_context_next_stage(&rq->context); + } else { + /* + * an error occured while handling an error + * leave loop to finish the request (without AddLog) + */ + r = REQ_PROCEED; + break; + } } } if(r == REQ_ABORTED) { - // if an error occurred, we send an error page - nsapi_error_request((Session*)sn, (Request*)rq); - break; + // switch to NSAPIError + rq->phase = NSAPIError; + nsapi_context_next_stage(&rq->context); + r = REQ_RESTART; } } while (r == REQ_RESTART); @@ -706,6 +726,69 @@ return ret; } +int nsapi_error(NSAPISession *sn, NSAPIRequest *rq) { + //printf("nsapi_error\n"); + httpd_objset *objset = rq->rq.os; + + if(NCX_OI(rq) == -1) { + NCX_OI(rq) = objset->pos - 1; + } + + int ret = rq->context.last_req_code; + for(int i=NCX_OI(rq);i>=0;i--) { + httpd_object *obj = objset->obj[i]; + dtable *dt = object_get_dtable(obj, NSAPIError); + + // execute directives + for(int j=NCX_DI(rq);jndir;j++) { + if(ret == REQ_NOACTION) { + directive *d = dt->dirs[j]; + + // check status code parameter + char *status = pblock_findkeyval(pb_key_type, d->param); + if(status) { + int statuscode = atoi(status); + if(statuscode != rq->rq.status_num) { + continue; + } + } + + // execute the saf + ret = nsapi_exec(d, sn, rq); + } + + if(ret == REQ_ABORTED) { + // if an error directive fails, we use the default + // error handler + break; + } + if(ret != REQ_NOACTION) { + if(ret == REQ_PROCEED) { + /* + * flush buffer and add termination if chunked encoding + * is enabled + */ + net_finish(sn->sn.csd); + } else if(ret == REQ_PROCESSING) { + // save nsapi context + rq->context.objset_index = i; + + // add +1 to start next round with next function + rq->context.dtable_index = j + 1; + } + return ret; + } + } + } + + if(ret != REQ_PROCEED) { + // default error handler + nsapi_error_request((Session*)sn, (Request*)rq); + } + + return ret; +} + int nsapi_addlog(NSAPISession *sn, NSAPIRequest *rq) { //printf("nsapi_addlog\n"); httpd_objset *objset = rq->rq.os;