src/server/daemon/httprequest.c

changeset 95
74a81d9e19d0
parent 91
fac51f87def0
child 96
0185b13bf41f
--- 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);j<dt->ndir;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;

mercurial