You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/10/10 20:47:00 UTC

svn commit: r1181131 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_ra_serf/ra_serf.h subversion/libsvn_ra_serf/serf.c

Author: hwright
Date: Mon Oct 10 18:47:00 2011
New Revision: 1181131

URL: http://svn.apache.org/viewvc?rev=1181131&view=rev
Log:
Merge r1154278, r1154379, r1154382 from trunk:

 * r1154278, r1154379, r1154382
   Make 'svn ls' capable of listing Subversion 1.0-1.3 repositories using
   ra_serf.
   Justification:
     We promised not to break backwards compatibility and it is not nice
     that serf doesn't want to list the neon repository.
     (Check svn ls http://svn.webdav.org/repos/projects/neon/)
   Notes:
     r1154278 is a quick hack to detect old servers and to at least return
              some information.
     r1154379 is the real fix: fallback to a more compatible request.
     r1154382 makes sure the right result is used directly after falling
              back from svn_ra_serf__get_dir.
              (Most likely the problem is detected earlier than this function)
   Votes:
     +1: rhuijben, cmpilato, jerenkrantz

Modified:
    subversion/branches/1.7.x/   (props changed)
    subversion/branches/1.7.x/STATUS
    subversion/branches/1.7.x/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/1.7.x/subversion/libsvn_ra_serf/serf.c

Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct 10 18:47:00 2011
@@ -64,4 +64,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147299,1147309,1147882,1148071,1148083,1148094,1148131,1148374,1148424,1148566,1148588,1148853,1148877,1148882,1148936,1149105,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149627,1149675,1149701,1149713,1150242,1150254,1150260-1150261,1150266,1150302,1150327,1150368,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151906,1151911,1152129,1152140,1152189-1152190,1152267,1152282,1152286,1152726,1152809,1153138,1153141,1153416,1153799,1153807,1153968,1154009,1154023,1154115,1154119,1154121,1154144,1154155,1154159,1154165,1154215,1154225,1154273,1154461,1154717-1154718,1154733,1154908,1154982,1155015,1155044,1155124,1155131,1155160,1155313,1155334,1155391,1155404,1156085,1156098,1156216,1156218,1156312,1156527,1156717,1156721,1156750,1156827,1156838,1157416,115
 8187,1158193-1158194,1158196,1158201,1158207,1158209-1158210,1158217,1158285,1158288,1158303,1158309,1158407,1158419,1158421,1158436,1158455,1158616-1158617,1158634,1158854,1158875,1158886,1158893,1158896,1158919,1158924,1158963,1159093,1159098,1159101,1159132,1159136,1159148,1159230,1159275,1159400,1159686,1159760,1159772,1160605,1160671,1160682,1160704-1160705,1160756,1161063,1161080,1161185,1161210,1161683,1161721,1162024,1162033,1162201,1162516,1162880,1162974,1162995,1163557,1163792,1163953,1164027,1164386,1164517,1164535,1164554,1164580,1164645,1164760,1164765,1166500,1166555,1166678,1167062,1167173,1167209,1167269,1167503,1167659,1169524,1169531,1169650,1171708,1173111,1173425,1173639,1174051,1174060,1174652,1174797,1175888,1177001
+/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147299,1147309,1147882,1148071,1148083,1148094,1148131,1148374,1148424,1148566,1148588,1148853,1148877,1148882,1148936,1149105,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149627,1149675,1149701,1149713,1150242,1150254,1150260-1150261,1150266,1150302,1150327,1150368,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151906,1151911,1152129,1152140,1152189-1152190,1152267,1152282,1152286,1152726,1152809,1153138,1153141,1153416,1153799,1153807,1153968,1154009,1154023,1154115,1154119,1154121,1154144,1154155,1154159,1154165,1154215,1154225,1154273,1154278,1154379,1154382,1154461,1154717-1154718,1154733,1154908,1154982,1155015,1155044,1155124,1155131,1155160,1155313,1155334,1155391,1155404,1156085,1156098,1156216,1156218,1156312,1156527,1156717,1156721,1156750,115
 6827,1156838,1157416,1158187,1158193-1158194,1158196,1158201,1158207,1158209-1158210,1158217,1158285,1158288,1158303,1158309,1158407,1158419,1158421,1158436,1158455,1158616-1158617,1158634,1158854,1158875,1158886,1158893,1158896,1158919,1158924,1158963,1159093,1159098,1159101,1159132,1159136,1159148,1159230,1159275,1159400,1159686,1159760,1159772,1160605,1160671,1160682,1160704-1160705,1160756,1161063,1161080,1161185,1161210,1161683,1161721,1162024,1162033,1162201,1162516,1162880,1162974,1162995,1163557,1163792,1163953,1164027,1164386,1164517,1164535,1164554,1164580,1164645,1164760,1164765,1166500,1166555,1166678,1167062,1167173,1167209,1167269,1167503,1167659,1169524,1169531,1169650,1171708,1173111,1173425,1173639,1174051,1174060,1174652,1174797,1175888,1177001

Modified: subversion/branches/1.7.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1181131&r1=1181130&r2=1181131&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Mon Oct 10 18:47:00 2011
@@ -141,23 +141,6 @@ Veto-blocked changes:
 Approved changes:
 =================
 
- * r1154278, r1154379, r1154382
-   Make 'svn ls' capable of listing Subversion 1.0-1.3 repositories using
-   ra_serf.
-   Justification:
-     We promised not to break backwards compatibility and it is not nice
-     that serf doesn't want to list the neon repository.
-     (Check svn ls http://svn.webdav.org/repos/projects/neon/)
-   Notes:
-     r1154278 is a quick hack to detect old servers and to at least return
-              some information.
-     r1154379 is the real fix: fallback to a more compatible request.
-     r1154382 makes sure the right result is used directly after falling
-              back from svn_ra_serf__get_dir.
-              (Most likely the problem is detected earlier than this function)
-   Votes:
-     +1: rhuijben, cmpilato, jerenkrantz
-
  * r1179767
    Prefix SASL error messages with a prefix that identifies them as such.
    Justification:

Modified: subversion/branches/1.7.x/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_ra_serf/ra_serf.h?rev=1181131&r1=1181130&r2=1181131&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/1.7.x/subversion/libsvn_ra_serf/ra_serf.h Mon Oct 10 18:47:00 2011
@@ -179,6 +179,9 @@ struct svn_ra_serf__session_t {
   /* Connection timeout value */
   long timeout;
 
+  /* HTTPv1 flags */
+  svn_tristate_t supports_deadprop_count;
+
   /*** HTTP v2 protocol stuff. ***
    *
    * We assume that if mod_dav_svn sends one of the special v2 OPTIONs

Modified: subversion/branches/1.7.x/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_ra_serf/serf.c?rev=1181131&r1=1181130&r2=1181131&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_ra_serf/serf.c Mon Oct 10 18:47:00 2011
@@ -39,10 +39,11 @@
 #include "../libsvn_ra/ra_loader.h"
 #include "svn_config.h"
 #include "svn_delta.h"
-#include "svn_version.h"
 #include "svn_dirent_uri.h"
+#include "svn_hash.h"
 #include "svn_path.h"
 #include "svn_time.h"
+#include "svn_version.h"
 
 #include "private/svn_dav_protocol.h"
 #include "private/svn_dep_compat.h"
@@ -386,6 +387,8 @@ svn_ra_serf__open(svn_ra_session_t *sess
   serf_sess->session_url_str = apr_pstrdup(serf_sess->pool, repos_URL);
   serf_sess->using_ssl = (svn_cstring_casecmp(url.scheme, "https") == 0);
 
+  serf_sess->supports_deadprop_count = svn_tristate_unknown;
+
   serf_sess->capabilities = apr_hash_make(serf_sess->pool);
 
   SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
@@ -660,6 +663,8 @@ struct dirent_walker_baton_t {
   /* Update the fields in this entry.  */
   svn_dirent_t *entry;
 
+  svn_tristate_t *supports_deadprop_count;
+
   /* If allocations are necessary, then use this pool.  */
   apr_pool_t *result_pool;
 };
@@ -685,9 +690,16 @@ dirent_walker(void *baton,
     {
       if(strcmp(name, "deadprop-count") == 0)
         {
-          apr_int64_t deadprop_count;
-          SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
-          dwb->entry->has_props = deadprop_count > 0;
+          if (*val->data)
+            {
+              apr_int64_t deadprop_count;
+              SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
+              dwb->entry->has_props = deadprop_count > 0;
+              if (dwb->supports_deadprop_count)
+                *dwb->supports_deadprop_count = svn_tristate_true;
+            }
+          else if (dwb->supports_deadprop_count)
+            *dwb->supports_deadprop_count = svn_tristate_false;
         }
     }
   else if (strcmp(ns, "DAV:") == 0)
@@ -734,6 +746,8 @@ struct path_dirent_visitor_t {
   apr_hash_t *full_paths;
   apr_hash_t *base_paths;
   const char *orig_path;
+  svn_tristate_t supports_deadprop_count;
+  apr_pool_t *result_pool;
 };
 
 static svn_error_t *
@@ -771,57 +785,74 @@ path_dirent_walker(void *baton,
     }
 
   dwb.entry = entry;
-  dwb.result_pool = pool;  /* ### fix this!  */
+  dwb.supports_deadprop_count = &dirents->supports_deadprop_count;
+  dwb.result_pool = dirents->result_pool;
   return svn_error_trace(dirent_walker(&dwb, ns, name, val, pool));
 }
 
 static const svn_ra_serf__dav_props_t *
-get_dirent_props(apr_uint32_t dirent_fields, apr_pool_t *pool)
+get_dirent_props(apr_uint32_t dirent_fields,
+                 svn_ra_serf__session_t *session,
+                 apr_pool_t *pool)
 {
   svn_ra_serf__dav_props_t *prop;
   apr_array_header_t *props = apr_array_make
     (pool, 7, sizeof(svn_ra_serf__dav_props_t));
 
-  if (dirent_fields & SVN_DIRENT_KIND)
+  if (session->supports_deadprop_count != svn_tristate_false
+      || ! (dirent_fields & SVN_DIRENT_HAS_PROPS))
     {
-      prop = apr_array_push(props);
-      prop->namespace = "DAV:";
-      prop->name = "resourcetype";
-    }
+      if (dirent_fields & SVN_DIRENT_KIND)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = "resourcetype";
+        }
 
-  if (dirent_fields & SVN_DIRENT_SIZE)
-    {
-      prop = apr_array_push(props);
-      prop->namespace = "DAV:";
-      prop->name = "getcontentlength";
-    }
+      if (dirent_fields & SVN_DIRENT_SIZE)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = "getcontentlength";
+        }
 
-  if (dirent_fields & SVN_DIRENT_HAS_PROPS)
-    {
-      prop = apr_array_push(props);
-      prop->namespace = SVN_DAV_PROP_NS_DAV;
-      prop->name = "deadprop-count";
-    }
+      if (dirent_fields & SVN_DIRENT_HAS_PROPS)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = SVN_DAV_PROP_NS_DAV;
+          prop->name = "deadprop-count";
+        }
 
