You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rodent of Unusual Size <Ke...@Golux.Com> on 2001/11/27 22:04:42 UTC

Re: [RFC] InodeEtag option

'Way back in May 2001, Phil Dietz proposed adding the ability
to control whether the file inode should be included in the
formulation of a document's ETag.  He originally proposed it
as an extension to the Options directive, but said he'd re-do
it as its own directive.  I can't find any record of that
actually happening, though, so here's a patch to do it.

Reason: Systems that fan out their content onto multiple back-end
servers with identical filesystem contents would nevertheless
produce cache-hammering responses because the same content would
have a different inode on each back-end server.  Taking the inode
out of the equation allows their content to be cached as identical.
The reduced ETag is based on only the last-modified time and the
file size, rather than those plus the inode.

The directive added by this patch is a FLAG UseInodesInETags.
It can be used wherever FileInfo directives can appear.  The
core per-dir config structure is extended by an int at the end,
used only by http_core.c and http_protocol.c.

If no-one has any complaints about this in the next couple of days,
I'll commit to 1.3 and then bring it forward to 2.0.  The concept
has already received the necessary +1s, so any issues *should*
only relate to implementation or names..

Index: src/CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1742
diff -u -r1.1742 CHANGES
--- src/CHANGES	2001/11/26 17:26:53	1.1742
+++ src/CHANGES	2001/11/27 20:46:29
@@ -1,4 +1,13 @@
 Changes with Apache 1.3.23
+  *) Add UseInodesInETags directive to control whether a file's
+     inode number can be used when constructing an ETag.  We
+     always have in the past, but it breaks caching for systems
+     with content fan-out across multiple back-end servers.
+     'UseInodesinETags Off' will result in only the last-modified
+     time and file size being used, which should allow such
+     fanned-out files to be cached.
+     [Ken Coar, from a patch by Phil Dietz]
+
   *) Win32: Do not allow threads to continue handling keepalive
      requests after a shutdown or restart has ben signaled.
      [Bill Stoddard]
Index: src/include/http_core.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/http_core.h,v
retrieving revision 1.64
diff -u -r1.64 http_core.h
--- src/include/http_core.h	2001/03/09 10:10:20	1.64
+++ src/include/http_core.h	2001/11/27 20:46:29
@@ -309,6 +309,12 @@
 #endif
 #endif /* CHARSET_EBCDIC */
 
+    /*
+     * Should file inodes be included in ETag generation?  Doing so
+     * can defeat caching of back-end fanned-out content.
+     */
+    int inode_etag;
+
 } core_dir_config;
 
 /* Per-server core configuration */
Index: src/main/http_core.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_core.c,v
retrieving revision 1.299
diff -u -r1.299 http_core.c
--- src/main/http_core.c	2001/11/16 01:32:20	1.299
+++ src/main/http_core.c	2001/11/27 20:46:29
@@ -170,6 +170,11 @@
 #endif
 #endif /* CHARSET_EBCDIC */
 
+    /*
+     * Flag for use of inodes in ETags.
+     */
+    conf->inode_etag = OPT_UNSET;
+
     return (void *)conf;
 }
 
@@ -319,6 +324,13 @@
 #endif
 #endif /* CHARSET_EBCDIC */
 
+    /*
+     * Use the closer setting if it was explicit.
+     */
+    conf->inode_etag = (new->inode_etag == OPT_UNSET)
+        ? base->inode_etag
+        : new->inode_etag;
+
     return (void*)conf;
 }
 
@@ -2985,6 +2997,18 @@
 #endif
 #endif /* CHARSET_EBCDIC */
 
+/*
+ * Note whether file inodes may be used when forming ETag values.
+ */
+static const char *set_inode_etag(cmd_parms *cmd, void *mconfig, int bool)
+{
+    core_dir_config *cfg;
+
+    cfg = (core_dir_config *) mconfig;
+    cfg->inode_etag = bool;
+    return NULL;
+}
+
 /* Note --- ErrorDocument will now work from .htaccess files.  
  * The AllowOverride of Fileinfo allows webmasters to turn it off
  */
@@ -3276,6 +3300,8 @@
 #endif
 #endif /* CHARSET_EBCDIC */
 
+{ "UseInodesInETags", set_inode_etag, NULL, OR_FILEINFO, FLAG,
+  "Use file number (inode) when generating ETag values"},
 { NULL }
 };
 
