You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2012/06/14 12:38:50 UTC

svn commit: r1350182 - in /subversion/trunk/subversion/libsvn_ra_serf: property.c ra_serf.h replay.c update.c

Author: gstein
Date: Thu Jun 14 10:38:49 2012
New Revision: 1350182

URL: http://svn.apache.org/viewvc?rev=1350182&view=rev
Log:
Convert PROPFIND response processing over to the v2 XML process.

The update/replay mechanisms that run their own PROPFIND have been
rejiggered to get a handler_t back from deliver_props() (rather than
an opaque propfind_context_t), which they must then run.

* subversion/libsvn_ra_serf/ra_serf.h:
  (svn_ra_serf__propfind_context_t): unused. removed.
  (svn_ra_serf__propfind_is_done): removed. use HANDLER->DONE.
  (svn_ra_serf__deliver_props): return a handler
  (svn_ra_serf__wait_for_props): wait on the handler instead of the
    old prop ctx. drop the session param.

* subversion/libsvn_ra_serf/property.c:
  (NONE): renamed to ...
  (INITIAL): ... this.
  (MULTISTATUS, HREF, PROPSTAT, COLLECTION, HREF_VALUE): new states
  (prop_info_t): removed. unused.
  (svn_ra_serf__propfind_context_t): remove CURRENT_PATH, DONE, and
    PARSER_CTX. add local typedef.
  (propfind_ttable): new transition table for PROPFIND responses.
  (propfind_open): new callback to deal with wildcard property tags
  (propfind_closed): new callback for processing the response
  (push_state, start_propfind, end_propfind, cdata_propfind): disabled
    from compilation, but remaining for a clean diff.
  (svn_ra_serf__deliver_props): change param to return a handler.
    construct an xmlctx, set it up, and return it. strip out the old
    xml parser. do not create a serf request for the handler, as the
    caller might use run_one() (which does it).
  (svn_ra_serf__propfind_is_done): removed
  (svn_ra_serf__wait_for_props): take a handler rather than the old
    opaque context. drop the session param, as we don't need it.
    adjust the code to use run_one() and how it accesses the result
    information.
  (svn_ra_serf__retrieve_props): adjust for getting a handler rather
    than the old prop ctx.

* subversion/libsvn_ra_serf/replay.c:
  (replay_context_t): store a handler for the propfind
  (start_replay): drop propfind_is_done() in favor of HANDLER->DONE
  (svn_ra_serf__replay_range): switch to getting a handler from
    deliver_props(), and create a serf request for it.

* subversion/libsvn_ra_serf/update.c:
  (report_dir_t): switch to storing a handler for the PROPFIND
  (report_info_t): switch to storing a handler for the PROPFIND
  (report_context_t): note that DONE_PROPFINDS will contain handler
    references rather than the old opaque propfind contexts
  (fetch_file): adjust for getting a handler from deliver_props() and
    start a serf request for it.
  (end_report): adjust for a handler from deliver_props() and start a
    serf request for it.
  (finish_report): we will now find handlers in done_list->data, and
    we can examine the handler's DONE flag rather than using the old
    propfind_is_done() function

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/property.c
    subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
    subversion/trunk/subversion/libsvn_ra_serf/replay.c
    subversion/trunk/subversion/libsvn_ra_serf/update.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/property.c?rev=1350182&r1=1350181&r2=1350182&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/property.c Thu Jun 14 10:38:49 2012
@@ -41,28 +41,22 @@
 
 /* Our current parsing state we're in for the PROPFIND response. */
 typedef enum prop_state_e {
-  NONE = 0,
+  INITIAL = 0,
+  MULTISTATUS,
   RESPONSE,
+  HREF,
+  PROPSTAT,
   PROP,
-  PROPVAL
+  PROPVAL,
+  COLLECTION,
+  HREF_VALUE
 } prop_state_e;
 
