Author: philip
Date: Mon May 24 22:11:04 2010
New Revision: 947833

URL: http://svn.apache.org/viewvc?rev=947833&view=rev
Log:
Fix issue 3085: mod_dav_svn runs pre-revprop-change hook twice.

* subversion/mod_dav_svn/dav_svn.h
  (struct dav_resource_private): Add revprop_error member.

* subversion/mod_dav_svn/deadprops.c
  (struct dav_deadprop_rollback): Now just a dummy.
  (save_value): Cache any revprop change error.
  (db_get_rollback): Allocate dummy struct.
  (db_apply_rollback): Just return any cached error.

Modified:
    subversion/trunk/subversion/mod_dav_svn/dav_svn.h
    subversion/trunk/subversion/mod_dav_svn/deadprops.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=947833&r1=947832&r2=947833&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/trunk/subversion/mod_dav_svn/dav_svn.h Mon May 24 22:11:04 2010
@@ -271,6 +271,9 @@ struct dav_resource_private {
      interface (ie: /path/to/item?p=PEGREV]? */
   svn_boolean_t pegged;
 
+  /* Cache any revprop change error */
+  svn_error_t *revprop_error;
+
   /* Pool to allocate temporary data from */
   apr_pool_t *pool;
 };

Modified: subversion/trunk/subversion/mod_dav_svn/deadprops.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/deadprops.c?rev=947833&r1=947832&r2=947833&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/deadprops.c Mon May 24 22:11:04 2010
@@ -54,8 +54,7 @@ struct dav_db {
 
 
 struct dav_deadprop_rollback {
-  dav_prop_name name;
-  svn_string_t value;
+  int dummy;
 };
 
 
@@ -219,6 +218,14 @@ save_value(dav_db *db, const dav_prop_na
                                                db->authz_read_baton,
                                                resource->pool);
 
+          /* mod_dav doesn't handle the returned error very well, it
+             generates its own generic error that will be returned to
+             the client.  Cache the detailed error here so that it can
+             be returned a second time when the rollback mechanism
+             triggers. */
+          if (serr)
+            resource->info->revprop_error = svn_error_dup(serr);
+
           /* Tell the logging subsystem about the revprop change. */
           dav_svn__operational_log(resource->info,
                                    svn_log__change_rev_prop(
@@ -661,19 +668,14 @@ db_get_rollback(dav_db *db,
                 const dav_prop_name *name,
                 dav_deadprop_rollback **prollback)
 {
-  dav_error *err;
-  dav_deadprop_rollback *ddp;
-  svn_string_t *propval;
-
-  if ((err = get_value(db, name, &propval)) != NULL)
-    return err;
+  /* This gets called by mod_dav in preparation for a revprop change.
+     mod_dav_svn doesn't need to make any changes during rollback, but
+     we want the rollback mechanism to trigger.  Making changes in
+     response to post-revprop-change hook errors would be positively
+     wrong. */
 
-  ddp = apr_palloc(db->p, sizeof(*ddp));
-  ddp->name = *name;
-  ddp->value.data = propval ? propval->data : NULL;
-  ddp->value.len = propval ? propval->len : 0;
+  *prollback = apr_palloc(db->p, sizeof(dav_deadprop_rollback));
 
-  *prollback = ddp;
   return NULL;
 }
 
@@ -681,12 +683,20 @@ db_get_rollback(dav_db *db,
 static dav_error *
 db_apply_rollback(dav_db *db, dav_deadprop_rollback *rollback)
 {
-  if (rollback->value.data == NULL)
-    {
-      return db_remove(db, &rollback->name);
-    }
+  dav_error *derr;
+
+  if (! db->resource->info->revprop_error)
+    return NULL;
+  
+  /* Returning the original revprop change error here will cause this
+     detailed error to get returned to the client in preference to the
+     more generic error created by mod_dav. */
+  derr = dav_svn__convert_err(db->resource->info->revprop_error,
+                              HTTP_INTERNAL_SERVER_ERROR, NULL,
+                              db->resource->pool);
+  db->resource->info->revprop_error = NULL;
 
-  return save_value(db, &rollback->name, &rollback->value);
+  return derr;
 }
 
 


Reply via email to