This patch addresses PRs 24884 and 25123. Please see my note at
http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=106947094322141&w=2
for a full explanation of the problem with code references.

Basically, 304s are supposed to include Expires headers if they may
have changed since the last request. Currently Apache only runs a
small fixed set of filters during error processing and there is currently
no way to add some filters back in to the output filter chain without
adding all of them back in.

This patch allows each individual filter to decide whether it is safe and
pertinent for use during error processing. A hook (the ihs_insert_error_filter
hook, in this case - pending acceptance) is run during error processing
(after the filters have been unloaded) that allows a filter to add itself
back in.

This has several desireable effects:
  >> Current default behavior is maintained unless a filter takes explicit
       action to add itself back in
  >> Filters add themselves back in according to the same filter-type as
       before, so the order that filters get called is maintained
  >> No change to the api

I don't see any undesireable effects. Does anyone else?

This, or something like it, is needed to address the RFC violation of
not returning an Expires header in 304 responses. It may also be helpful
in solving other issues related to mod_headers or other filters that should
do some processing during errors.

--
Paul J. Reder
-----------------------------------------------------------
"The strength of the Constitution lies entirely in the determination of each
citizen to defend it.  Only if every single citizen feels duty bound to do
his share in this defense are the constitutional rights secure."
-- Albert Einstein







Index: httpd-2.0/include/http_protocol.h
===================================================================
RCS file: /home/cvs/httpd-2.0/include/http_protocol.h,v
retrieving revision 1.84
diff -u -r1.84 http_protocol.h
--- httpd-2.0/include/http_protocol.h   3 Feb 2003 17:52:53 -0000       1.84
+++ httpd-2.0/include/http_protocol.h   5 Dec 2003 22:14:33 -0000
@@ -74,6 +74,13 @@
  * @package HTTP protocol handling
  */

+/**
+ * This hook allows modules to insert filters for the current error response
+ * @param r the current request
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(void,insert_error_filter,(request_rec *r))
+
 /* This is an optimization.  We keep a record of the filter_rec that
  * stores the old_write filter, so that we can avoid strcmp's later.
  */
Index: httpd-2.0/modules/http/http_protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
retrieving revision 1.473
diff -u -r1.473 http_protocol.c
--- httpd-2.0/modules/http/http_protocol.c      16 Nov 2003 02:09:13 -0000      1.473
+++ httpd-2.0/modules/http/http_protocol.c      5 Dec 2003 22:14:35 -0000
@@ -182,6 +182,11 @@
     "510 Not Extended"
 };

+APR_HOOK_STRUCT(
+    APR_HOOK_LINK(insert_error_filter)
+)
+
+AP_IMPLEMENT_HOOK_VOID(insert_error_filter, (request_rec *r), (r))

 /* The index of the first bit field that is used to index into a limit
  * bitmask. M_INVALID + 1 to METHOD_NUMBER_LAST.
@@ -2341,6 +2346,8 @@
      */

     r->output_filters = r->proto_output_filters;
+
+    ap_run_insert_error_filter(r);

     /*
      * It's possible that the Location field might be in r->err_headers_out
Index: httpd-2.0/modules/metadata/mod_expires.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/metadata/mod_expires.c,v
retrieving revision 1.48
diff -u -r1.48 mod_expires.c
--- httpd-2.0/modules/metadata/mod_expires.c    22 Nov 2003 02:11:00 -0000      1.48
+++ httpd-2.0/modules/metadata/mod_expires.c    5 Dec 2003 22:14:35 -0000
@@ -205,6 +205,7 @@
 #include "http_config.h"
 #include "http_log.h"
 #include "http_request.h"
+#include "http_protocol.h"

 typedef struct {
     int active;
@@ -585,6 +586,7 @@
 {
     ap_register_output_filter("MOD_EXPIRES", expires_filter, NULL,
                               AP_FTYPE_CONTENT_SET);
+    ap_hook_insert_error_filter(expires_insert_filter, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_insert_filter(expires_insert_filter, NULL, NULL, APR_HOOK_MIDDLE);
 }



Reply via email to