-  if (dirent_fields & SVN_DIRENT_CREATED_REV)
-    {
-      svn_ra_serf__dav_props_t *p = apr_array_push(props);
-      p->namespace = "DAV:";
-      p->name = SVN_DAV__VERSION_NAME;
-    }
+      if (dirent_fields & SVN_DIRENT_CREATED_REV)
+        {
+          svn_ra_serf__dav_props_t *p = apr_array_push(props);
+          p->namespace = "DAV:";
+          p->name = SVN_DAV__VERSION_NAME;
+        }
 
-  if (dirent_fields & SVN_DIRENT_TIME)
-    {
-      prop = apr_array_push(props);
-      prop->namespace = "DAV:";
-      prop->name = SVN_DAV__CREATIONDATE;
-    }
+      if (dirent_fields & SVN_DIRENT_TIME)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = SVN_DAV__CREATIONDATE;
+        }
 
-  if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+      if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = "creator-displayname";
+        }
+    }
+  else
     {
+      /* We found an old subversion server that can't handle
+         the deadprop-count property in the way we expect.
+
+         The neon behavior is to retrieve all properties in this case */
       prop = apr_array_push(props);
       prop->namespace = "DAV:";
-      prop->name = "creator-displayname";
+      prop->name = "allprop";
     }
 
   prop = apr_array_push(props);
