Bug 19355

Summary: mod_include allows invalid ETag headers
Product: Apache httpd-2 Reporter: Geoffrey Young <geoff>
Component: mod_includeAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: CLOSED FIXED    
Severity: minor    
Priority: P3    
Version: 2.0-HEAD   
Target Milestone: ---   
Hardware: All   
OS: Linux   

Description Geoffrey Young 2003-04-27 00:49:18 UTC
this bug was first reported to dev@httpd.apache.org

http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=105120818606501&w=2

mod_include has an ETag bug when activated using XBitHack Full.  in general, default_handler generates an ETag header for documents it serves.  because embedded SSI tags have the ability to alter the content of a document, mod_include strips outgoing ETag headers from responses it enters.  however, the method by which mod_include strips these headers is insufficient in cases where default_handler decides a 304 is warranted.

consider the following series of requests when XBitHack is activated for a document in DocumentRoot (uninteresting headers snipped for brevity)

GET /ssi.html HTTP/1.1

HTTP/1.1 200 OK
Last-Modified: Thu, 24 Apr 2003 16:50:50 GMT

-------------

GET /ssi.html HTTP/1.1
If-Modified-Since: Thu, 24 Apr 2003 16:50:50 GMT

HTTP/1.1 304 Not Modified
Last-Modified: Thu, 24 Apr 2003 16:50:50 GMT
ETag: "35157-5f-4861ce80"


while mod_include removes the ETag header from the first request, default_handler generates an (almost always invalid) ETag on the subsequent 304.

the below patch seems to be a better way for mod_include to handle ETag generation (or, rather, supression).


Index: modules/filters/mod_include.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/filters/mod_include.c,v
retrieving revision 1.233
diff -u -r1.233 mod_include.c
--- modules/filters/mod_include.c	3 Feb 2003 17:53:01 -0000	1.233
+++ modules/filters/mod_include.c	24 Apr 2003 17:46:13 -0000
@@ -3338,6 +3338,12 @@
         f->r->no_local_copy = 1;
     }
     
+    /* Don't allow ETag headers to be generated - see RFC2616 - 13.3.4.
+     * We don't know if we are going to be including a file or executing
+     * a program - in either case a strong ETag header will likely be invalid.
+     */
+    apr_table_setn(f->r->notes, "no-etag", 1);
+
     return OK;
 }
 
@@ -3407,14 +3413,13 @@
      */
     apr_table_unset(f->r->headers_out, "Content-Length");
 
-    /* Always unset the ETag/Last-Modified fields - see RFC2616 - 13.3.4.
+    /* Always unset the Last-Modified fields - see RFC2616 - 13.3.4.
      * We don't know if we are going to be including a file or executing
      * a program which may change the Last-Modified header or make the 
      * content completely dynamic.  Therefore, we can't support these
      * headers.
      * Exception: XBitHack full means we *should* set the Last-Modified field.
      */
-    apr_table_unset(f->r->headers_out, "ETag");
 
     /* Assure the platform supports Group protections */
     if ((*conf->xbithack == xbithack_full)
Comment 1 André Malo 2003-11-02 22:14:48 UTC
Well, fixed in 2.1 and proposed for backport.
I've slightly modified your patch and used

apr_table_setn(f->r->notes, "no-etag", "");

because the "1" pointer is not really portable and may cause bus errors on weird
systems.

Thanks.