Philip Martin <phi...@codematters.co.uk> writes:

> In the past we supported different versions on the master and slave and
> we introduced the SVNMasterVersion directive to configure it.
> Unfortunately that information is not immediately available in
> get_vsn_options() where the server advertises some commit features.  If
> I simply remove the SVN_DAV_NS_DAV_SVN_SVNDIFF2 header from
> get_vsn_options() then I can commit.
>
> I'm not sure how we fix this.  Do we delay the svndiff2 negotiation
> until later in the commit?  Do we abandon mixed master/slave versions?

I think that we might be able to selectively stop advertising the new-
in-1.10 capabilities based on the SVNMasterVersion value, similarly to
how we handle SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS.

Perhaps, we could do something along the lines of the attached patch?


Thanks,
Evgeny Kotkov
Index: subversion/mod_dav_svn/dav_svn.h
===================================================================
--- subversion/mod_dav_svn/dav_svn.h    (revision 1820731)
+++ subversion/mod_dav_svn/dav_svn.h    (working copy)
@@ -359,12 +359,24 @@ svn_boolean_t dav_svn__get_list_parentpath_flag(re
    master server version (if provided via SVNMasterVersion).  */
 svn_boolean_t dav_svn__check_httpv2_support(request_rec *r);
 
-/* For the repository referred to by this request, should ephemeral
-   txnprop support be advertised?  */
-svn_boolean_t dav_svn__check_ephemeral_txnprops_support(request_rec *r);
+typedef enum dav_svn__commit_capability_t
+{
+  dav_svn__capability_ephemeral_txnprops,
+  dav_svn__capability_svndiff1,
+  dav_svn__capability_svndiff2,
+  dav_svn__capability_put_result_checksum
+} dav_svn__commit_capability_t;
 
+/* For the repository referred to by this request, is the specified
+   commit-related capability supported?  Note that this also takes into
+   account the support level expected of based on the specified
+   master server version (if provided via SVNMasterVersion).  */
+svn_boolean_t
+dav_svn__check_commit_capability(request_rec *r,
+                                 dav_svn__commit_capability_t capability);
 
 
+
 /* SPECIAL URI
 
    SVN needs to create many types of "pseudo resources" -- resources
Index: subversion/mod_dav_svn/mod_dav_svn.c
===================================================================
--- subversion/mod_dav_svn/mod_dav_svn.c        (revision 1820731)
+++ subversion/mod_dav_svn/mod_dav_svn.c        (working copy)
@@ -924,17 +924,30 @@ dav_svn__check_httpv2_support(request_rec *r)
 
 
 svn_boolean_t
-dav_svn__check_ephemeral_txnprops_support(request_rec *r)
+dav_svn__check_commit_capability(request_rec *r,
+                                 dav_svn__commit_capability_t capability)
 {
   svn_version_t *version = dav_svn__get_master_version(r);
 
-  /* We know this server supports ephemeral txnprops.  But if we're
-     proxying requests to a master server, we need to see if it
-     supports them, too.  */
-  if (version && (! svn_version__at_least(version, 1, 8, 0)))
-    return FALSE;
+  /* Unless we are proxying requests to a master server with a declared
+     version number, there is no need to dumb ourselves down. */
+  if (!version)
+    return TRUE;
 
-  return TRUE;
+  /* We _are_ proxying requests to another master server with a declared
+     version number.  See if we need to selectively disable some of the
+     capabilities that it doesn't support. */
+  switch (capability)
+    {
+      case dav_svn__capability_ephemeral_txnprops:
+        return svn_version__at_least(version, 1, 8, 0);
+      case dav_svn__capability_svndiff1:
+      case dav_svn__capability_svndiff2:
+      case dav_svn__capability_put_result_checksum:
+        return svn_version__at_least(version, 1, 10, 0);
+      default:
+        SVN_ERR_MALFUNCTION_NO_RETURN();
+    }
 }
 
 
Index: subversion/mod_dav_svn/version.c
===================================================================
--- subversion/mod_dav_svn/version.c    (revision 1820731)
+++ subversion/mod_dav_svn/version.c    (working copy)
@@ -152,9 +152,6 @@ get_vsn_options(apr_pool_t *p, apr_text_header *ph
   apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INHERITED_PROPS);
   apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INLINE_PROPS);
   apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_REVERSE_FILE_REVS);
-  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_SVNDIFF1);
-  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_SVNDIFF2);
-  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_PUT_RESULT_CHECKSUM);
   apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_LIST);
   /* Mergeinfo is a special case: here we merely say that the server
    * knows how to handle mergeinfo -- whether the repository does too
@@ -210,12 +207,29 @@ get_option(const dav_resource *resource,
                   "</D:activity-collection-set>");
 
   /* If we're allowed (by configuration) to do so, advertise support
-     for ephemeral transaction properties. */
-  if (dav_svn__check_ephemeral_txnprops_support(r))
+     for various commit-related capabilities. */
+  if (dav_svn__check_commit_capability(r,
+                                       dav_svn__capability_ephemeral_txnprops))
     {
       apr_table_addn(r->headers_out, "DAV",
                      SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS);
     }
+  if (dav_svn__check_commit_capability(r, dav_svn__capability_svndiff1))
+    {
+      apr_table_addn(r->headers_out, "DAV",
+                     SVN_DAV_NS_DAV_SVN_SVNDIFF1);
+    }
+  if (dav_svn__check_commit_capability(r, dav_svn__capability_svndiff2))
+    {
+      apr_table_addn(r->headers_out, "DAV",
+                     SVN_DAV_NS_DAV_SVN_SVNDIFF2);
+    }
+  if (dav_svn__check_commit_capability(r,
+                                       
dav_svn__capability_put_result_checksum))
+    {
+      apr_table_addn(r->headers_out, "DAV",
+                     SVN_DAV_NS_DAV_SVN_PUT_RESULT_CHECKSUM);
+    }
 
   if (resource->info->repos->fs)
     {

Reply via email to