You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2015/01/28 00:27:46 UTC

svn commit: r1655189 [4/9] - in /subversion/branches/svn-auth-x509: ./ build/ build/generator/ subversion/bindings/javahl/native/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_fs_base/ subversion/libsvn_fs_...

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.c Tue Jan 27 23:27:44 2015
@@ -145,18 +145,46 @@ svn_fs_x__path_revprop_generation(svn_fs
   return svn_dirent_join(fs->path, PATH_REVPROP_GENERATION, result_pool);
 }
 
-const char *
-svn_fs_x__path_rev_packed(svn_fs_t *fs, svn_revnum_t rev, const char *kind,
-                          apr_pool_t *pool)
+/* Return the full path of the file FILENAME within revision REV's shard in
+ * FS.  If FILENAME is NULL, return the shard directory directory itself.
+ * REVPROPS indicates the parent of the shard parent folder ("revprops" or
+ * "revs").  PACKED says whether we want the packed shard's name.
+ *
+ * Allocate the result in RESULT_POOL.
+ */static const char*
+construct_shard_sub_path(svn_fs_t *fs,
+                         svn_revnum_t rev,
+                         svn_boolean_t revprops,
+                         svn_boolean_t packed,
+                         const char *filename,
+                         apr_pool_t *result_pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
-  assert(svn_fs_x__is_packed_rev(fs, rev));
+  char buffer[SVN_INT64_BUFFER_SIZE + sizeof(PATH_EXT_PACKED_SHARD)] = { 0 };
+
+  /* Select the appropriate parent path constant. */
+  const char *parent = revprops ? PATH_REVPROPS_DIR : PATH_REVS_DIR;
 
-  return svn_dirent_join_many(pool, fs->path, PATH_REVS_DIR,
-                              apr_psprintf(pool,
-                                           "%ld" PATH_EXT_PACKED_SHARD,
-                                           rev / ffd->max_files_per_dir),
-                              kind, SVN_VA_NULL);
+  /* String containing the shard number. */
+  apr_size_t len = svn__i64toa(buffer, rev / ffd->max_files_per_dir);
+
+  /* Append the suffix.  Limit it to the buffer size (should never hit it). */
+  if (packed)
+    strncpy(buffer + len, PATH_EXT_PACKED_SHARD, sizeof(buffer) - len - 1);
+
+  /* This will also work for NULL FILENAME as well. */
+  return svn_dirent_join_many(result_pool, fs->path, parent, buffer,
+                              filename, SVN_VA_NULL);
+}
+
+const char *
+svn_fs_x__path_rev_packed(svn_fs_t *fs,
+                          svn_revnum_t rev,
+                          const char *kind,
+                          apr_pool_t *result_pool)
+{
+  assert(svn_fs_x__is_packed_rev(fs, rev));
+  return construct_shard_sub_path(fs, rev, FALSE, TRUE, kind, result_pool);
 }
 
 const char *
@@ -164,33 +192,29 @@ svn_fs_x__path_rev_shard(svn_fs_t *fs,
                          svn_revnum_t rev,
                          apr_pool_t *result_pool)
 {
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-
-  char buffer[SVN_INT64_BUFFER_SIZE];
-  svn__i64toa(buffer, rev / ffd->max_files_per_dir);
-
-  return svn_dirent_join_many(result_pool, fs->path, PATH_REVS_DIR, buffer,
-                              SVN_VA_NULL);
+  return construct_shard_sub_path(fs, rev, FALSE, FALSE, NULL, result_pool);
 }
 
 const char *
-svn_fs_x__path_rev(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool)
+svn_fs_x__path_rev(svn_fs_t *fs,
+                   svn_revnum_t rev,
+                   apr_pool_t *result_pool)
 {
-  assert(! svn_fs_x__is_packed_rev(fs, rev));
+  char buffer[SVN_INT64_BUFFER_SIZE];
+  svn__i64toa(buffer, rev);
 
-  return svn_dirent_join(svn_fs_x__path_rev_shard(fs, rev, pool),
-                         apr_psprintf(pool, "%ld", rev),
-                         pool);
+  assert(! svn_fs_x__is_packed_rev(fs, rev));
+  return construct_shard_sub_path(fs, rev, FALSE, FALSE, buffer, result_pool);
 }
 
 const char *
 svn_fs_x__path_rev_absolute(svn_fs_t *fs,
                             svn_revnum_t rev,
-                            apr_pool_t *pool)
+                            apr_pool_t *result_pool)
 {
-  return ! svn_fs_x__is_packed_rev(fs, rev)
-       ? svn_fs_x__path_rev(fs, rev, pool)
-       : svn_fs_x__path_rev_packed(fs, rev, PATH_PACKED, pool);
+  return svn_fs_x__is_packed_rev(fs, rev)
+       ? svn_fs_x__path_rev_packed(fs, rev, PATH_PACKED, result_pool)
+       : svn_fs_x__path_rev(fs, rev, result_pool);
 }
 
 const char *
@@ -198,34 +222,27 @@ svn_fs_x__path_revprops_shard(svn_fs_t *
                               svn_revnum_t rev,
                               apr_pool_t *result_pool)
 {
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-
-  char buffer[SVN_INT64_BUFFER_SIZE];
-  svn__i64toa(buffer, rev / ffd->max_files_per_dir);
-
-  return svn_dirent_join_many(result_pool, fs->path, PATH_REVPROPS_DIR,
-                              buffer, SVN_VA_NULL);
+  return construct_shard_sub_path(fs, rev, TRUE, FALSE, NULL, result_pool);
 }
 
 const char *
 svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
                                    svn_revnum_t rev,
-                                   apr_pool_t *pool)
+                                   apr_pool_t *result_pool)
 {
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-
-  return svn_dirent_join_many(pool, fs->path, PATH_REVPROPS_DIR,
-                              apr_psprintf(pool, "%ld" PATH_EXT_PACKED_SHARD,
-                                           rev / ffd->max_files_per_dir),
-                              SVN_VA_NULL);
+  return construct_shard_sub_path(fs, rev, TRUE, TRUE, NULL, result_pool);
 }
 
 const char *
-svn_fs_x__path_revprops(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool)
+svn_fs_x__path_revprops(svn_fs_t *fs,
+                        svn_revnum_t rev,
+                        apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_revprops_shard(fs, rev, pool),
-                         apr_psprintf(pool, "%ld", rev),
-                         pool);
+  char buffer[SVN_INT64_BUFFER_SIZE];
+  svn__i64toa(buffer, rev);
+
+  assert(! svn_fs_x__is_packed_revprop(fs, rev));
+  return construct_shard_sub_path(fs, rev, TRUE, FALSE, buffer, result_pool);
 }
 
 const char *
@@ -251,19 +268,6 @@ svn_fs_x__txn_by_name(svn_fs_x__txn_id_t
   return SVN_NO_ERROR;
 }
 
-
-/* Return TO_ADD appended to the C string representation of TXN_ID.
- * Allocate the result in POOL.
- */
-static const char *
-combine_txn_id_string(svn_fs_x__txn_id_t txn_id,
-                      const char *to_add,
-                      apr_pool_t *pool)
-{
-  return apr_pstrcat(pool, svn_fs_x__txn_name(txn_id, pool),
-                     to_add, SVN_VA_NULL);
-}
-
 const char *
 svn_fs_x__path_txns_dir(svn_fs_t *fs,
                         apr_pool_t *result_pool)
@@ -271,15 +275,35 @@ svn_fs_x__path_txns_dir(svn_fs_t *fs,
   return svn_dirent_join(fs->path, PATH_TXNS_DIR, result_pool);
 }
 