@@ -845,10 +876,12 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
   svn_revnum_t fetched_rev;
   svn_error_t *err;
   struct dirent_walker_baton_t dwb;
+  svn_tristate_t deadprop_count = svn_tristate_unknown;
 
   err = fetch_path_props(&prop_ctx, &props, &path, &fetched_rev,
                          session, rel_path, revision,
-                         get_dirent_props(SVN_DIRENT_ALL, pool), pool);
+                         get_dirent_props(SVN_DIRENT_ALL, session, pool),
+                         pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
@@ -862,11 +895,33 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
     }
 
   dwb.entry = apr_pcalloc(pool, sizeof(*dwb.entry));
-  dwb.result_pool = pool;  /* ### fix this  */
+  dwb.supports_deadprop_count = &deadprop_count;
+  dwb.result_pool = pool;
   SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev,
                                       dirent_walker, &dwb,
                                       pool));
 
+  if (deadprop_count == svn_tristate_false
+      && session->supports_deadprop_count == svn_tristate_unknown
+      && !dwb.entry->has_props)
+    {
+      /* We have to requery as the server didn't give us the right
+         information */
+      session->supports_deadprop_count = svn_tristate_false;
+
+      SVN_ERR(fetch_path_props(&prop_ctx, &props, &path, &fetched_rev,
+                               session, rel_path, fetched_rev,
+                               get_dirent_props(SVN_DIRENT_ALL, session, pool),
+                               pool));
+
+      SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev,
+                                      dirent_walker, &dwb,
+                                      pool));
+    }
+
+  if (deadprop_count != svn_tristate_unknown)
+    session->supports_deadprop_count = deadprop_count;
+
   *dirent = dwb.entry;
 
   return SVN_NO_ERROR;