Index: src/main/http_protocol.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.301
diff -u -r1.301 http_protocol.c
--- src/main/http_protocol.c	2001/06/22 12:43:54	1.301
+++ src/main/http_protocol.c	2001/11/27 20:46:29
@@ -649,7 +649,10 @@
 {
     char *etag;
     char *weak;
+    core_dir_config *cfg;
 
+    cfg = (core_dir_config *)ap_get_module_config(r->per_dir_config,
+                                                  &core_module);
     /*
      * Make an ETag header out of various pieces of information. We use
      * the last-modified date and, if we have a real file, the
@@ -666,11 +669,24 @@
     weak = ((r->request_time - r->mtime > 1) && !force_weak) ? "" : "W/";
 
     if (r->finfo.st_mode != 0) {
-        etag = ap_psprintf(r->pool,
-                    "%s\"%lx-%lx-%lx\"", weak,
-                    (unsigned long) r->finfo.st_ino,
-                    (unsigned long) r->finfo.st_size,
-                    (unsigned long) r->mtime);
+        if (cfg->inode_etag != 0) {
+            /*
+             * This picks up both the explicit 'yes, use inodes' and the
+             * 'didn't bother to set it so use backward-compatible behaviour'
+             * settings.
+             */
+            etag = ap_psprintf(r->pool,
+                               "%s\"%lx-%lx-%lx\"", weak,
+                               (unsigned long) r->finfo.st_ino,
+                               (unsigned long) r->finfo.st_size,
+                               (unsigned long) r->mtime);
+        }
+        else {
+            etag = ap_psprintf(r->pool,
+                               "%s\"%lx-%lx\"", weak,
+                               (unsigned long) r->finfo.st_size,
+                               (unsigned long) r->mtime);
+        }
     }
     else {
         etag = ap_psprintf(r->pool, "%s\"%lx\"", weak,

-- 
#ken	P-)}

Ken Coar, Sanagendamgagwedweinini  http://Golux.Com/coar/
Author, developer, opinionist      http://Apache-Server.Com/

"All right everyone!  Step away from the glowing hamburger!"

Re: [RFC] InodeEtag option

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Rodent of Unusual Size wrote:
> 
> The former (omit the ETag field from the response header) will
> require a MMN bump

Well, maybe not -- not if I don't mind polluting ap_send_header_field()
with knowledge about what it means and how to figure it out..
-- 
#ken	P-)}

Ken Coar, Sanagendamgagwedweinini  http://Golux.Com/coar/
Author, developer, opinionist      http://Apache-Server.Com/

"All right everyone!  Step away from the glowing hamburger!"

Re: [RFC] InodeEtag option

Posted by "Roy T. Fielding" <fi...@ebuilt.com>.
On Fri, Nov 30, 2001 at 03:54:39PM -0500, Rodent of Unusual Size wrote:
> "Roy T. Fielding" wrote:
> > 
> > Good idea -- I was trying to keep the most relevant part of the name
> > at the front so that it is easy to find in the documentation, but
> > FileETagValue is better than the alternatives.  Actually, just FileETag
> > (with one option being "none") would be best.
> 
> And how should 'FileETag None' be interpreted?  As no ETag at
> all, or a blank one, or what?  (null), '[W/]""', or something else?

No ETag at all.  I'm not wild about this idea -- I just thought of it
for completeness sake.

> The former (omit the ETag field from the response header) will
> require a MMN bump, even though it seems to match the keyword
> intent more closely..

It could be done with notes or an env variable, but we could just skip
it for now.  I wasn't thinking of doing it for 1.3.

....Roy


Re: [RFC] InodeEtag option

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
"Roy T. Fielding" wrote:
> 
> Good idea -- I was trying to keep the most relevant part of the name
> at the front so that it is easy to find in the documentation, but
> FileETagValue is better than the alternatives.  Actually, just FileETag
> (with one option being "none") would be best.

And how should 'FileETag None' be interpreted?  As no ETag at
all, or a blank one, or what?  (null), '[W/]""', or something else?
The former (omit the ETag field from the response header) will
require a MMN bump, even though it seems to match the keyword
intent more closely..
-- 
#ken	P-)}

Ken Coar, Sanagendamgagwedweinini  http://Golux.Com/coar/
Author, developer, opinionist      http://Apache-Server.Com/

"All right everyone!  Step away from the glowing hamburger!"

Re: [RFC] InodeEtag option

Posted by "Roy T. Fielding" <fi...@ebuilt.com>.
> Can/will do.  I assume you also want a 'Size' keyword?

Yes, forgot that one.

> Should the directive be renamed to FileETagValue to make it more clear
> that it only applies to file-based documents and has no effect
> on dynamic content?

Good idea -- I was trying to keep the most relevant part of the name
at the front so that it is easy to find in the documentation, but
FileETagValue is better than the alternatives.  Actually, just FileETag
(with one option being "none") would be best.

....Roy


Re: [RFC] InodeEtag option

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
* On 2001-11-27 at 16:24,
  Roy T. Fielding <fi...@ebuilt.com> excited the electrons to say:
> 
> For the sake of future extensibility, I suggest a directive like
> 
>    EtagValue Inode LMDate
> 
> even if it doesn't include more than those two keywords as possible
> values right now.

Can/will do.  I assume you also want a 'Size' keyword?  Should
the directive be renamed to FileETagValue to make it more clear
that it only applies to file-based documents and has no effect
on dynamic content?
-- 
#ken	P-)}

Ken Coar, Sanagendamgagwedweinini  http://Golux.Com/coar/
Author, developer, opinionist      http://Apache-Server.Com/

"All right everyone!  Step away from the glowing hamburger!"

Re: [RFC] InodeEtag option

Posted by "Roy T. Fielding" <fi...@ebuilt.com>.
For the sake of future extensibility, I suggest a directive like

   EtagValue Inode LMDate

even if it doesn't include more than those two keywords as possible
values right now.  All it would do is set a mask of options for what
to include.  I considered an EtagFormat option, but that would slow down
the server for no good reason.

....Roy