+/* Return the full path of the file FILENAME within transaction TXN_ID's
+ * transaction directory in FS.  If FILENAME is NULL, return the transaction
+ * directory itself.
+ *
+ * Allocate the result in RESULT_POOL.
+ */
+static const char *
+construct_txn_path(svn_fs_t *fs,
+                   svn_fs_x__txn_id_t txn_id,
+                   const char *filename,
+                   apr_pool_t *result_pool)
+{
+  /* Construct the transaction directory name without temp. allocations. */
+  char buffer[SVN_INT64_BUFFER_SIZE + sizeof(PATH_EXT_TXN)] = { 0 };
+  apr_size_t len = svn__ui64tobase36(buffer, txn_id);
+  strncpy(buffer + len, PATH_EXT_TXN, sizeof(buffer) - len - 1);
+
+  /* If FILENAME is NULL, it will terminate the list of segments
+     to concatenate. */
+  return svn_dirent_join_many(result_pool, fs->path, PATH_TXNS_DIR,
+                              buffer, filename, SVN_VA_NULL);
+}
+
 const char *
 svn_fs_x__path_txn_dir(svn_fs_t *fs,
                        svn_fs_x__txn_id_t txn_id,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool)
 {
-  return svn_dirent_join_many(pool, svn_fs_x__path_txns_dir(fs, pool),
-                              combine_txn_id_string(txn_id, PATH_EXT_TXN,
-                                                    pool),
-                              SVN_VA_NULL);
+  return construct_txn_path(fs, txn_id, NULL, result_pool);
 }
 
 /* Return the name of the sha1->rep mapping file in transaction TXN_ID
@@ -303,55 +327,51 @@ svn_fs_x__path_txn_sha1(svn_fs_t *fs,
 const char *
 svn_fs_x__path_txn_changes(svn_fs_t *fs,
                            svn_fs_x__txn_id_t txn_id,
-                           apr_pool_t *pool)
+                           apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         PATH_CHANGES, pool);
+  return construct_txn_path(fs, txn_id, PATH_CHANGES, result_pool);
 }
 
 const char *
 svn_fs_x__path_txn_props(svn_fs_t *fs,
                          svn_fs_x__txn_id_t txn_id,
-                         apr_pool_t *pool)
+                         apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         PATH_TXN_PROPS, pool);
+  return construct_txn_path(fs, txn_id, PATH_TXN_PROPS, result_pool);
 }
 
 const char *
 svn_fs_x__path_txn_props_final(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *pool)
+                               apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         PATH_TXN_PROPS_FINAL, pool);
+  return construct_txn_path(fs, txn_id, PATH_TXN_PROPS_FINAL, result_pool);
 }
 
 const char*
 svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *pool)
+                               apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         PATH_INDEX PATH_EXT_L2P_INDEX, pool);
+  return construct_txn_path(fs, txn_id, PATH_INDEX PATH_EXT_L2P_INDEX,
+                            result_pool);
 }
 
 const char*
 svn_fs_x__path_p2l_proto_index(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *pool)
+                               apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         PATH_INDEX PATH_EXT_P2L_INDEX, pool);
+  return construct_txn_path(fs, txn_id, PATH_INDEX PATH_EXT_P2L_INDEX,
+                            result_pool);
 }
 
 const char *
 svn_fs_x__path_txn_next_ids(svn_fs_t *fs,
                             svn_fs_x__txn_id_t txn_id,
-                            apr_pool_t *pool)
+                            apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         PATH_NEXT_IDS, pool);
+  return construct_txn_path(fs, txn_id, PATH_NEXT_IDS, result_pool);
 }
 
 const char *
@@ -371,77 +391,105 @@ svn_fs_x__path_txn_proto_revs(svn_fs_t *
 const char *
 svn_fs_x__path_txn_item_index(svn_fs_t *fs,
                               svn_fs_x__txn_id_t txn_id,
-                              apr_pool_t *pool)
+                              apr_pool_t *result_pool)
 {
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         PATH_TXN_ITEM_INDEX, pool);
+  return construct_txn_path(fs, txn_id, PATH_TXN_ITEM_INDEX, result_pool);
+}
+
+/* Return the full path of the proto-rev file / lock file for transaction
+ * TXN_ID in FS.  The SUFFIX determines what file (rev / lock) it will be.
+ *
+ * Allocate the result in RESULT_POOL.
+ */
+static const char *
+construct_proto_rev_path(svn_fs_t *fs,
+                         svn_fs_x__txn_id_t txn_id,
+                         const char *suffix,
+                         apr_pool_t *result_pool)
+{
+  /* Construct the file name without temp. allocations. */
+  char buffer[SVN_INT64_BUFFER_SIZE + sizeof(PATH_EXT_REV_LOCK)] = { 0 };
+  apr_size_t len = svn__ui64tobase36(buffer, txn_id);
+  strncpy(buffer + len, suffix, sizeof(buffer) - len - 1);
+
+  /* If FILENAME is NULL, it will terminate the list of segments
+     to concatenate. */
+  return svn_dirent_join_many(result_pool, fs->path, PATH_TXN_PROTOS_DIR,
+                              buffer, SVN_VA_NULL);
 }
 
 const char *
 svn_fs_x__path_txn_proto_rev(svn_fs_t *fs,
                              svn_fs_x__txn_id_t txn_id,
-                             apr_pool_t *pool)
+                             apr_pool_t *result_pool)
 {
-  return svn_dirent_join_many(pool, svn_fs_x__path_txn_proto_revs(fs, pool),
-                              combine_txn_id_string(txn_id, PATH_EXT_REV,
-                                                    pool),
-                              SVN_VA_NULL);
+  return construct_proto_rev_path(fs, txn_id, PATH_EXT_REV, result_pool);
 }
 
 const char *
 svn_fs_x__path_txn_proto_rev_lock(svn_fs_t *fs,
                                   svn_fs_x__txn_id_t txn_id,
-                                  apr_pool_t *pool)
+                                  apr_pool_t *result_pool)
+{
+  return construct_proto_rev_path(fs, txn_id, PATH_EXT_REV_LOCK, result_pool);
+}
+
+/* Return the full path of the noderev-related file with the extension SUFFIX
+ * for noderev *ID in transaction TXN_ID in FS.
+ *
+ * Allocate the result in RESULT_POOL and temporaries in SCRATCH_POOL.
+ */
+static const char *
+construct_txn_node_path(svn_fs_t *fs,
+                        const svn_fs_x__id_t *id,
+                        const char *suffix,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
 {
-  return svn_dirent_join_many(pool, svn_fs_x__path_txn_proto_revs(fs, pool),
-                              combine_txn_id_string(txn_id,
-                                                    PATH_EXT_REV_LOCK,
-                                                    pool),
-                              SVN_VA_NULL);
+  const char *filename = svn_fs_x__id_unparse(id, result_pool)->data;
+  apr_int64_t txn_id = svn_fs_x__get_txn_id(id->change_set);
+
+  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, scratch_pool),
+                         apr_psprintf(scratch_pool, PATH_PREFIX_NODE "%s%s",
+                                      filename, suffix),
+                         result_pool);
 }
 
 const char *
 svn_fs_x__path_txn_node_rev(svn_fs_t *fs,
                             const svn_fs_x__id_t *id,
-                            apr_pool_t *pool)
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
 {
-  const char *filename = svn_fs_x__id_unparse(id, pool)->data;
-  apr_int64_t txn_id = svn_fs_x__get_txn_id(id->change_set);
-
-  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                         apr_psprintf(pool, PATH_PREFIX_NODE "%s", filename),
-                         pool);
+  return construct_txn_node_path(fs, id, "", result_pool, scratch_pool);
 }
 
 const char *
 svn_fs_x__path_txn_node_props(svn_fs_t *fs,
                               const svn_fs_x__id_t *id,
-                              apr_pool_t *pool)
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
 {
-  return apr_pstrcat(pool, svn_fs_x__path_txn_node_rev(fs, id, pool),
-                     PATH_EXT_PROPS, SVN_VA_NULL);
+  return construct_txn_node_path(fs, id, PATH_EXT_PROPS, result_pool,
+                                 scratch_pool);
 }
 
 const char *
 svn_fs_x__path_txn_node_children(svn_fs_t *fs,
                                  const svn_fs_x__id_t *id,
-                                 apr_pool_t *pool)
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
 {
-  return apr_pstrcat(pool, svn_fs_x__path_txn_node_rev(fs, id, pool),
-                     PATH_EXT_CHILDREN, SVN_VA_NULL);
+  return construct_txn_node_path(fs, id, PATH_EXT_CHILDREN, result_pool,
+                                 scratch_pool);
 }
 
-
-/* Check that BUF, a nul-terminated buffer of text from file PATH,
-   contains only digits at OFFSET and beyond, raising an error if not.
-   TITLE contains a user-visible description of the file, usually the
-   short file name.
-
-   Uses POOL for temporary allocation. */
 svn_error_t *
-svn_fs_x__check_file_buffer_numeric(const char *buf, apr_off_t offset,
-                                    const char *path, const char *title,
-                                    apr_pool_t *pool)
+svn_fs_x__check_file_buffer_numeric(const char *buf,
+                                    apr_off_t offset,
+                                    const char *path,
+                                    const char *title,
+                                    apr_pool_t *scratch_pool)
 {
   const char *p;
 
@@ -449,7 +497,7 @@ svn_fs_x__check_file_buffer_numeric(cons
     if (!svn_ctype_isdigit(*p))
       return svn_error_createf(SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
         _("%s file '%s' contains unexpected non-digit '%c' within '%s'"),
-        title, svn_dirent_local_style(path, pool), *p, buf);
+        title, svn_dirent_local_style(path, scratch_pool), *p, buf);
 
   return SVN_NO_ERROR;
 }
@@ -607,12 +655,10 @@ svn_fs_x__get_file_offset(apr_off_t *off
   return SVN_NO_ERROR;
 }
 