@@ -943,7 +998,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
                                           path, revision, "1",
                                           get_dirent_props(dirent_fields,
-                                                           pool),
+                                                           session, pool),
                                           pool, pool));
 
       /* Check if the path is really a directory. */
@@ -956,11 +1011,38 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       dirent_walk.full_paths = apr_hash_make(pool);
       dirent_walk.base_paths = apr_hash_make(pool);
       dirent_walk.orig_path = svn_urlpath__canonicalize(path, pool);
+      dirent_walk.supports_deadprop_count = svn_tristate_unknown;
+      dirent_walk.result_pool = pool;
 
       SVN_ERR(svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
                                           &dirent_walk, pool));
 
+      if (dirent_walk.supports_deadprop_count == svn_tristate_false
+          && session->supports_deadprop_count == svn_tristate_unknown
+          && dirent_fields & SVN_DIRENT_HAS_PROPS)
+        {
+          /* We have to requery as the server didn't give us the right
+             information */
+          session->supports_deadprop_count = svn_tristate_false;
+          SVN_ERR(svn_ra_serf__retrieve_props(&props, session,
+                                              session->conns[0],
+                                              path, revision, "1",
+                                              get_dirent_props(dirent_fields,
+                                                               session, pool),
+                                              pool, pool));
+
+          SVN_ERR(svn_hash__clear(dirent_walk.full_paths, pool));
+          SVN_ERR(svn_hash__clear(dirent_walk.base_paths, pool));
+
+          SVN_ERR(svn_ra_serf__walk_all_paths(props, revision,
+                                              path_dirent_walker,
+                                              &dirent_walk, pool));
+        }
+
       *dirents = dirent_walk.base_paths;
+
+      if (dirent_walk.supports_deadprop_count != svn_tristate_unknown)
+        session->supports_deadprop_count = dirent_walk.supports_deadprop_count;
     }
 
   /* If we're asked for the directory properties, fetch them too. */