diff options
-rw-r--r-- | modules/generators/mod_cgi.c | 29 | ||||
-rw-r--r-- | modules/generators/mod_cgid.c | 29 |
2 files changed, 56 insertions, 2 deletions
diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index b0ffdabe25..4d3b0783d2 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -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"); diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 3aeca2a192..de7cdaf42f 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -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"); |