-/* Read the 'current' file FNAME and store the contents in *BUF.
-   Allocations are performed in POOL. */
 svn_error_t *
 svn_fs_x__read_content(svn_stringbuf_t **content,
                        const char *fname,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool)
 {
   int i;
   *content = NULL;
@@ -620,12 +666,12 @@ svn_fs_x__read_content(svn_stringbuf_t *
   for (i = 0; !*content && (i < SVN_FS_X__RECOVERABLE_RETRY_COUNT); ++i)
     SVN_ERR(svn_fs_x__try_stringbuf_from_file(content, NULL,
                            fname, i + 1 < SVN_FS_X__RECOVERABLE_RETRY_COUNT,
-                           pool));
+                           result_pool));
 
   if (!*content)
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Can't read '%s'"),
-                             svn_dirent_local_style(fname, pool));
+                             svn_dirent_local_style(fname, result_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.h?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.h (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/util.h Tue Jan 27 23:27:44 2015
@@ -146,13 +146,13 @@ svn_fs_x__path_revprop_generation(svn_fs
 
 /* Return the path of the pack-related file that for revision REV in FS.
  * KIND specifies the file name base, e.g. "pack".
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_rev_packed(svn_fs_t *fs,
                           svn_revnum_t rev,
                           const char *kind,
-                          apr_pool_t *pool);
+                          apr_pool_t *result_pool);
 
 /* Return the full path of the rev shard directory that will contain
  * revision REV in FS.  Allocate the result in RESULT_POOL.
@@ -163,15 +163,15 @@ svn_fs_x__path_rev_shard(svn_fs_t *fs,
                          apr_pool_t *result_pool);
 
 /* Return the full path of the non-packed rev file containing revision REV
- * in FS.  Allocate the result in POOL.
+ * in FS.  Allocate the result in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_rev(svn_fs_t *fs,
                    svn_revnum_t rev,
-                   apr_pool_t *pool);
+                   apr_pool_t *result_pool);
 
 /* Set *PATH to the path of REV in FS, whether in a pack file or not.
-   Allocate *PATH in POOL.
+   Allocate *PATH in RESULT_POOL.
 
    Note: If the caller does not have the write lock on FS, then the path is
    not guaranteed to be correct or to remain correct after the function
@@ -181,7 +181,7 @@ svn_fs_x__path_rev(svn_fs_t *fs,
 const char *
 svn_fs_x__path_rev_absolute(svn_fs_t *fs,
                             svn_revnum_t rev,
-                            apr_pool_t *pool);
+                            apr_pool_t *result_pool);
 
 /* Return the full path of the revision properties shard directory that
  * will contain the properties of revision REV in FS.
@@ -194,20 +194,21 @@ svn_fs_x__path_revprops_shard(svn_fs_t *
 
 /* Return the full path of the revision properties pack shard directory
  * that will contain the packed properties of revision REV in FS.
- * Allocate the result in POOL.
+ * Allocate the result in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
                                    svn_revnum_t rev,
-                                   apr_pool_t *pool);
+                                   apr_pool_t *result_pool);
 
 /* Return the full path of the non-packed revision properties file that
- * contains the props for revision REV in FS.  Allocate the result in POOL.
+ * contains the props for revision REV in FS.
+ * Allocate the result in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_revprops(svn_fs_t *fs,
                         svn_revnum_t rev,
-                        apr_pool_t *pool);
+                        apr_pool_t *result_pool);
 
 /* Convert the TXN_ID into a string, allocated from RESULT_POOL.
  */
@@ -221,12 +222,12 @@ svn_fs_x__txn_by_name(svn_fs_x__txn_id_t
                       const char *txn_name);
 
 /* Return the path of the directory containing the transaction TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_dir(svn_fs_t *fs,
                        svn_fs_x__txn_id_t txn_id,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool);
 
 /* Return the path of the 'transactions' directory in FS.
  * The result will be allocated in RESULT_POOL.
@@ -252,57 +253,57 @@ svn_fs_x__path_txn_proto_revs(svn_fs_t *
                               apr_pool_t *result_pool);
 
 /* Return the path of the changes file for transaction TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_changes(svn_fs_t *fs,
                            svn_fs_x__txn_id_t txn_id,
-                           apr_pool_t *pool);
+                           apr_pool_t *result_pool);
 
 /* Return the path of the file containing the log-to-phys index for
  * the transaction identified by TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char*
 svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *pool);
+                               apr_pool_t *result_pool);
 
 /* Return the path of the file containing the phys-to-log index for
  * the transaction identified by TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char*
 svn_fs_x__path_p2l_proto_index(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *pool);
+                               apr_pool_t *result_pool);
 
 /* Return the path of the file containing the transaction properties for
  * the transaction identified by TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_props(svn_fs_t *fs,
                          svn_fs_x__txn_id_t txn_id,
-                         apr_pool_t *pool);
+                         apr_pool_t *result_pool);
 
 /* Return the path of the file containing the "final" transaction
  * properties for the transaction identified by TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_props_final(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *pool);
+                               apr_pool_t *result_pool);
 
 /* Return the path of the file containing the node and copy ID counters for
  * the transaction identified by TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_next_ids(svn_fs_t *fs,
                             svn_fs_x__txn_id_t txn_id,
-                            apr_pool_t *pool);
+                            apr_pool_t *result_pool);
 
 /* Return the path of the file storing the oldest non-packed revision in FS.
  * The result will be allocated in RESULT_POOL.
@@ -313,66 +314,71 @@ svn_fs_x__path_min_unpacked_rev(svn_fs_t
 
 /* Return the path of the file containing item_index counter for
  * the transaction identified by TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_item_index(svn_fs_t *fs,
                               svn_fs_x__txn_id_t txn_id,
-                              apr_pool_t *pool);
+                              apr_pool_t *result_pool);
 
 /* Return the path of the proto-revision file for transaction TXN_ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_proto_rev(svn_fs_t *fs,
                              svn_fs_x__txn_id_t txn_id,
-                             apr_pool_t *pool);
+                             apr_pool_t *result_pool);
 
 /* Return the path of the proto-revision lock file for transaction TXN_ID
- * in FS.  The result will be allocated in POOL.
+ * in FS.  The result will be allocated in RESULT_POOL.
  */
 const char *
 svn_fs_x__path_txn_proto_rev_lock(svn_fs_t *fs,
                                   svn_fs_x__txn_id_t txn_id,
-                                  apr_pool_t *pool);
+                                  apr_pool_t *result_pool);
 
 /* Return the path of the file containing the in-transaction node revision
- * identified by ID in FS.  The result will be allocated in POOL.
+ * identified by ID in FS.
+ * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL.
  */
 const char *
 svn_fs_x__path_txn_node_rev(svn_fs_t *fs,
                             const svn_fs_x__id_t *id,
-                            apr_pool_t *pool);
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
 
 /* Return the path of the file containing the in-transaction properties of
- * the node identified by ID in FS.  The result will be allocated in POOL.
+ * the node identified by ID in FS.
+ * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL.
  */
 const char *
 svn_fs_x__path_txn_node_props(svn_fs_t *fs,
                               const svn_fs_x__id_t *id,
-                              apr_pool_t *pool);
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
 
 /* Return the path of the file containing the directory entries of the
  * in-transaction directory node identified by ID in FS.
- * The result will be allocated in POOL.
+ * The result will be allocated in RESULT_POOL, temporaries in SCRATCH_POOL.
  */
 const char *
 svn_fs_x__path_txn_node_children(svn_fs_t *fs,
                                  const svn_fs_x__id_t *id,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
 
 /* Check that BUF, a nul-terminated buffer of text from file PATH,
    contains only digits at OFFSET and beyond, raising an error if not.
    TITLE contains a user-visible description of the file, usually the
    short file name.
 
-   Uses POOL for temporary allocation. */
+   Uses SCRATCH_POOL for temporary allocation. */
 svn_error_t *
 svn_fs_x__check_file_buffer_numeric(const char *buf,
                                     apr_off_t offset,
                                     const char *path,
                                     const char *title,
-                                    apr_pool_t *pool);
+                                    apr_pool_t *scratch_pool);
 
 /* Set *MIN_UNPACKED_REV to the integer value read from the file returned
  * by #svn_fs_fs__path_min_unpacked_rev() for FS.
@@ -384,11 +390,11 @@ svn_fs_x__read_min_unpacked_rev(svn_revn
                                 apr_pool_t *scratch_pool);
 
 /* Re-read the MIN_UNPACKED_REV member of FS from disk.
- * Use POOL for temporary allocations.
+ * Use SCRATCH_POOL for temporary allocations.
  */
 svn_error_t *
 svn_fs_x__update_min_unpacked_rev(svn_fs_t *fs,
-                                  apr_pool_t *pool);
+                                  apr_pool_t *scratch_pool);
 
 /* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed
  * REVNUM.  Perform temporary allocations in SCRATCH_POOL.
@@ -436,11 +442,11 @@ svn_fs_x__get_file_offset(apr_off_t *off
                           apr_pool_t *scratch_pool);
 
 /* Read the file FNAME and store the contents in *BUF.
-   Allocations are performed in POOL. */
+   Allocations are performed in RESULT_POOL. */
 svn_error_t *
 svn_fs_x__read_content(svn_stringbuf_t **content,
                        const char *fname,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool);
 
 /* Reads a line from STREAM and converts it to a 64 bit integer to be
  * returned in *RESULT.  If we encounter eof, set *HIT_EOF and leave

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blame.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blame.c Tue Jan 27 23:27:44 2015
@@ -280,7 +280,8 @@ static svn_error_t *
 create_file_revs_body(serf_bucket_t **body_bkt,
                       void *baton,
                       serf_bucket_alloc_t *alloc,
-                      apr_pool_t *pool)
+                      apr_pool_t *pool /* request pool */,
+                      apr_pool_t *scratch_pool)
 {
   serf_bucket_t *buckets;
   blame_context_t *blame_ctx = baton;
@@ -351,7 +352,7 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
     peg_rev = start;
 
   SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
-                                      session, NULL /* conn */,
+                                      session,
                                       NULL /* url */, peg_rev,
                                       pool, pool));
 
@@ -361,15 +362,13 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
                                            blame_cdata,
                                            blame_ctx,
                                            pool);
-  handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, pool);
+  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
   handler->body_type = "text/xml";
   handler->body_delegate = create_file_revs_body;
   handler->body_delegate_baton = blame_ctx;
-  handler->conn = session->conns[0];
-  handler->session = session;
 
   SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.c Tue Jan 27 23:27:44 2015
