You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ha...@apache.org on 2020/01/06 14:08:39 UTC

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

Author: hartmannathan
Date: Mon Jan  6 14:08:39 2020
New Revision: 1872381

URL: http://svn.apache.org/viewvc?rev=1872381&view=rev
Log:
Rework r1866425 ('Last-Modified' header).  Do not use pointer comparison
and 'special value' for APR_TIME_T.

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

* subversion/mod_dav_svn/repos.c
  (parse_uri,
   get_parentpath_resource): Set IS_PUBLIC_URI to TRUE for 'public' URIs (not
   under '/!svn/')
  (get_last_modified): Delete.
  (set_headers): Rework of 'Last-Modified' related code.

See dev@ email thread "[Patch] Rework of r1866425 ('Last-Modified' header)"
started 2019/12/10, archived at several places, including:
https://lists.apache.org/thread.html/aff4ab41e87c997fbc90fc79e3240ffcda10fe7f09a1e31bec4af797%40%3Cdev.subversion.apache.org%3E

Patch by: sergey.raevskiy{_AT_}visualsvn.com

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=1872381&r1=1872380&r2=1872381&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/trunk/subversion/mod_dav_svn/dav_svn.h Mon Jan  6 14:08:39 2020
@@ -303,6 +303,9 @@ struct dav_resource_private {
   /* whether this resource parameters are fixed and won't change
      between requests. */
   svn_boolean_t idempotent;
+
+  /* resource is accessed by 'public' uri (not under "!svn") */
+  svn_boolean_t is_public_uri;
 };
 
 

Modified: subversion/trunk/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/repos.c?rev=1872381&r1=1872380&r2=1872381&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/repos.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/repos.c Mon Jan  6 14:08:39 2020
@@ -714,6 +714,8 @@ parse_uri(dav_resource_combined *comb,
       && ((ch = uri[len2]) == '/' || ch == '\0')
       && memcmp(uri, special_uri, len2) == 0)
     {
+      comb->priv.is_public_uri = FALSE;
+
       if (ch == '\0')
         {
           /* URI was "/root/!svn". It exists, but has restricted usage. */
@@ -789,6 +791,8 @@ parse_uri(dav_resource_combined *comb,
       /* The location of these resources corresponds directly to the URI,
          and we keep the leading "/". */
       comb->priv.repos_path = comb->priv.uri_path->data;
+
+      comb->priv.is_public_uri = TRUE;
     }
 
   return FALSE;
@@ -1596,6 +1600,7 @@ get_parentpath_resource(request_rec *r,
   comb->priv.r = r;
   comb->priv.repos_path = "Collection of Repositories";
   comb->priv.root = *droot;
+  comb->priv.is_public_uri = TRUE;
   droot->rev = SVN_INVALID_REVNUM;
 
   comb->priv.repos = repos;
@@ -3139,50 +3144,6 @@ seek_stream(dav_stream *stream, apr_off_
        && resource->baselined))
 
 
-/* Return the last modification time of RESOURCE, or -1 if the DAV
-   resource type is not handled, or if an error occurs.  Temporary
-   allocations are made from RESOURCE->POOL. */
-static apr_time_t
-get_last_modified(const dav_resource *resource)
-{
-  apr_time_t last_modified;
-  svn_error_t *serr;
-  svn_revnum_t created_rev;
-  svn_string_t *date_time;
-
-  if (RESOURCE_LACKS_ETAG_POTENTIAL(resource))
-    return -1;
-
-  if ((serr = svn_fs_node_created_rev(&created_rev, resource->info->root.root,
-                                      resource->info->repos_path,
-                                      resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  if ((serr = svn_fs_revision_prop2(&date_time, resource->info->repos->fs,
-                                    created_rev, SVN_PROP_REVISION_DATE,
-                                    TRUE, resource->pool, resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  if (date_time == NULL || date_time->data == NULL)
-    return -1;
-
-  if ((serr = svn_time_from_cstring(&last_modified, date_time->data,
-                                    resource->pool)))
-    {
-      svn_error_clear(serr);
-      return -1;
-    }
-
-  return last_modified;
-}
-
-
 const char *
 dav_svn__getetag(const dav_resource *resource, apr_pool_t *pool)
 {
@@ -3264,20 +3225,42 @@ set_headers(request_rec *r, const dav_re
     return NULL;
 
   if ((resource->type == DAV_RESOURCE_TYPE_REGULAR) 
-      && (resource->info->repos_path == resource->info->uri_path->data))
+      && resource->info->is_public_uri)
     {
       /* Include Last-Modified header for 'external' GET or HEAD requests
          (i.e. requests to URI's not under /!svn), to support usage of an
          SVN server as a file server, where the client needs timestamps
          for instance to use as "last modification time" of files on disk. */
-      const apr_time_t last_modified = get_last_modified(resource);
-      if (last_modified != -1)
+
+      svn_revnum_t created_rev;
+      svn_string_t *date_str = NULL;
+
+      serr = svn_fs_node_created_rev(&created_rev, resource->info->root.root,
+                                     resource->info->repos_path,
+                                     resource->pool);
+
+      if (serr == NULL)
         {
-          /* Note the modification time for the requested resource, and
-             include the Last-Modified header in the response. */
-          ap_update_mtime(r, last_modified);
-          ap_set_last_modified(r);
-        }  
+          serr = svn_fs_revision_prop2(&date_str, resource->info->repos->fs,
+                                       created_rev, SVN_PROP_REVISION_DATE,
+                                       TRUE, resource->pool, resource->pool);
+        }
+
+      if ((serr == NULL) && date_str && date_str->data)
+        {
+          apr_time_t mtime;
+          serr = svn_time_from_cstring(&mtime, date_str->data, resource->pool);
+
+          if (serr == NULL)
+            {
+              /* Note the modification time for the requested resource, and
+                 include the Last-Modified header in the response. */
+              ap_update_mtime(r, mtime);
+              ap_set_last_modified(r);
+            }
+        }
+
+      svn_error_clear(serr);
     }
 
   /* generate our etag and place it into the output */