* Prevent running through the error stack by returning OK and setting r->status
authorRuediger Pluem <rpluem@apache.org>
Sun, 27 May 2007 13:57:46 +0000 (13:57 +0000)
committerRuediger Pluem <rpluem@apache.org>
Sun, 27 May 2007 13:57:46 +0000 (13:57 +0000)
  accordingly if ret is HTTP_NOT_MODIFIED as this breaks mod_cache validating a
  stale entity.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@541990 13f79535-47bb-0310-9956-ffa450edef68

modules/generators/mod_cgi.c
modules/generators/mod_cgid.c

index b0ffdabe25540ff5cd8ec64575b0979fd6f156ed..4d3b0783d2beff9cc0a38c6cdee6c0d280515d21 100644 (file)
@@ -929,7 +929,34 @@ static int cgi_handler(request_rec *r)
         int ret;
 
         if ((ret = ap_scan_script_header_err_brigade(r, bb, sbuf))) {
-            return log_script(r, conf, ret, dbuf, sbuf, bb, script_err);
+            ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err);
+
+            /*
+             * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
+             * does not set an explicit status and ap_meets_conditions, which
+             * is called by ap_scan_script_header_err_brigade, detects that
+             * the conditions of the requests are met and the response is
+             * not modified.
+             * In this case set r->status and return OK in order to prevent
+             * running through the error processing stack as this would
+             * break with mod_cache, if the conditions had been set by
+             * mod_cache itself to validate a stale entity.
+             * BTW: We circumvent the error processing stack anyway if the
+             * CGI script set an explicit status code (whatever it is) and
+             * the only possible values for ret here are:
+             *
+             * HTTP_NOT_MODIFIED          (set by ap_meets_conditions)
+             * HTTP_PRECONDITION_FAILED   (set by ap_meets_conditions)
+             * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
+             * processing of the response of the CGI script, e.g broken headers
+             * or a crashed CGI process).
+             */
+            if (ret == HTTP_NOT_MODIFIED) {
+                r->status = ret;
+                return OK;
+            }
+
+            return ret;
         }
 
         location = apr_table_get(r->headers_out, "Location");
index 3aeca2a192f96cc0a738f1dfa8d7f7222638f66a..de7cdaf42fc1b5f833b933bd092e6fe195da08af 100644 (file)
@@ -1479,7 +1479,34 @@ static int cgid_handler(request_rec *r)
         APR_BRIGADE_INSERT_TAIL(bb, b);
 
         if ((ret = ap_scan_script_header_err_brigade(r, bb, sbuf))) {
-            return log_script(r, conf, ret, dbuf, sbuf, bb, NULL);
+            ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL);
+
+            /*
+             * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
+             * does not set an explicit status and ap_meets_conditions, which
+             * is called by ap_scan_script_header_err_brigade, detects that
+             * the conditions of the requests are met and the response is
+             * not modified.
+             * In this case set r->status and return OK in order to prevent
+             * running through the error processing stack as this would
+             * break with mod_cache, if the conditions had been set by
+             * mod_cache itself to validate a stale entity.
+             * BTW: We circumvent the error processing stack anyway if the
+             * CGI script set an explicit status code (whatever it is) and
+             * the only possible values for ret here are:
+             *
+             * HTTP_NOT_MODIFIED          (set by ap_meets_conditions)
+             * HTTP_PRECONDITION_FAILED   (set by ap_meets_conditions)
+             * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
+             * processing of the response of the CGI script, e.g broken headers
+             * or a crashed CGI process).
+             */
+            if (ret == HTTP_NOT_MODIFIED) {
+                r->status = ret;
+                return OK;
+            }
+
+            return ret;
         }
 
         location = apr_table_get(r->headers_out, "Location");