-typedef struct prop_info_t {
-  apr_pool_t *pool;
-
-  /* Current ns, attribute name, and value of the property we're parsing */
-  const char *ns;
-  const char *name;
-  svn_stringbuf_t *value;
-
-  const char *encoding;
-
-} prop_info_t;
 
 /*
  * This structure represents a pending PROPFIND response.
  */
-struct svn_ra_serf__propfind_context_t {
+typedef struct svn_ra_serf__propfind_context_t {
   /* pool to issue allocations from */
   apr_pool_t *pool;
 
@@ -92,24 +86,170 @@ struct svn_ra_serf__propfind_context_t {
    */
   apr_hash_t *ret_props;
 
-  /* If we're dealing with a Depth: 1 response,
-   * we may be dealing with multiple paths.
-   */
-  const char *current_path;
-
-  /* Are we done issuing the PROPFIND? */
-  svn_boolean_t done;
-
-  /* Context from XML stream */
-  svn_ra_serf__xml_parser_t *parser_ctx;
-
   /* If not-NULL, add us to this list when we're done. */
   svn_ra_serf__list_t **done_list;
 
   svn_ra_serf__list_t done_item;
+
+} svn_ra_serf__propfind_context_t;
+
+
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t propfind_ttable[] = {
+  { INITIAL, D_, "multistatus", MULTISTATUS,
+    FALSE, { NULL }, TRUE },
+
+  { MULTISTATUS, D_, "response", RESPONSE,
+    FALSE, { NULL }, FALSE },
+
+  { RESPONSE, D_, "href", HREF,
+    TRUE, { NULL }, TRUE },
+
+  { RESPONSE, D_, "propstat", PROPSTAT,
+    FALSE, { NULL }, FALSE },
+
+  { PROPSTAT, D_, "prop", PROP,
+    FALSE, { NULL }, FALSE },
+
+  { PROP, "*", "*", PROPVAL,
+    TRUE, { "?V:encoding", NULL }, TRUE },
+
+  { PROPVAL, D_, "collection", COLLECTION,
+    FALSE, { NULL }, TRUE },
+
+  { PROPVAL, D_, "href", HREF_VALUE,
+    TRUE, { NULL }, TRUE },
+
+  { 0 }
 };
 
 
+/* Conforms to svn_ra_serf__xml_opened_t  */
+static svn_error_t *
+propfind_opened(svn_ra_serf__xml_estate_t *xes,
+                void *baton,
+                int entered_state,
+                const svn_ra_serf__dav_props_t *tag,
+                apr_pool_t *scratch_pool)
+{
+  if (entered_state == PROPVAL)
+    {
+      svn_ra_serf__xml_note(xes, PROPVAL, "ns", tag->namespace);
+      svn_ra_serf__xml_note(xes, PROPVAL, "name", tag->name);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+/* Conforms to svn_ra_serf__xml_closed_t  */
+static svn_error_t *
+propfind_closed(svn_ra_serf__xml_estate_t *xes,
+                void *baton,
+                int leaving_state,
+                const svn_string_t *cdata,
+                apr_hash_t *attrs,
+                apr_pool_t *scratch_pool)
+{
+  svn_ra_serf__propfind_context_t *ctx = baton;
+
+  if (leaving_state == MULTISTATUS)
+    {
+      /* We've gathered all the data from the reponse. Add this item
+         onto the "done list". External callers will then know this
+         request has been completed (tho stray response bytes may still
+         arrive).  */
+      if (ctx->done_list)
+        {
+          ctx->done_item.data = ctx->handler;
+          ctx->done_item.next = *ctx->done_list;
+          *ctx->done_list = &ctx->done_item;
+        }
+    }
+  else if (leaving_state == HREF)
+    {
+      const char *path;
+      const svn_string_t *val_str;
+
+      if (strcmp(ctx->depth, "1") == 0)
+        path = svn_urlpath__canonicalize(cdata->data, scratch_pool);
+      else
+        path = ctx->path;
+
+      svn_ra_serf__xml_note(xes, RESPONSE, "path", path);
+
+      /* Copy the value into the right pool, then save the HREF.  */
+      val_str = svn_string_dup(cdata, ctx->pool);
+      svn_ra_serf__set_ver_prop(ctx->ret_props,
+                                path, ctx->rev, D_, "href", val_str,
+                                ctx->pool);
+    }
+  else if (leaving_state == COLLECTION)
+    {
+      svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", "collection");
+    }
+  else if (leaving_state == HREF_VALUE)
+    {
+      svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", cdata->data);
+    }
+  else
+    {
+      const char *encoding = apr_hash_get(attrs, "V:encoding",
+                                          APR_HASH_KEY_STRING);
+      const svn_string_t *val_str;
+      apr_hash_t *gathered;
+      const char *path;
+      const char *ns;
+      const char *name;
+      const char *altvalue;
+
+      SVN_ERR_ASSERT(leaving_state == PROPVAL);
+
+      if (encoding)
+        {
+          if (strcmp(encoding, "base64") != 0)
+            return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
+                                     NULL,
+                                     _("Got unrecognized encoding '%s'"),
+                                     encoding);
+
+          /* Decode into the right pool.  */
+          val_str = svn_base64_decode_string(cdata, ctx->pool);
+        }
+      else
+        {
+          /* Copy into the right pool.  */
+          val_str = svn_string_dup(cdata, ctx->pool);
+        }
+
+      /* The current path sits on the RESPONSE state. Gather up all the
+         state from this PROPVAL to the (grandparent) RESPONSE state,
+         and grab the path from there.  */
+      gathered = svn_ra_serf__xml_gather_since(xes, RESPONSE);
+
+      /* These will be dup'd into CTX->POOL, as necessary.  */
+      path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
+      if (path == NULL)
+        path = ctx->path;
+
+      ns = apr_hash_get(attrs, "ns", APR_HASH_KEY_STRING);
+      name = apr_pstrdup(ctx->pool,
+                         apr_hash_get(attrs, "name", APR_HASH_KEY_STRING));
+
+      altvalue = apr_hash_get(attrs, "altvalue", APR_HASH_KEY_STRING);
+      if (altvalue != NULL)
+        val_str = svn_string_create(altvalue, ctx->pool);
+
+      svn_ra_serf__set_ver_prop(ctx->ret_props,
+                                path, ctx->rev, ns, name, val_str,
+                                ctx->pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 const svn_string_t *
 svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
                                  const char *path,
@@ -226,6 +366,9 @@ svn_ra_serf__set_prop(apr_hash_t *props,
                             val, pool);
 }
 
+
+#if 0
+
 static prop_info_t *
 push_state(svn_ra_serf__xml_parser_t *parser,
            svn_ra_serf__propfind_context_t *propfind,
@@ -409,6 +552,9 @@ cdata_propfind(svn_ra_serf__xml_parser_t
   return SVN_NO_ERROR;
 }
 
+#endif
+
+
 static svn_error_t *
 setup_propfind_headers(serf_bucket_t *headers,
                         void *setup_baton,
@@ -511,7 +657,7 @@ create_propfind_body(serf_bucket_t **bkt
 
 
 svn_error_t *
-svn_ra_serf__deliver_props(svn_ra_serf__propfind_context_t **prop_ctx,
+svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
                            apr_hash_t *ret_props,
                            svn_ra_serf__session_t *sess,
                            svn_ra_serf__connection_t *conn,
@@ -524,7 +670,7 @@ svn_ra_serf__deliver_props(svn_ra_serf__
 {
   svn_ra_serf__propfind_context_t *new_prop_ctx;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
 
   new_prop_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx));
 
@@ -533,7 +679,6 @@ svn_ra_serf__deliver_props(svn_ra_serf__
   new_prop_ctx->find_props = find_props;
   new_prop_ctx->ret_props = ret_props;
   new_prop_ctx->depth = depth;
-  new_prop_ctx->done = FALSE;
   new_prop_ctx->sess = sess;
   new_prop_ctx->conn = conn;
   new_prop_ctx->rev = rev;
@@ -548,9 +693,14 @@ svn_ra_serf__deliver_props(svn_ra_serf__
       new_prop_ctx->label = NULL;
     }
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(propfind_ttable,
+                                           propfind_opened,
+                                           propfind_closed,
+                                           NULL,
+                                           new_prop_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
-  handler->handler_pool = pool;
   handler->method = "PROPFIND";
   handler->path = path;
   handler->body_delegate = create_propfind_body;
@@ -564,51 +714,28 @@ svn_ra_serf__deliver_props(svn_ra_serf__
 
   new_prop_ctx->handler = handler;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx->parser_ctx));
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = new_prop_ctx;
-  parser_ctx->start = start_propfind;
-  parser_ctx->end = end_propfind;
-  parser_ctx->cdata = cdata_propfind;
-  parser_ctx->done = &new_prop_ctx->done;
-  parser_ctx->done_list = new_prop_ctx->done_list;
-  parser_ctx->done_item = &new_prop_ctx->done_item;
-
-  new_prop_ctx->parser_ctx = parser_ctx;
-
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
-  /* create request */
-  svn_ra_serf__request_create(new_prop_ctx->handler);
-
-  *prop_ctx = new_prop_ctx;
+  *propfind_handler = handler;
 
   return SVN_NO_ERROR;
 }
 
-svn_boolean_t
-svn_ra_serf__propfind_is_done(svn_ra_serf__propfind_context_t *ctx)
-{
-  return ctx->done;
-}
-
 
 /*
  * This helper function will block until the PROP_CTX indicates that is done
  * or another error is returned.
  */
 svn_error_t *
-svn_ra_serf__wait_for_props(svn_ra_serf__propfind_context_t *prop_ctx,
-                            svn_ra_serf__session_t *sess,
-                            apr_pool_t *pool)
+svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
+                            apr_pool_t *scratch_pool)
 {
-  svn_error_t *err, *err2;
+  svn_error_t *err;
+  svn_error_t *err2;
 
-  err = svn_ra_serf__context_run_wait(&prop_ctx->done, sess, pool);
+  err = svn_ra_serf__context_run_one(handler, scratch_pool);
 
-  err2 = svn_ra_serf__error_on_status(prop_ctx->handler->sline.code,
-                                      prop_ctx->path, NULL);
+  err2 = svn_ra_serf__error_on_status(handler->sline.code,
+                                      handler->path,
+                                      NULL);
   if (err2)
     {
       svn_error_clear(err);
@@ -632,13 +759,13 @@ svn_ra_serf__retrieve_props(apr_hash_t *
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__propfind_context_t *prop_ctx;
+  svn_ra_serf__handler_t *handler;
 
   *results = apr_hash_make(result_pool);
 
-  SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, *results, sess, conn, url,
+  SVN_ERR(svn_ra_serf__deliver_props(&handler, *results, sess, conn, url,
                                      rev, depth, props, NULL, result_pool));
-  SVN_ERR(svn_ra_serf__wait_for_props(prop_ctx, sess, result_pool));
+  SVN_ERR(svn_ra_serf__wait_for_props(handler, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=1350182&r1=1350181&r2=1350182&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Thu Jun 14 10:38:49 2012
@@ -1027,16 +1027,6 @@ svn_ra_serf__expand_ns(svn_ra_serf__dav_
 
 /** PROPFIND-related functions **/
 
-/* Opaque structure representing PROPFINDs. */
-typedef struct svn_ra_serf__propfind_context_t svn_ra_serf__propfind_context_t;
-
-/*
- * Returns a flag representing whether the PROPFIND @a ctx is completed.
- */
-svn_boolean_t
-svn_ra_serf__propfind_is_done(svn_ra_serf__propfind_context_t *ctx);
-
-
 /*
  * This function will deliver a PROP_CTX PROPFIND request in the SESS
  * serf context for the properties listed in LOOKUP_PROPS at URL for
@@ -1046,7 +1036,7 @@ svn_ra_serf__propfind_is_done(svn_ra_ser
  * expected to call svn_ra_serf__wait_for_props().
  */
 svn_error_t *
-svn_ra_serf__deliver_props(svn_ra_serf__propfind_context_t **prop_ctx,
+svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
                            apr_hash_t *prop_vals,
                            svn_ra_serf__session_t *sess,
                            svn_ra_serf__connection_t *conn,
@@ -1058,13 +1048,12 @@ svn_ra_serf__deliver_props(svn_ra_serf__
                            apr_pool_t *pool);
 
 /*
- * This helper function will block until the PROP_CTX indicates that is done
- * or another error is returned.
+ * This helper function will block until PROPFIND_HANDLER indicates that is
+ * done or another error is returned.
  */
 svn_error_t *
-svn_ra_serf__wait_for_props(svn_ra_serf__propfind_context_t *prop_ctx,
-                            svn_ra_serf__session_t *sess,
-                            apr_pool_t *pool);
+svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
+                            apr_pool_t *scratch_pool);
 
 /* This is a blocking version of deliver_props.
 

Modified: subversion/trunk/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/replay.c?rev=1350182&r1=1350181&r2=1350182&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/replay.c Thu Jun 14 10:38:49 2012
@@ -129,7 +129,7 @@ typedef struct replay_context_t {
   svn_ra_serf__xml_parser_t *parser_ctx;
 
   /* The propfind for the revision properties of the current revision */
-  svn_ra_serf__propfind_context_t *prop_ctx;
+  svn_ra_serf__handler_t *propfind_handler;
 
 } replay_context_t;
 
@@ -188,8 +188,7 @@ start_replay(svn_ra_serf__xml_parser_t *
       push_state(parser, ctx, REPORT);
 
       /* Before we can continue, we need the revision properties. */
-      SVN_ERR_ASSERT(!ctx->prop_ctx
-                     || svn_ra_serf__propfind_is_done(ctx->prop_ctx));
+      SVN_ERR_ASSERT(!ctx->propfind_handler || ctx->propfind_handler->done);
 
       /* Create a pool for the commit editor. */
       ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
@@ -781,7 +780,7 @@ svn_ra_serf__replay_range(svn_ra_session
               replay_ctx->revprop_rev = rev;
             }
 
-          SVN_ERR(svn_ra_serf__deliver_props(&replay_ctx->prop_ctx,
+          SVN_ERR(svn_ra_serf__deliver_props(&replay_ctx->propfind_handler,
                                              replay_ctx->revs_props, session,
                                              session->conns[0],
                                              replay_ctx->revprop_target,
@@ -790,6 +789,9 @@ svn_ra_serf__replay_range(svn_ra_session
                                              NULL,
                                              replay_ctx->src_rev_pool));
 
+          /* Spin up the serf request for the PROPFIND.  */
+          svn_ra_serf__request_create(replay_ctx->propfind_handler);
+
           /* Send the replay report request. */
           handler = apr_pcalloc(replay_ctx->src_rev_pool, sizeof(*handler));
 

Modified: subversion/trunk/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/update.c?rev=1350182&r1=1350181&r2=1350182&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/update.c Thu Jun 14 10:38:49 2012
@@ -143,7 +143,7 @@ typedef struct report_dir_t
   apr_hash_t *removed_props;
 
   /* The propfind request for our current directory */
-  svn_ra_serf__propfind_context_t *propfind;
+  svn_ra_serf__handler_t *propfind_handler;
 
   /* Has the server told us to fetch the dir props? */
   svn_boolean_t fetch_props;
@@ -203,7 +203,7 @@ typedef struct report_info_t
   svn_revnum_t copyfrom_rev;
 
   /* The propfind request for our current file (if present) */
-  svn_ra_serf__propfind_context_t *propfind;
+  svn_ra_serf__handler_t *propfind_handler;
 
   /* Has the server told us to fetch the file props? */
   svn_boolean_t fetch_props;
@@ -346,7 +346,7 @@ struct report_context_t {
   /* number of pending PROPFIND requests */
   unsigned int active_propfinds;
 
-  /* completed PROPFIND requests (contains svn_ra_serf__propfind_context_t) */
+  /* completed PROPFIND requests (contains svn_ra_serf__handler_t) */
   svn_ra_serf__list_t *done_propfinds;
 
   /* list of files that only have prop changes (contains report_info_t) */
@@ -1230,15 +1230,18 @@ fetch_file(report_context_t *ctx, report
     }
 
   /* If needed, create the PROPFIND to retrieve the file's properties. */
-  info->propfind = NULL;
+  info->propfind_handler = NULL;
   if (info->fetch_props)
     {
-      SVN_ERR(svn_ra_serf__deliver_props(&info->propfind, info->props,
+      SVN_ERR(svn_ra_serf__deliver_props(&info->propfind_handler, info->props,
                                          ctx->sess, conn, info->url,
                                          ctx->target_rev, "0", all_props,
                                          &ctx->done_propfinds,
                                          info->dir->pool));
-      SVN_ERR_ASSERT(info->propfind);
+      SVN_ERR_ASSERT(info->propfind_handler);
+
+      /* Create a serf request for the PROPFIND.  */
+      svn_ra_serf__request_create(info->propfind_handler);
 
       ctx->active_propfinds++;
     }
@@ -1282,7 +1285,7 @@ fetch_file(report_context_t *ctx, report
       if (info->cached_contents)
         {
           /* If we'll be doing a PROPFIND for this file... */
-          if (info->propfind)
+          if (info->propfind_handler)
             { 
               /* ... then we'll just leave ourselves a little "todo"
                  about that fact (and we'll deal with the file content
@@ -1339,7 +1342,7 @@ fetch_file(report_context_t *ctx, report
           ctx->active_fetches++;
         }
     }
-  else if (info->propfind)
+  else if (info->propfind_handler)
     {
       svn_ra_serf__list_t *list_item;
 
@@ -1892,7 +1895,7 @@ end_report(svn_ra_serf__xml_parser_t *pa
           /* Unconditionally set fetch_props now. */
           info->dir->fetch_props = TRUE;
 
-          SVN_ERR(svn_ra_serf__deliver_props(&info->dir->propfind,
+          SVN_ERR(svn_ra_serf__deliver_props(&info->dir->propfind_handler,
                                              info->dir->props, ctx->sess,
                                              ctx->sess->conns[ctx->sess->cur_conn],
                                              info->dir->url,
@@ -1900,7 +1903,10 @@ end_report(svn_ra_serf__xml_parser_t *pa
                                              all_props,
                                              &ctx->done_propfinds,
                                              info->dir->pool));
-          SVN_ERR_ASSERT(info->dir->propfind);
+          SVN_ERR_ASSERT(info->dir->propfind_handler);
+
+          /* Create a serf request for the PROPFIND.  */
+          svn_ra_serf__request_create(info->dir->propfind_handler);
 
           ctx->active_propfinds++;
 
@@ -1910,7 +1916,7 @@ end_report(svn_ra_serf__xml_parser_t *pa
         }
       else
         {
-          info->dir->propfind = NULL;
+          info->dir->propfind_handler = NULL;
         }
 
       svn_ra_serf__xml_pop_state(parser);
@@ -2481,7 +2487,7 @@ finish_report(void *report_baton,
                 {
                   report_info_t *item = cur->data;
 
-                  if (item->propfind == done_list->data)
+                  if (item->propfind_handler == done_list->data)
                     {
                       break;
                     }
@@ -2549,9 +2555,9 @@ finish_report(void *report_baton,
            *   we've already completed the propfind
            * then, we know it's time for us to close this directory.
            */
-          while (cur_dir && !cur_dir->ref_count && cur_dir->tag_closed &&
-                 (!cur_dir->fetch_props ||
-                  svn_ra_serf__propfind_is_done(cur_dir->propfind)))
+          while (cur_dir && !cur_dir->ref_count && cur_dir->tag_closed
+                 && (!cur_dir->fetch_props
+                     || cur_dir->propfind_handler->done))
             {
               report_dir_t *parent = cur_dir->parent_dir;