You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by iv...@apache.org on 2015/11/21 19:53:14 UTC

svn commit: r1715551 - in /subversion/trunk/subversion/mod_dav_svn: dav_svn.h repos.c

Author: ivan
Date: Sat Nov 21 18:53:14 2015
New Revision: 1715551

URL: http://svn.apache.org/viewvc?rev=1715551&view=rev
Log:
Resolve issue SVN-4514. Add 'Cache-Control: max-age=604800' for all requests
to resource that are 'idempotent', i.e. target is fully specified in URI and
cannot change. For other requests add 'Cache-Control: max-age=0' to disable
browser's heuristic caching.

* subversion/mod_dav_svn/dav_svn.h
  (dav_resource_private): Add new member IDEMPOTENT.

* subversion/mod_dav_svn/repos.c
  (parse_version_uri): Mark resource as 'idempotent'.
  (prep_regular): Mark resource as 'idempotent' only if revision is specified
   in request URI.
  (is_cacheable): New.
  (set_headers): Use is_cacheable() to determine Cache-Control header value.
   Set Cache-Control for non-existing resources too.

Modified:
    subversion/trunk/subversion/mod_dav_svn/dav_svn.h
    subversion/trunk/subversion/mod_dav_svn/repos.c

Modified: subversion/trunk/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/dav_svn.h?rev=1715551&r1=1715550&r2=1715551&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/trunk/subversion/mod_dav_svn/dav_svn.h Sat Nov 21 18:53:14 2015
@@ -296,6 +296,10 @@ struct dav_resource_private {
   /* was keyword substitution requested using our public CGI interface
      (ie: /path/to/item?kw=1)? */
   svn_boolean_t keyword_subst;
+
+  /* whether this resource parameters are fixed and won't change
+     between requests. */
+  svn_boolean_t idempotent;
 };
 
 

Modified: subversion/trunk/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/repos.c?rev=1715551&r1=1715550&r2=1715551&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/repos.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/repos.c Sat Nov 21 18:53:14 2015
@@ -173,6 +173,9 @@ parse_version_uri(dav_resource_combined
   if (comb->priv.root.rev == SVN_INVALID_REVNUM)
     return TRUE;
 
+  /* We have idempotent resource. */
+  comb->priv.idempotent = TRUE;
+
   return FALSE;
 }
 
@@ -447,6 +450,9 @@ parse_revstub_uri(dav_resource_combined
   /* which baseline (revision tree) to access */
   comb->priv.root.rev = revnum;
 
+  /* all resource parameters are fixed in URI. */
+  comb->priv.idempotent = TRUE;
+
   /* NOTE: comb->priv.repos_path == NULL */
   /* NOTE: comb->priv.created_rev == SVN_INVALID_REVNUM */
 
@@ -813,6 +819,12 @@ prep_regular(dav_resource_combined *comb
                                       pool);
         }
     }
+  else
+    {
+      /* Mark resource as 'idempotent' since we have specific revision
+         in URI. */
+      comb->priv.idempotent = TRUE;
+    }
 
   /* get the root of the tree */
   serr = svn_fs_revision_root(&comb->priv.root.root, repos->fs,
@@ -3096,6 +3108,29 @@ getetag_pathetic(const dav_resource *res
   return dav_svn__getetag(resource, resource->pool);
 }
 
+/* Helper for set_headers(). Returns TRUE if request R to RESOURCE can be
+ * cached. Returns FALSe otherwise. */
+static svn_boolean_t
+is_cacheable(request_rec *r, const dav_resource *resource)
+{
+  /* Non-idempotent resource cannot be cached because actual
+     target could change when youngest revision or transacation
+     will change. */
+  if (!resource->info->idempotent)
+    return FALSE;
+
+  /* Our GET requests on collections include dynamic data (the
+     HEAD revision, the build version of Subversion, etc.).
+     Directory content is also subject of authz filtering.*/
+  if (resource->collection)
+    return FALSE;
+
+  if (resource->type == DAV_RESOURCE_TYPE_REGULAR ||
+      resource->type == DAV_RESOURCE_TYPE_VERSION)
+      return TRUE;
+  else
+      return FALSE;
+}
 
 static dav_error *
 set_headers(request_rec *r, const dav_resource *resource)
@@ -3105,6 +3140,13 @@ set_headers(request_rec *r, const dav_re
   const char *mimetype = NULL;
   apr_time_t last_modified;
 
+  /* As version resources don't change, encourage caching. */
+  if (is_cacheable(r, resource))
+    /* Cache resource for one week (specified in seconds). */
+    apr_table_setn(r->headers_out, "Cache-Control", "max-age=604800");
+  else
+    apr_table_setn(r->headers_out, "Cache-Control", "max-age=0");
+
   if (!resource->exists)
     return NULL;
 
@@ -3121,13 +3163,6 @@ set_headers(request_rec *r, const dav_re
   apr_table_setn(r->headers_out, "ETag",
                  dav_svn__getetag(resource, resource->pool));
 
-  /* As version resources don't change, encourage caching. */
-  if ((resource->type == DAV_RESOURCE_TYPE_REGULAR
-       && resource->versioned && !resource->collection)
-      || resource->type == DAV_RESOURCE_TYPE_VERSION)
-    /* Cache resource for one week (specified in seconds). */
-    apr_table_setn(r->headers_out, "Cache-Control", "max-age=604800");
-
   /* we accept byte-ranges */
   apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");