@@ -112,7 +112,7 @@ svn_ra_serf__blncache_set(svn_ra_serf__b
                           const char *baseline_url,
                           svn_revnum_t revision,
                           const char *bc_url,
-                          apr_pool_t *pool)
+                          apr_pool_t *scratch_pool)
 {
   if (bc_url && SVN_IS_VALID_REVNUM(revision))
     {
@@ -147,11 +147,11 @@ svn_error_t *
 svn_ra_serf__blncache_get_bc_url(const char **bc_url_p,
                                  svn_ra_serf__blncache_t *blncache,
                                  svn_revnum_t revnum,
-                                 apr_pool_t *pool)
+                                 apr_pool_t *result_pool)
 {
   const char *value = apr_hash_get(blncache->revnum_to_bc,
                                    &revnum, sizeof(revnum));
-  *bc_url_p = value ? apr_pstrdup(pool, value) : NULL;
+  *bc_url_p = value ? apr_pstrdup(result_pool, value) : NULL;
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.h?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.h (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/blncache.h Tue Jan 27 23:27:44 2015
@@ -59,7 +59,7 @@ svn_ra_serf__blncache_set(svn_ra_serf__b
                           const char *baseline_url,
                           svn_revnum_t revnum,
                           const char *bc_url,
-                          apr_pool_t *pool);
+                          apr_pool_t *scratch_pool);
 
 /* Sets *BC_URL_P with a pointer to baseline collection URL for the given
  * REVNUM. *BC_URL_P will be NULL if cache doesn't have information about
@@ -69,7 +69,7 @@ svn_error_t *
 svn_ra_serf__blncache_get_bc_url(const char **bc_url_p,
                                  svn_ra_serf__blncache_t *blncache,
                                  svn_revnum_t revnum,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool);
 
 /* Sets *BC_URL_P with pointer to baseline collection URL and *REVISION_P
  * with revision number of baseline BASELINE_URL. *BC_URL_P will be NULL,

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/commit.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/commit.c Tue Jan 27 23:27:44 2015
@@ -51,7 +51,6 @@ typedef struct commit_context_t {
   apr_pool_t *pool;
 
   svn_ra_serf__session_t *session;
-  svn_ra_serf__connection_t *conn;
 
   apr_hash_t *revprop_table;
 
@@ -85,13 +84,11 @@ typedef struct proppatch_context_t {
 
   commit_context_t *commit_ctx;
 
-  /* Changed and removed properties. */
-  apr_hash_t *changed_props;
-  apr_hash_t *removed_props;
-
-  /* Same, for the old value (*old_value_p). */
-  apr_hash_t *previous_changed_props;
-  apr_hash_t *previous_removed_props;
+  /* Changed properties. const char * -> svn_prop_t * */
+  apr_hash_t *prop_changes;
+
+  /* Same, for the old value, or NULL. */
+  apr_hash_t *old_props;
 
   /* In HTTP v2, this is the file/directory version we think we're changing. */
   svn_revnum_t base_revision;
@@ -139,9 +136,8 @@ typedef struct dir_context_t {
   const char *copy_path;
   svn_revnum_t copy_revision;
 
-  /* Changed and removed properties */
-  apr_hash_t *changed_props;
-  apr_hash_t *removed_props;
+  /* Changed properties (const char * -> svn_prop_t *) */
+  apr_hash_t *prop_changes;
 
   /* The checked-out working resource for this directory.  May be NULL; if so
      call checkout_dir() first.  */
@@ -186,9 +182,8 @@ typedef struct file_context_t {
   /* Our resulting checksum as reported by the WC. */
   const char *result_checksum;
 
-  /* Changed and removed properties. */
-  apr_hash_t *changed_props;
-  apr_hash_t *removed_props;
+  /* Changed properties (const char * -> svn_prop_t *) */
+  apr_hash_t *prop_changes;
 
   /* URL to PUT the file at. */
   const char *url;
@@ -203,7 +198,8 @@ static svn_error_t *
 create_checkout_body(serf_bucket_t **bkt,
                      void *baton,
                      serf_bucket_alloc_t *alloc,
-                     apr_pool_t *pool)
+                     apr_pool_t *pool /* request pool */,
+                     apr_pool_t *scratch_pool)
 {
   const char *activity_url = baton;
   serf_bucket_t *body_bkt;
@@ -267,9 +263,7 @@ checkout_node(const char **working_url,
 
   /* HANDLER_POOL is the scratch pool since we don't need to remember
      anything from the handler. We just want the working resource.  */
-  handler = svn_ra_serf__create_handler(scratch_pool);
-  handler->session = commit_ctx->session;
-  handler->conn = commit_ctx->conn;
+  handler = svn_ra_serf__create_handler(commit_ctx->session, scratch_pool);
 
   handler->body_delegate = create_checkout_body;
   handler->body_delegate_baton = (/* const */ void *)commit_ctx->activity_url;
@@ -459,7 +453,6 @@ get_version_url(const char **checked_in_
   else
     {
       const char *propfind_url;
-      svn_ra_serf__connection_t *conn = session->conns[0];
 
       if (SVN_IS_VALID_REVNUM(base_revision))
         {
@@ -468,10 +461,9 @@ get_version_url(const char **checked_in_
              this lookup, so we'll do things the hard(er) way, by
              looking up the version URL from a resource in the
              baseline collection. */
-          /* ### conn==NULL for session->conns[0]. same as CONN.  */
           SVN_ERR(svn_ra_serf__get_stable_url(&propfind_url,
                                               NULL /* latest_revnum */,
-                                              session, NULL /* conn */,
+                                              session,
                                               NULL /* url */, base_revision,
                                               scratch_pool, scratch_pool));
         }
@@ -480,8 +472,8 @@ get_version_url(const char **checked_in_
           propfind_url = session->session_url.path;
         }
 
-      SVN_ERR(svn_ra_serf__fetch_dav_prop(&root_checkout,
-                                          conn, propfind_url, base_revision,
+      SVN_ERR(svn_ra_serf__fetch_dav_prop(&root_checkout, session,
+                                          propfind_url, base_revision,
                                           "checked-in",
                                           scratch_pool, scratch_pool));
       if (!root_checkout)
@@ -569,101 +561,23 @@ get_encoding_and_cdata(const char **enco
   return SVN_NO_ERROR;
 }
 
-typedef struct walker_baton_t {
-  serf_bucket_t *body_bkt;
-  apr_pool_t *body_pool;
-
-  apr_hash_t *previous_changed_props;
-  apr_hash_t *previous_removed_props;
-
-  const char *path;
-
-  /* Hack, since change_rev_prop(old_value_p != NULL, value = NULL) uses D:set
-     rather than D:remove...  (see notes/http-and-webdav/webdav-protocol) */
-  enum {
-    filter_all_props,
-    filter_props_with_old_value,
-    filter_props_without_old_value
-  } filter;
-
-  /* Is the property being deleted? */
-  svn_boolean_t deleting;
-} walker_baton_t;
-
-/* If we have (recorded in WB) the old value of the property named NS:NAME,
- * then set *HAVE_OLD_VAL to TRUE and set *OLD_VAL_P to that old value
- * (which may be NULL); else set *HAVE_OLD_VAL to FALSE.  */
+/* Helper for create_proppatch_body. Writes per property xml to body */
 static svn_error_t *
-derive_old_val(svn_boolean_t *have_old_val,
-               const svn_string_t **old_val_p,
-               walker_baton_t *wb,
-               const char *ns,
-               const char *name)
+write_prop_xml(const proppatch_context_t *proppatch,
+               serf_bucket_t *body_bkt,
+               serf_bucket_alloc_t *alloc,
+               const svn_prop_t *prop,
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
 {
-  *have_old_val = FALSE;
-
-  if (wb->previous_changed_props)
-    {
-      const svn_string_t *val;
-      val = svn_ra_serf__get_prop_string(wb->previous_changed_props,
-                                         wb->path, ns, name);
-      if (val)
-        {
-          *have_old_val = TRUE;
-          *old_val_p = val;
-        }
-    }
-
-  if (wb->previous_removed_props)
-    {
-      const svn_string_t *val;
-      val = svn_ra_serf__get_prop_string(wb->previous_removed_props,
-                                         wb->path, ns, name);
-      if (val)
-        {
-          *have_old_val = TRUE;
-          *old_val_p = NULL;
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-proppatch_walker(void *baton,
-                 const char *ns,
-                 const char *name,
-                 const svn_string_t *val,
-                 apr_pool_t *scratch_pool)
-{
-  walker_baton_t *wb = baton;
-  serf_bucket_t *body_bkt = wb->body_bkt;
   serf_bucket_t *cdata_bkt;
-  serf_bucket_alloc_t *alloc;
   const char *encoding;
-  svn_boolean_t have_old_val;
-  const svn_string_t *old_val;
   const svn_string_t *encoded_value;
   const char *prop_name;
+  const svn_prop_t *old_prop;
 
-  SVN_ERR(derive_old_val(&have_old_val, &old_val, wb, ns, name));
-
-  /* Jump through hoops to work with D:remove and its val = (""-for-NULL)
-   * representation. */
-  if (wb->filter != filter_all_props)
-    {
-      if (wb->filter == filter_props_with_old_value && ! have_old_val)
-        return SVN_NO_ERROR;
-      if (wb->filter == filter_props_without_old_value && have_old_val)
-        return SVN_NO_ERROR;
-    }
-  if (wb->deleting)
-    val = NULL;
-
-  alloc = body_bkt->allocator;
-
-  SVN_ERR(get_encoding_and_cdata(&encoding, &encoded_value, alloc, val,
-                                 wb->body_pool, scratch_pool));
+  SVN_ERR(get_encoding_and_cdata(&encoding, &encoded_value, alloc, prop->value,
+                                 result_pool, scratch_pool));
   if (encoded_value)
     {
       cdata_bkt = SERF_BUCKET_SIMPLE_STRING_LEN(encoded_value->data,
@@ -677,12 +591,18 @@ proppatch_walker(void *baton,
 
   /* Use the namespace prefix instead of adding the xmlns attribute to support
      property names containing ':' */
-  if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
-    prop_name = apr_pstrcat(wb->body_pool, "S:", name, SVN_VA_NULL);
-  else if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
-    prop_name = apr_pstrcat(wb->body_pool, "C:", name, SVN_VA_NULL);
+  if (strncmp(prop->name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0)
+    {
+      prop_name = apr_pstrcat(result_pool,
+                              "S:", prop->name + sizeof(SVN_PROP_PREFIX) - 1,
+                              SVN_VA_NULL);
+    }
   else
-    SVN_ERR_MALFUNCTION();
+    {
+      prop_name = apr_pstrcat(result_pool,
+                              "C:", prop->name,
+                              SVN_VA_NULL);
+    }
 
   if (cdata_bkt)
     svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, prop_name,
@@ -693,15 +613,18 @@ proppatch_walker(void *baton,
                                       "V:" SVN_DAV__OLD_VALUE__ABSENT, "1",
                                       SVN_VA_NULL);
 
-  if (have_old_val)
+  old_prop = proppatch->old_props
+                          ? svn_hash_gets(proppatch->old_props, prop->name)
+                          : NULL;
+  if (old_prop)
     {
       const char *encoding2;
       const svn_string_t *encoded_value2;
       serf_bucket_t *cdata_bkt2;
 
       SVN_ERR(get_encoding_and_cdata(&encoding2, &encoded_value2,
-                                     alloc, old_val,
-                                     wb->body_pool, scratch_pool));
+                                     alloc, old_prop->value,
+                                     result_pool, scratch_pool));
 
       if (encoded_value2)
         {
@@ -789,7 +712,8 @@ maybe_set_lock_token_header(serf_bucket_
 static svn_error_t *
 setup_proppatch_headers(serf_bucket_t *headers,
                         void *baton,
-                        apr_pool_t *pool)
+                        apr_pool_t *pool /* request pool */,
+                        apr_pool_t *scratch_pool)
 {
   proppatch_context_t *proppatch = baton;
 
@@ -813,11 +737,13 @@ static svn_error_t *
 create_proppatch_body(serf_bucket_t **bkt,
                       void *baton,
                       serf_bucket_alloc_t *alloc,
+                      apr_pool_t *pool /* request pool */,
                       apr_pool_t *scratch_pool)
 {
   proppatch_context_t *ctx = baton;
   serf_bucket_t *body_bkt;
-  walker_baton_t wb = { 0 };
+  svn_boolean_t opened = FALSE;
+  apr_hash_index_t *hi;
 
   body_bkt = serf_bucket_aggregate_create(alloc);
 
@@ -829,59 +755,64 @@ create_proppatch_body(serf_bucket_t **bk
                                     "xmlns:S", SVN_DAV_PROP_NS_SVN,
                                     SVN_VA_NULL);
 
-  wb.body_bkt = body_bkt;
-  wb.body_pool = scratch_pool;
-  wb.previous_changed_props = ctx->previous_changed_props;
-  wb.previous_removed_props = ctx->previous_removed_props;
-  wb.path = ctx->path;
-
-  if (apr_hash_count(ctx->changed_props) > 0)
-    {
-      svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:set", SVN_VA_NULL);
-      svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop", SVN_VA_NULL);
-
-      wb.filter = filter_all_props;
-      wb.deleting = FALSE;
-      SVN_ERR(svn_ra_serf__walk_all_props(ctx->changed_props, ctx->path,
-                                          SVN_INVALID_REVNUM,
-                                          proppatch_walker, &wb,
-                                          scratch_pool));
+  /* First we write property SETs */
+  for (hi = apr_hash_first(scratch_pool, ctx->prop_changes);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+      svn_prop_t *prop = apr_hash_this_val(hi);
 
-      svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:prop");
-      svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:set");
+      if (prop->value
+          || (ctx->old_props && svn_hash_gets(ctx->old_props, prop->name)))
+        {
+          if (!opened)
+            {
+              opened = TRUE;
+              svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:set",
+                                                SVN_VA_NULL);
+              svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop",
+                                                SVN_VA_NULL);
+            }
+
+          SVN_ERR(write_prop_xml(ctx, body_bkt, alloc, prop,
+                                 pool, scratch_pool));
+        }
     }
 
-  if ((apr_hash_count(ctx->removed_props) > 0)
-      && (wb.previous_changed_props || wb.previous_removed_props))
+  if (opened)
     {
-      /* For revision properties we handle a remove as a special propset if
-         we want to provide the old version of the property */
-      svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:set", SVN_VA_NULL);
-      svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop", SVN_VA_NULL);
-
-      wb.filter = filter_props_with_old_value;
-      wb.deleting = TRUE;
-      SVN_ERR(svn_ra_serf__walk_all_props(ctx->removed_props, ctx->path,
-                                          SVN_INVALID_REVNUM,
-                                          proppatch_walker, &wb,
-                                          scratch_pool));
-
       svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:prop");
       svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:set");
     }
 
-  if (apr_hash_count(ctx->removed_props) > 0)
+  /* And then property REMOVEs */
+  opened = FALSE;
+
+  for (hi = apr_hash_first(scratch_pool, ctx->prop_changes);
+       hi;
+       hi = apr_hash_next(hi))
     {
-      svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:remove", SVN_VA_NULL);
-      svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop", SVN_VA_NULL);
+      svn_prop_t *prop = apr_hash_this_val(hi);
+
+      if (!prop->value
+          && !(ctx->old_props && svn_hash_gets(ctx->old_props, prop->name)))
+        {
+          if (!opened)
+            {
+              opened = TRUE;
+              svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:remove",
+                                                SVN_VA_NULL);
+              svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop",
+                                                SVN_VA_NULL);
+            }
 
-      wb.filter = filter_props_without_old_value;
-      wb.deleting = TRUE;
-      SVN_ERR(svn_ra_serf__walk_all_props(ctx->removed_props, ctx->path,
-                                          SVN_INVALID_REVNUM,
-                                          proppatch_walker, &wb,
-                                          scratch_pool));
+          SVN_ERR(write_prop_xml(ctx, body_bkt, alloc, prop,
+                                 pool, scratch_pool));
+        }
+    }
 
+  if (opened)
+    {
       svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:prop");
       svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:remove");
     }
@@ -894,19 +825,16 @@ create_proppatch_body(serf_bucket_t **bk
 
 static svn_error_t*
 proppatch_resource(svn_ra_serf__session_t *session,
-                   svn_ra_serf__connection_t *conn,
                    proppatch_context_t *proppatch,
                    apr_pool_t *pool)
 {
   svn_ra_serf__handler_t *handler;
   svn_error_t *err;
 
-  handler = svn_ra_serf__create_handler(pool);
+  handler = svn_ra_serf__create_handler(session, pool);
 
   handler->method = "PROPPATCH";
   handler->path = proppatch->path;
-  handler->conn = conn;
-  handler->session = session;
 
   handler->header_delegate = setup_proppatch_headers;
   handler->header_delegate_baton = proppatch;
@@ -943,7 +871,8 @@ static svn_error_t *
 create_put_body(serf_bucket_t **body_bkt,
                 void *baton,
                 serf_bucket_alloc_t *alloc,
-                apr_pool_t *pool)
+                apr_pool_t *pool /* request pool */,
+                apr_pool_t *scratch_pool)
 {
   file_context_t *ctx = baton;
   apr_off_t offset;
@@ -971,7 +900,8 @@ static svn_error_t *
 create_empty_put_body(serf_bucket_t **body_bkt,
                       void *baton,
                       serf_bucket_alloc_t *alloc,
-                      apr_pool_t *pool)
+                      apr_pool_t *pool /* request pool */,
+                      apr_pool_t *scratch_pool)
 {
   *body_bkt = SERF_BUCKET_SIMPLE_STRING("", alloc);
   return SVN_NO_ERROR;
@@ -980,7 +910,8 @@ create_empty_put_body(serf_bucket_t **bo
 static svn_error_t *
 setup_put_headers(serf_bucket_t *headers,
                   void *baton,
-                  apr_pool_t *pool)
+                  apr_pool_t *pool /* request pool */,
+                  apr_pool_t *scratch_pool)
 {
   file_context_t *ctx = baton;
 
@@ -1011,7 +942,8 @@ setup_put_headers(serf_bucket_t *headers
 static svn_error_t *
 setup_copy_file_headers(serf_bucket_t *headers,
                         void *baton,
-                        apr_pool_t *pool)
+                        apr_pool_t *pool /* request pool */,
+                        apr_pool_t *scratch_pool)
 {
   file_context_t *file = baton;
   apr_uri_t uri;
@@ -1109,7 +1041,8 @@ setup_if_header_recursive(svn_boolean_t
 static svn_error_t *
 setup_add_dir_common_headers(serf_bucket_t *headers,
                              void *baton,
-                             apr_pool_t *pool)
+                             apr_pool_t *pool /* request pool */,
+                             apr_pool_t *scratch_pool)
 {
   dir_context_t *dir = baton;
   svn_boolean_t added;
@@ -1122,7 +1055,8 @@ setup_add_dir_common_headers(serf_bucket
 static svn_error_t *
 setup_copy_dir_headers(serf_bucket_t *headers,
                        void *baton,
-                       apr_pool_t *pool)
+                       apr_pool_t *pool /* request pool */,
+                       apr_pool_t *scratch_pool)
 {
   dir_context_t *dir = baton;
   apr_uri_t uri;
@@ -1151,13 +1085,15 @@ setup_copy_dir_headers(serf_bucket_t *he
   /* Implicitly checkout this dir now. */
   dir->working_url = apr_pstrdup(dir->pool, uri.path);
 
-  return svn_error_trace(setup_add_dir_common_headers(headers, baton, pool));
+  return svn_error_trace(setup_add_dir_common_headers(headers, baton, pool,
+                                                      scratch_pool));
 }
 
 static svn_error_t *
 setup_delete_headers(serf_bucket_t *headers,
                      void *baton,
-                     apr_pool_t *pool)
+                     apr_pool_t *pool /* request pool */,
+                     apr_pool_t *scratch_pool)
 {
   delete_context_t *del = baton;
   svn_boolean_t added;
@@ -1182,7 +1118,8 @@ static svn_error_t *
 create_txn_post_body(serf_bucket_t **body_bkt,
                      void *baton,
                      serf_bucket_alloc_t *alloc,
-                     apr_pool_t *pool)
+                     apr_pool_t *pool /* request pool */,
+                     apr_pool_t *scratch_pool)
 {
   apr_hash_t *revprops = baton;
   svn_skel_t *request_skel;
@@ -1211,7 +1148,8 @@ create_txn_post_body(serf_bucket_t **bod
 static svn_error_t *
 setup_post_headers(serf_bucket_t *headers,
                    void *baton,
-                   apr_pool_t *pool)
+                   apr_pool_t *pool /* request pool */,
+                   apr_pool_t *scratch_pool)
 {
 #ifdef SVN_DAV_SEND_VTXN_NAME
   /* Enable this to exercise the VTXN-NAME code based on a client
@@ -1320,7 +1258,7 @@ open_root(void *edit_baton,
                                  "create-txn-with-props"));
 
       /* Create our activity URL now on the server. */
-      handler = svn_ra_serf__create_handler(scratch_pool);
+      handler = svn_ra_serf__create_handler(commit_ctx->session, scratch_pool);
 
       handler->method = "POST";
       handler->body_type = SVN_SKEL_MIME_TYPE;
@@ -1330,8 +1268,6 @@ open_root(void *edit_baton,
       handler->header_delegate = setup_post_headers;
       handler->header_delegate_baton = NULL;
       handler->path = commit_ctx->session->me_resource;
-      handler->conn = commit_ctx->session->conns[0];
-      handler->session = commit_ctx->session;
 
       prc = apr_pcalloc(scratch_pool, sizeof(*prc));
       prc->handler = handler;
@@ -1356,7 +1292,7 @@ open_root(void *edit_baton,
       SVN_ERR(svn_ra_serf__get_relative_path(
                                         &rel_path,
                                         commit_ctx->session->session_url.path,
-                                        commit_ctx->session, NULL,
+                                        commit_ctx->session,
                                         scratch_pool));
       commit_ctx->txn_root_url = svn_path_url_add_component2(
                                         commit_ctx->txn_root_url,
@@ -1369,8 +1305,7 @@ open_root(void *edit_baton,
       dir->base_revision = base_revision;
       dir->relpath = "";
       dir->name = "";
-      dir->changed_props = apr_hash_make(dir->pool);
-      dir->removed_props = apr_hash_make(dir->pool);
+      dir->prop_changes = apr_hash_make(dir->pool);
       dir->url = apr_pstrdup(dir->pool, commit_ctx->txn_root_url);
 
       /* If we included our revprops in the POST, we need not
@@ -1384,21 +1319,8 @@ open_root(void *edit_baton,
       if (!activity_str)
         SVN_ERR(svn_ra_serf__v1_get_activity_collection(
                                     &activity_str,
-                                    commit_ctx->session->conns[0],
-                                    commit_ctx->pool, scratch_pool));
-
-      /* Cache the result. */
-      if (activity_str)
-        {
-          commit_ctx->session->activity_collection_url =
-            apr_pstrdup(commit_ctx->session->pool, activity_str);
-        }
-      else
-        {
-          return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
-                                  _("The OPTIONS response did not include the "
-                                    "requested activity-collection-set value"));
-        }
+                                    commit_ctx->session,
+                                    scratch_pool, scratch_pool));
 
       commit_ctx->activity_url = svn_path_url_add_component2(
                                     activity_str,
@@ -1406,12 +1328,10 @@ open_root(void *edit_baton,
                                     commit_ctx->pool);
 
       /* Create our activity URL now on the server. */
-      handler = svn_ra_serf__create_handler(scratch_pool);
+      handler = svn_ra_serf__create_handler(commit_ctx->session, scratch_pool);
 
       handler->method = "MKACTIVITY";
       handler->path = commit_ctx->activity_url;
-      handler->conn = commit_ctx->session->conns[0];
-      handler->session = commit_ctx->session;
 
       handler->response_handler = svn_ra_serf__expect_empty_body;
       handler->response_baton = handler;
@@ -1423,8 +1343,7 @@ open_root(void *edit_baton,
 
       /* Now go fetch our VCC and baseline so we can do a CHECKOUT. */
       SVN_ERR(svn_ra_serf__discover_vcc(&(commit_ctx->vcc_url),
-                                        commit_ctx->session,
-                                        commit_ctx->conn, commit_ctx->pool));
+                                        commit_ctx->session, scratch_pool));
 
 
       /* Build our directory baton. */
@@ -1434,8 +1353,7 @@ open_root(void *edit_baton,
       dir->base_revision = base_revision;
       dir->relpath = "";
       dir->name = "";
-      dir->changed_props = apr_hash_make(dir->pool);
-      dir->removed_props = apr_hash_make(dir->pool);
+      dir->prop_changes = apr_hash_make(dir->pool);
 
       SVN_ERR(get_version_url(&dir->url, dir->commit_ctx->session,
                               dir->relpath,
@@ -1458,35 +1376,22 @@ open_root(void *edit_baton,
       proppatch_ctx->pool = scratch_pool;
       proppatch_ctx->commit_ctx = NULL; /* No lock info */
       proppatch_ctx->path = proppatch_target;
-      proppatch_ctx->changed_props = apr_hash_make(proppatch_ctx->pool);
-      proppatch_ctx->removed_props = apr_hash_make(proppatch_ctx->pool);
+      proppatch_ctx->prop_changes = apr_hash_make(proppatch_ctx->pool);
       proppatch_ctx->base_revision = SVN_INVALID_REVNUM;
 
       for (hi = apr_hash_first(scratch_pool, commit_ctx->revprop_table);
            hi;
            hi = apr_hash_next(hi))
         {
-          const char *name = apr_hash_this_key(hi);
-          svn_string_t *value = apr_hash_this_val(hi);
-          const char *ns;
+          svn_prop_t *prop = apr_palloc(scratch_pool, sizeof(*prop));
 
-          if (strncmp(name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0)
-            {
-              ns = SVN_DAV_PROP_NS_SVN;
-              name += sizeof(SVN_PROP_PREFIX) - 1;
-            }
-          else
-            {
-              ns = SVN_DAV_PROP_NS_CUSTOM;
-            }
+          prop->name = apr_hash_this_key(hi);
+          prop->value = apr_hash_this_val(hi);
 
-          svn_ra_serf__set_prop(proppatch_ctx->changed_props,
-                                proppatch_ctx->path,
-                                ns, name, value, scratch_pool);
+          svn_hash_sets(proppatch_ctx->prop_changes, prop->name, prop);
         }
 
       SVN_ERR(proppatch_resource(commit_ctx->session,
-                                 commit_ctx->conn,
                                  proppatch_ctx, scratch_pool));
     }
 
@@ -1530,9 +1435,7 @@ delete_entry(const char *path,
   delete_ctx->revision = revision;
   delete_ctx->commit_ctx = dir->commit_ctx;
 
-  handler = svn_ra_serf__create_handler(pool);
-  handler->session = dir->commit_ctx->session;
-  handler->conn = dir->commit_ctx->conn;
+  handler = svn_ra_serf__create_handler(dir->commit_ctx->session, pool);
 
   handler->response_handler = svn_ra_serf__expect_empty_body;
   handler->response_baton = handler;
@@ -1580,8 +1483,7 @@ add_directory(const char *path,
   dir->copy_path = apr_pstrdup(dir->pool, copyfrom_path);
   dir->relpath = apr_pstrdup(dir->pool, path);
   dir->name = svn_relpath_basename(dir->relpath, NULL);
-  dir->changed_props = apr_hash_make(dir->pool);
-  dir->removed_props = apr_hash_make(dir->pool);
+  dir->prop_changes = apr_hash_make(dir->pool);
 
   if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
     {
@@ -1601,9 +1503,7 @@ add_directory(const char *path,
                                dir->name, dir->pool);
     }
 
-  handler = svn_ra_serf__create_handler(dir->pool);
-  handler->conn = dir->commit_ctx->conn;
-  handler->session = dir->commit_ctx->session;
+  handler = svn_ra_serf__create_handler(dir->commit_ctx->session, dir->pool);
 
   handler->response_handler = svn_ra_serf__expect_empty_body;
   handler->response_baton = handler;
@@ -1628,10 +1528,8 @@ add_directory(const char *path,
                                    dir->copy_path);
         }
 
-      /* ### conn==NULL for session->conns[0]. same as commit->conn.  */
       SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                           dir->commit_ctx->session,
-                                          NULL /* conn */,
                                           uri.path, dir->copy_revision,
                                           dir_pool, dir_pool));
 
@@ -1673,8 +1571,7 @@ open_directory(const char *path,
   dir->base_revision = base_revision;
   dir->relpath = apr_pstrdup(dir->pool, path);
   dir->name = svn_relpath_basename(dir->relpath, NULL);
-  dir->changed_props = apr_hash_make(dir->pool);
-  dir->removed_props = apr_hash_make(dir->pool);
+  dir->prop_changes = apr_hash_make(dir->pool);
 
   if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
     {
@@ -1698,46 +1595,23 @@ static svn_error_t *
 change_dir_prop(void *dir_baton,
                 const char *name,
                 const svn_string_t *value,
-                apr_pool_t *pool)
+                apr_pool_t *scratch_pool)
 {
   dir_context_t *dir = dir_baton;
-  const char *ns;
-  const char *proppatch_target;
-
+  svn_prop_t *prop;
 
-  if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
-    {
-      proppatch_target = dir->url;
-    }
-  else
+  if (! USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
     {
       /* Ensure we have a checked out dir. */
-      SVN_ERR(checkout_dir(dir, pool /* scratch_pool */));
-
-      proppatch_target = dir->working_url;
+      SVN_ERR(checkout_dir(dir, scratch_pool));
     }
 
-  if (strncmp(name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0)
-    {
-      ns = SVN_DAV_PROP_NS_SVN;
-      name += sizeof(SVN_PROP_PREFIX) - 1;
-    }
-  else
-    {
-      ns = SVN_DAV_PROP_NS_CUSTOM;
-    }
+  prop = apr_palloc(dir->pool, sizeof(*prop));
 
-  if (value)
-    {
-      svn_ra_serf__set_prop(dir->changed_props, proppatch_target,
-                            ns, name, value, dir->pool);
-    }
-  else
-    {
-      value = svn_string_create_empty(pool);
-      svn_ra_serf__set_prop(dir->removed_props, proppatch_target,
-                            ns, name, value, dir->pool);
-    }
+  prop->name = apr_pstrdup(dir->pool, name);
+  prop->value = value ? svn_string_dup(value, dir->pool) : NULL;
+
+  svn_hash_sets(dir->prop_changes, prop->name, prop);
 
   return SVN_NO_ERROR;
 }
@@ -1753,17 +1627,15 @@ close_directory(void *dir_baton,
    */
 
   /* PROPPATCH our prop change and pass it along.  */
-  if (apr_hash_count(dir->changed_props) ||
-      apr_hash_count(dir->removed_props))
+  if (apr_hash_count(dir->prop_changes))
     {
       proppatch_context_t *proppatch_ctx;
 
       proppatch_ctx = apr_pcalloc(pool, sizeof(*proppatch_ctx));
       proppatch_ctx->pool = pool;
-      proppatch_ctx->commit_ctx = dir->commit_ctx;
+      proppatch_ctx->commit_ctx = NULL /* No lock tokens necessary */;
       proppatch_ctx->relpath = dir->relpath;
-      proppatch_ctx->changed_props = dir->changed_props;
-      proppatch_ctx->removed_props = dir->removed_props;
+      proppatch_ctx->prop_changes = dir->prop_changes;
       proppatch_ctx->base_revision = dir->base_revision;
 
       if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
@@ -1776,7 +1648,6 @@ close_directory(void *dir_baton,
         }
 
       SVN_ERR(proppatch_resource(dir->commit_ctx->session,
-                                 dir->commit_ctx->conn,
                                  proppatch_ctx, dir->pool));
     }
 
@@ -1809,8 +1680,7 @@ add_file(const char *path,
   new_file->base_revision = SVN_INVALID_REVNUM;
   new_file->copy_path = apr_pstrdup(new_file->pool, copy_path);
   new_file->copy_revision = copy_revision;
-  new_file->changed_props = apr_hash_make(new_file->pool);
-  new_file->removed_props = apr_hash_make(new_file->pool);
+  new_file->prop_changes = apr_hash_make(new_file->pool);
 
   /* Ensure that the file doesn't exist by doing a HEAD on the
      resource.  If we're using HTTP v2, we'll just look into the
@@ -1853,18 +1723,15 @@ add_file(const char *path,
       if (status)
         return svn_ra_serf__wrap_err(status, NULL);
 
-      /* ### conn==NULL for session->conns[0]. same as commit_ctx->conn.  */
       SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                           dir->commit_ctx->session,
-                                          NULL /* conn */,
                                           uri.path, copy_revision,
                                           scratch_pool, scratch_pool));
 
-      handler = svn_ra_serf__create_handler(scratch_pool);
+      handler = svn_ra_serf__create_handler(dir->commit_ctx->session,
+                                            scratch_pool);
       handler->method = "COPY";
       handler->path = req_url;
-      handler->conn = dir->commit_ctx->conn;
-      handler->session = dir->commit_ctx->session;
 
       handler->response_handler = svn_ra_serf__expect_empty_body;
       handler->response_baton = handler;
@@ -1883,15 +1750,15 @@ add_file(const char *path,
       svn_ra_serf__handler_t *handler;
       svn_error_t *err;
 
-      handler = svn_ra_serf__create_handler(scratch_pool);
-      handler->session = new_file->commit_ctx->session;
-      handler->conn = new_file->commit_ctx->conn;
+      handler = svn_ra_serf__create_handler(dir->commit_ctx->session,
+                                            scratch_pool);
       handler->method = "HEAD";
       handler->path = svn_path_url_add_component2(
                                         dir->commit_ctx->session->session_url.path,
                                         path, scratch_pool);
       handler->response_handler = svn_ra_serf__expect_empty_body;
       handler->response_baton = handler;
+      handler->no_dav_headers = TRUE; /* Read only operation outside txn */
 
       err = svn_ra_serf__context_run_one(handler, scratch_pool);
 
@@ -1933,8 +1800,7 @@ open_file(const char *path,
   new_file->name = svn_relpath_basename(new_file->relpath, NULL);
   new_file->added = FALSE;
   new_file->base_revision = base_revision;
-  new_file->changed_props = apr_hash_make(new_file->pool);
-  new_file->removed_props = apr_hash_make(new_file->pool);
+  new_file->prop_changes = apr_hash_make(new_file->pool);
 
   if (USING_HTTPV2_COMMIT_SUPPORT(parent->commit_ctx))
     {
@@ -2008,30 +1874,14 @@ change_file_prop(void *file_baton,
                  apr_pool_t *pool)
 {
   file_context_t *file = file_baton;
-  const char *ns;
+  svn_prop_t *prop;
 
-  if (strncmp(name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0)
-    {
-      ns = SVN_DAV_PROP_NS_SVN;
-      name += sizeof(SVN_PROP_PREFIX) - 1;
-    }
-  else
-    {
-      ns = SVN_DAV_PROP_NS_CUSTOM;
-    }
+  prop = apr_palloc(file->pool, sizeof(*prop));
 
-  if (value)
-    {
-      svn_ra_serf__set_prop(file->changed_props, file->url,
-                            ns, name, value, file->pool);
-    }
-  else
-    {
-      value = svn_string_create_empty(pool);
+  prop->name = apr_pstrdup(file->pool, name);
+  prop->value = value ? svn_string_dup(value, file->pool) : NULL;
 
-      svn_ra_serf__set_prop(file->removed_props, file->url,
-                            ns, name, value, file->pool);
-    }
+  svn_hash_sets(file->prop_changes, prop->name, prop);
 
   return SVN_NO_ERROR;
 }
@@ -2058,12 +1908,11 @@ close_file(void *file_baton,
       svn_ra_serf__handler_t *handler;
       int expected_result;
 
-      handler = svn_ra_serf__create_handler(scratch_pool);
+      handler = svn_ra_serf__create_handler(ctx->commit_ctx->session,
+                                            scratch_pool);
 
       handler->method = "PUT";
       handler->path = ctx->url;
-      handler->conn = ctx->commit_ctx->conn;
-      handler->session = ctx->commit_ctx->session;
 
       handler->response_handler = svn_ra_serf__expect_empty_body;
       handler->response_baton = handler;
@@ -2099,8 +1948,7 @@ close_file(void *file_baton,
     SVN_ERR(svn_io_file_close(ctx->svndiff, scratch_pool));
 
   /* If we had any prop changes, push them via PROPPATCH. */
-  if (apr_hash_count(ctx->changed_props) ||
-      apr_hash_count(ctx->removed_props))
+  if (apr_hash_count(ctx->prop_changes))
     {
       proppatch_context_t *proppatch;
 
@@ -2109,12 +1957,10 @@ close_file(void *file_baton,
       proppatch->relpath = ctx->relpath;
       proppatch->path = ctx->url;
       proppatch->commit_ctx = ctx->commit_ctx;
-      proppatch->changed_props = ctx->changed_props;
-      proppatch->removed_props = ctx->removed_props;
+      proppatch->prop_changes = ctx->prop_changes;
       proppatch->base_revision = ctx->base_revision;
 
       SVN_ERR(proppatch_resource(ctx->commit_ctx->session,
-                                 ctx->commit_ctx->conn,
                                  proppatch, scratch_pool));
     }
 
@@ -2133,7 +1979,6 @@ close_edit(void *edit_baton,
   /* MERGE our activity */
   SVN_ERR(svn_ra_serf__run_merge(&commit_info,
                                  ctx->session,
-                                 ctx->session->conns[0],
                                  merge_target,
                                  ctx->lock_tokens,
                                  ctx->keep_locks,
@@ -2148,12 +1993,10 @@ close_edit(void *edit_baton,
     {
       svn_ra_serf__handler_t *handler;
 
-      handler = svn_ra_serf__create_handler(pool);
+      handler = svn_ra_serf__create_handler(ctx->session, pool);
 
       handler->method = "DELETE";
       handler->path = ctx->activity_url;
-      handler->conn = ctx->conn;
-      handler->session = ctx->session;
 
       handler->response_handler = svn_ra_serf__expect_empty_body;
       handler->response_baton = handler;
@@ -2186,11 +2029,9 @@ abort_edit(void *edit_baton,
   serf_connection_reset(ctx->session->conns[0]->conn);
 
   /* DELETE our aborted activity */
-  handler = svn_ra_serf__create_handler(pool);
+  handler = svn_ra_serf__create_handler(ctx->session, pool);
 
   handler->method = "DELETE";
-  handler->conn = ctx->session->conns[0];
-  handler->session = ctx->session;
 
   handler->response_handler = svn_ra_serf__expect_empty_body;
   handler->response_baton = handler;
@@ -2243,7 +2084,6 @@ svn_ra_serf__get_commit_editor(svn_ra_se
   ctx->pool = pool;
 
   ctx->session = session;
-  ctx->conn = session->conns[0];
 
   ctx->revprop_table = svn_prop_hash_dup(revprop_table, pool);
 
@@ -2311,9 +2151,9 @@ svn_ra_serf__change_rev_prop(svn_ra_sess
   svn_ra_serf__session_t *session = ra_session->priv;
   proppatch_context_t *proppatch_ctx;
   const char *proppatch_target;
-  const char *ns;
   const svn_string_t *tmp_old_value;
   svn_boolean_t atomic_capable = FALSE;
+  svn_prop_t *prop;
   svn_error_t *err;
 
   if (old_value_p || !value)
@@ -2356,70 +2196,39 @@ svn_ra_serf__change_rev_prop(svn_ra_sess
     {
       const char *vcc_url;
 
-      SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session,
-                                        session->conns[0], pool));
+      SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, pool));
 
       SVN_ERR(svn_ra_serf__fetch_dav_prop(&proppatch_target,
-                                          session->conns[0], vcc_url, rev,
-                                          "href",
+                                          session, vcc_url, rev, "href",
                                           pool, pool));
     }
 
-  if (strncmp(name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0)
-    {
-      ns = SVN_DAV_PROP_NS_SVN;
-      name += sizeof(SVN_PROP_PREFIX) - 1;
-    }
-  else
-    {
-      ns = SVN_DAV_PROP_NS_CUSTOM;
-    }
-
   /* PROPPATCH our log message and pass it along.  */
   proppatch_ctx = apr_pcalloc(pool, sizeof(*proppatch_ctx));
   proppatch_ctx->pool = pool;
   proppatch_ctx->commit_ctx = NULL; /* No lock headers */
   proppatch_ctx->path = proppatch_target;
-  proppatch_ctx->changed_props = apr_hash_make(pool);
-  proppatch_ctx->removed_props = apr_hash_make(pool);
-  if (old_value_p)
-    {
-      proppatch_ctx->previous_changed_props = apr_hash_make(pool);
-      proppatch_ctx->previous_removed_props = apr_hash_make(pool);
-    }
+  proppatch_ctx->prop_changes = apr_hash_make(pool);
   proppatch_ctx->base_revision = SVN_INVALID_REVNUM;
 
-  if (old_value_p && *old_value_p)
-    {
-      svn_ra_serf__set_prop(proppatch_ctx->previous_changed_props,
-                            proppatch_ctx->path,
-                            ns, name, *old_value_p, pool);
-    }
-  else if (old_value_p)
+  if (old_value_p)
     {
-      svn_string_t *dummy_value = svn_string_create_empty(pool);
+      prop = apr_palloc(pool, sizeof (*prop));
 
-      svn_ra_serf__set_prop(proppatch_ctx->previous_removed_props,
-                            proppatch_ctx->path,
-                            ns, name, dummy_value, pool);
-    }
+      prop->name = name;
+      prop->value = *old_value_p;
 
-  if (value)
-    {
-      svn_ra_serf__set_prop(proppatch_ctx->changed_props, proppatch_ctx->path,
-                            ns, name, value, pool);
+      proppatch_ctx->old_props = apr_hash_make(pool);
+      svn_hash_sets(proppatch_ctx->old_props, prop->name, prop);
     }
-  else
-    {
-      value = svn_string_create_empty(pool);
 
-      svn_ra_serf__set_prop(proppatch_ctx->removed_props, proppatch_ctx->path,
-                            ns, name, value, pool);
-    }
+  prop = apr_palloc(pool, sizeof (*prop));
+
+  prop->name = name;
+  prop->value = value;
+  svn_hash_sets(proppatch_ctx->prop_changes, prop->name, prop);
 
-  err = proppatch_resource(session,
-                           session->conns[0],
-                            proppatch_ctx, pool);
+  err = proppatch_resource(session, proppatch_ctx, pool);
 
   /* Use specific error code for old property value mismatch.
      Use loop to provide the right result with tracing */

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_deleted_rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_deleted_rev.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_deleted_rev.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_deleted_rev.c Tue Jan 27 23:27:44 2015
@@ -92,7 +92,8 @@ static svn_error_t *
 create_getdrev_body(serf_bucket_t **body_bkt,
                     void *baton,
                     serf_bucket_alloc_t *alloc,
-                    apr_pool_t *pool)
+                    apr_pool_t *pool /* request pool */,
+                    apr_pool_t *scratch_pool)
 {
   serf_bucket_t *buckets;
   drev_context_t *drev_ctx = baton;
@@ -148,23 +149,20 @@ svn_ra_serf__get_deleted_rev(svn_ra_sess
   drev_ctx->revision_deleted = revision_deleted;
 
   SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
-                                      ras, NULL /* conn */,
-                                      NULL /* url */, peg_revision,
+                                      ras, NULL /* url */, peg_revision,
                                       pool, pool));
 
   xmlctx = svn_ra_serf__xml_context_create(getdrev_ttable,
                                            NULL, getdrev_closed, NULL,
                                            drev_ctx,
                                            pool);
-  handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, pool);
+  handler = svn_ra_serf__create_expat_handler(ras, xmlctx, NULL, pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
   handler->body_type = "text/xml";
   handler->body_delegate = create_getdrev_body;
   handler->body_delegate_baton = drev_ctx;
-  handler->conn = ras->conns[0];
-  handler->session = ras;
 
   err = svn_ra_serf__context_run_one(handler, pool);
 

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_file.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_file.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_file.c Tue Jan 27 23:27:44 2015
@@ -83,7 +83,8 @@ typedef struct stream_ctx_t {
 static svn_error_t *
 headers_fetch(serf_bucket_t *headers,
               void *baton,
-              apr_pool_t *pool)
+              apr_pool_t *pool /* request pool */,
+              apr_pool_t *scratch_pool)
 {
   stream_ctx_t *fetch_ctx = baton;
 
@@ -143,12 +144,10 @@ cancel_fetch(serf_request_t *request,
 static svn_error_t *
 try_get_wc_contents(svn_boolean_t *found_p,
                     svn_ra_serf__session_t *session,
-                    apr_hash_t *props,
+                    const char *sha1_checksum_prop,
                     svn_stream_t *dst_stream,
                     apr_pool_t *pool)
 {
-  apr_hash_t *svn_props;
-  const char *sha1_checksum_prop;
   svn_checksum_t *checksum;
   svn_stream_t *wc_stream;
   svn_error_t *err;
@@ -156,24 +155,10 @@ try_get_wc_contents(svn_boolean_t *found
   /* No contents found by default. */
   *found_p = FALSE;
 
-  if (!session->wc_callbacks->get_wc_contents)
-    {
-      /* No callback, nothing to do. */
-      return SVN_NO_ERROR;
-    }
-
-
-  svn_props = svn_hash_gets(props, SVN_DAV_PROP_NS_DAV);
-  if (!svn_props)
-    {
-      /* No properties -- therefore no checksum property -- in response. */
-      return SVN_NO_ERROR;
-    }
-
-  sha1_checksum_prop = svn_prop_get_value(svn_props, "sha1-checksum");
-  if (sha1_checksum_prop == NULL)
+  if (!session->wc_callbacks->get_wc_contents
+      || sha1_checksum_prop == NULL)
     {
-      /* No checksum property in response. */
+      /* Nothing to do. */
       return SVN_NO_ERROR;
     }
 
@@ -279,6 +264,55 @@ handle_stream(serf_request_t *request,
   /* not reached */
 }
 
+/* Baton for get_file_prop_cb */
+struct file_prop_baton_t
+{
+  apr_pool_t *result_pool;
+  svn_node_kind_t kind;
+  apr_hash_t *props;
+  const char *sha1_checksum;
+};
+
+/* Implements svn_ra_serf__prop_func_t for svn_ra_serf__get_file */
+static svn_error_t *
+get_file_prop_cb(void *baton,
+                 const char *path,
+                 const char *ns,
+                 const char *name,
+                 const svn_string_t *value,
+                 apr_pool_t *scratch_pool)
+{
+  struct file_prop_baton_t *fb = baton;
+  const char *svn_name;
+
+  if (strcmp(ns, "DAV:") == 0 && strcmp(name, "resourcetype") == 0)
+    {
+      const char *val = value->data;
+
+      if (strcmp(val, "collection") == 0)
+        fb->kind = svn_node_dir;
+      else
+        fb->kind = svn_node_file;
+
+      return SVN_NO_ERROR;
+    }
+  else if (strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0
+           && strcmp(name, "sha1-checksum") == 0)
+    {
+      fb->sha1_checksum = apr_pstrdup(fb->result_pool, value->data);
+    }
+
+  if (!fb->props)
+    return SVN_NO_ERROR;
+
+  svn_name = svn_ra_serf__svnname_from_wirename(ns, name, fb->result_pool);
+  if (svn_name)
+    {
+      svn_hash_sets(fb->props, svn_name,
+                    svn_string_dup(value, fb->result_pool));
+    }
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_ra_serf__get_file(svn_ra_session_t *ra_session,
@@ -290,14 +324,10 @@ svn_ra_serf__get_file(svn_ra_session_t *
                       apr_pool_t *pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
-  svn_ra_serf__connection_t *conn;
   const char *fetch_url;
-  apr_hash_t *fetch_props;
-  svn_node_kind_t res_kind;
   const svn_ra_serf__dav_props_t *which_props;
-
-  /* What connection should we go on? */
-  conn = session->conns[session->cur_conn];
+  svn_ra_serf__handler_t *propfind_handler;
+  struct file_prop_baton_t fb;
 
   /* Fetch properties. */
 
@@ -311,7 +341,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
   if (SVN_IS_VALID_REVNUM(revision) || fetched_rev)
     {
       SVN_ERR(svn_ra_serf__get_stable_url(&fetch_url, fetched_rev,
-                                          session, conn,
+                                          session,
                                           fetch_url, revision,
                                           pool, pool));
       revision = SVN_INVALID_REVNUM;
@@ -320,44 +350,39 @@ svn_ra_serf__get_file(svn_ra_session_t *
   SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));
 
   if (props)
-    {
       which_props = all_props;
-    }
   else if (stream && session->wc_callbacks->get_wc_contents)
-    {
       which_props = type_and_checksum_props;
-    }
   else
-    {
       which_props = check_path_props;
-    }
 
-  SVN_ERR(svn_ra_serf__fetch_node_props(&fetch_props, conn, fetch_url,
-                                        SVN_INVALID_REVNUM,
-                                        which_props,
-                                        pool, pool));
+  fb.result_pool = pool;
+  fb.props = props ? apr_hash_make(pool) : NULL;
+  fb.kind = svn_node_unknown;
+  fb.sha1_checksum = NULL;
+
+  SVN_ERR(svn_ra_serf__create_propfind_handler(&propfind_handler, session,
+                                               fetch_url, SVN_INVALID_REVNUM,
+                                               "0", which_props,
+                                               get_file_prop_cb, &fb,
+                                               pool));
+
+  SVN_ERR(svn_ra_serf__context_run_one(propfind_handler, pool));
 
   /* Verify that resource type is not collection. */
-  SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, fetch_props));
-  if (res_kind != svn_node_file)
+  if (fb.kind != svn_node_file)
     {
       return svn_error_create(SVN_ERR_FS_NOT_FILE, NULL,
                               _("Can't get text contents of a directory"));
     }
 
-  /* TODO Filter out all of our props into a usable format. */
   if (props)
-    {
-      /* ### flatten_props() does not copy PROPVALUE, but fetch_node_props()
-         ### put them into POOL, so we're okay.  */
-      SVN_ERR(svn_ra_serf__flatten_props(props, fetch_props,
-                                         pool, pool));
-    }
+    *props = fb.props;
 
   if (stream)
     {
       svn_boolean_t found;
-      SVN_ERR(try_get_wc_contents(&found, session, fetch_props, stream, pool));
+      SVN_ERR(try_get_wc_contents(&found, session, fb.sha1_checksum, stream, pool));
 
       /* No contents found in the WC, let's fetch from server. */
       if (!found)
@@ -370,12 +395,13 @@ svn_ra_serf__get_file(svn_ra_session_t *
           stream_ctx->result_stream = stream;
           stream_ctx->using_compression = session->using_compression;
 
-          handler = svn_ra_serf__create_handler(pool);
+          handler = svn_ra_serf__create_handler(session, pool);
+
+          /* What connection should we go on? */
+          handler->conn = session->conns[session->cur_conn];
 
           handler->method = "GET";
           handler->path = fetch_url;
-          handler->conn = conn;
-          handler->session = session;
 
           handler->custom_accept_encoding = TRUE;
           handler->no_dav_headers = TRUE;

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_lock.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_lock.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/get_lock.c Tue Jan 27 23:27:44 2015
@@ -232,7 +232,8 @@ static svn_error_t *
 create_getlock_body(serf_bucket_t **body_bkt,
                     void *baton,
                     serf_bucket_alloc_t *alloc,
-                    apr_pool_t *pool)
+                    apr_pool_t *pool /* request pool */,
+                    apr_pool_t *scratch_pool)
 {
   serf_bucket_t *buckets;
 
@@ -255,7 +256,8 @@ create_getlock_body(serf_bucket_t **body
 static svn_error_t*
 setup_getlock_headers(serf_bucket_t *headers,
                       void *baton,
-                      apr_pool_t *pool)
+                      apr_pool_t *pool /* request pool */,
+                      apr_pool_t *scratch_pool)
 {
   serf_bucket_headers_setn(headers, "Depth", "0");
 
@@ -289,14 +291,13 @@ svn_ra_serf__get_lock(svn_ra_session_t *
                                            NULL, locks_closed, NULL,
                                            lock_ctx,
                                            scratch_pool);
-  handler = svn_ra_serf__create_expat_handler(xmlctx, locks_expected_status,
+  handler = svn_ra_serf__create_expat_handler(session, xmlctx,
+                                              locks_expected_status,
                                               scratch_pool);
 
   handler->method = "PROPFIND";
   handler->path = req_url;
   handler->body_type = "text/xml";
-  handler->conn = session->conns[0];
-  handler->session = session;
 
   handler->body_delegate = create_getlock_body;
   handler->body_delegate_baton = lock_ctx;
@@ -304,6 +305,8 @@ svn_ra_serf__get_lock(svn_ra_session_t *
   handler->header_delegate = setup_getlock_headers;
   handler->header_delegate_baton = lock_ctx;
 
+  handler->no_dav_headers = TRUE;
+
   lock_ctx->inner_handler = handler->response_handler;
   lock_ctx->inner_baton = handler->response_baton;
   handler->response_handler = handle_lock;

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/getdate.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/getdate.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/getdate.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/getdate.c Tue Jan 27 23:27:44 2015
@@ -100,7 +100,8 @@ static svn_error_t *
 create_getdate_body(serf_bucket_t **body_bkt,
                     void *baton,
                     serf_bucket_alloc_t *alloc,
-                    apr_pool_t *pool)
+                    apr_pool_t *pool /* request pool */,
+                    apr_pool_t *scratch_pool)
 {
   serf_bucket_t *buckets;
   date_context_t *date_ctx = baton;
@@ -139,19 +140,17 @@ svn_ra_serf__get_dated_revision(svn_ra_s
   date_ctx->time = tm;
   date_ctx->revision = revision;
 
-  SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool));
+  SVN_ERR(svn_ra_serf__report_resource(&report_target, session, pool));
 
   xmlctx = svn_ra_serf__xml_context_create(date_ttable,
                                            NULL, date_closed, NULL,
                                            date_ctx,
                                            pool);
-  handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, pool);
+  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool);
 
   handler->method = "REPORT";
   handler->path = report_target;
   handler->body_type = "text/xml";
-  handler->conn = session->conns[0];
-  handler->session = session;
 
   handler->body_delegate = create_getdate_body;
   handler->body_delegate_baton = date_ctx;