That is, not only when a hook/handler returns AP_FILTER_ERROR.
Graham (initially) and I made some changes to trunk (backport proposed
in r1665737) so that no internal module should return anything but
AP_FILTER_ERROR in this case, but we can't do much for third-party
modules.
That way ap_die() could become a safe gard against unintentional
double responses (hence HRS) for the same request, in any case since
it is always called at the end.
Something like:
Index: modules/http/http_request.c
===
--- modules/http/http_request.c(revision 1665647)
+++ modules/http/http_request.c(working copy)
@@ -75,6 +75,7 @@ static void update_r_in_filters(ap_filter_t *f,
static void ap_die_r(int type, request_rec *r, int recursive_error)
{
+ap_filter_t *next;
char *custom_response;
request_rec *r_1st_err = r;
@@ -83,38 +84,34 @@ static void ap_die_r(int type, request_rec *r, int
return;
}
+/*
+ * Check if we still have the ap_http_header_filter in place. If
+ * this is the case we should not ignore the error here because
+ * it means that we have not sent any response at all. Otherwise,
+ * don't send two responses for the same request.
+ */
+next = r-output_filters;
+while (next (next-frec != ap_http_header_filter_handle)) {
+next = next-next;
+}
+if (!next) {
+return;
+}
+
+/*
+ * AP_FILTER_ERROR or any invalid status, send an internal server
+ * error instead.
+ */
if (!ap_is_HTTP_VALID_RESPONSE(type)) {
-ap_filter_t *next;
-
-/*
- * Check if we still have the ap_http_header_filter in place. If
- * this is the case we should not ignore the error here because
- * it means that we have not sent any response at all and never
- * will. This is bad. Sent an internal server error instead.
- */
-next = r-output_filters;
-while (next (next-frec != ap_http_header_filter_handle)) {
- next = next-next;
-}
-
-/*
- * If next != NULL then we left the while above because of
- * next-frec == ap_http_header_filter
- */
-if (next) {
-if (type != AP_FILTER_ERROR) {
-ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01579)
- Invalid response status %i, type);
-}
-else {
-ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02831)
- Response from AP_FILTER_ERROR);
-}
-type = HTTP_INTERNAL_SERVER_ERROR;
-}
-else {
-return;
-}
+if (type != AP_FILTER_ERROR) {
+ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01579)
+ Invalid response status %i, type);
+}
+else {
+ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02831)
+ Response from AP_FILTER_ERROR);
+}
+type = HTTP_INTERNAL_SERVER_ERROR;
}
/*
--
This is not a great cycles loss since this path is not a fast one
already (!OK !DONE = ap_send_error_response() or
ap_internal_redirect()), and the inconditional loop is not really
heavy...
Thoughts?
Regards,
Yann.