You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/04/03 15:32:54 UTC

svn commit: r1308894 [6/14] - in /subversion/branches/ev2-export: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ notes/ notes/directory-index/ notes/wc-ng/ subversion/bindings/javahl/ subversion/bindings/swig/perl/native/t/ subv...

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/merge.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/merge.c Tue Apr  3 13:32:48 2012
@@ -80,8 +80,8 @@ typedef struct merge_info_t {
 
   const char *prop_ns;
   const char *prop_name;
-  const char *prop_val;
-  apr_size_t prop_val_len;
+  svn_stringbuf_t *prop_value;
+
 } merge_info_t;
 
 /* Structure associated with a MERGE request. */
@@ -119,6 +119,7 @@ push_state(svn_ra_serf__xml_parser_t *pa
       info = apr_palloc(parser->state->pool, sizeof(*info));
       info->pool = parser->state->pool;
       info->props = apr_hash_make(info->pool);
+      info->prop_value = svn_stringbuf_create_empty(info->pool);
 
       parser->state->private = info;
     }
@@ -128,11 +129,11 @@ push_state(svn_ra_serf__xml_parser_t *pa
 
 static svn_error_t *
 start_merge(svn_ra_serf__xml_parser_t *parser,
-            void *userData,
             svn_ra_serf__dav_props_t name,
-            const char **attrs)
+            const char **attrs,
+            apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__merge_context_t *ctx = userData;
+  svn_ra_serf__merge_context_t *ctx = parser->user_data;
   merge_state_e state;
   merge_info_t *info;
 
@@ -163,9 +164,8 @@ start_merge(svn_ra_serf__xml_parser_t *p
       info = push_state(parser, ctx, PROP_VAL);
 
       info->prop_ns = name.namespace;
-      info->prop_name = apr_pstrdup(info->pool, name.name);
-      info->prop_val = NULL;
-      info->prop_val_len = 0;
+      info->prop_name = "href";
+      svn_stringbuf_setempty(info->prop_value);
     }
   else if (state == RESPONSE &&
            strcmp(name.name, "propstat") == 0)
@@ -206,11 +206,9 @@ start_merge(svn_ra_serf__xml_parser_t *p
            strcmp(name.name, "checked-in") == 0)
     {
       info = push_state(parser, ctx, IGNORE_PROP_NAME);
-
       info->prop_ns = name.namespace;
-      info->prop_name = apr_pstrdup(info->pool, name.name);
-      info->prop_val = NULL;
-      info->prop_val_len = 0;
+      info->prop_name = "checked-in";
+      svn_stringbuf_setempty(info->prop_value);
     }
   else if (state == PROP)
     {
@@ -225,8 +223,7 @@ start_merge(svn_ra_serf__xml_parser_t *p
       info = push_state(parser, ctx, PROP_VAL);
       info->prop_ns = name.namespace;
       info->prop_name = apr_pstrdup(info->pool, name.name);
-      info->prop_val = NULL;
-      info->prop_val_len = 0;
+      svn_stringbuf_setempty(info->prop_value);
     }
   else
     {
@@ -238,10 +235,10 @@ start_merge(svn_ra_serf__xml_parser_t *p
 
 static svn_error_t *
 end_merge(svn_ra_serf__xml_parser_t *parser,
-          void *userData,
-          svn_ra_serf__dav_props_t name)
+          svn_ra_serf__dav_props_t name,
+          apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__merge_context_t *ctx = userData;
+  svn_ra_serf__merge_context_t *ctx = parser->user_data;
   merge_state_e state;
   merge_info_t *info;
 
@@ -349,24 +346,27 @@ end_merge(svn_ra_serf__xml_parser_t *par
     }
   else if (state == PROP_VAL)
     {
+      const char *value;
+
       if (!info->prop_name)
         {
+          /* ### gstein sez: dunno what this is about.  */
           info->prop_name = apr_pstrdup(info->pool, name.name);
         }
-      info->prop_val = apr_pstrmemdup(info->pool, info->prop_val,
-                                      info->prop_val_len);
+
       if (strcmp(info->prop_name, "href") == 0)
-        info->prop_val = svn_urlpath__canonicalize(info->prop_val,
-                                                       info->pool);
+        value = svn_urlpath__canonicalize(info->prop_value->data, info->pool);
+      else
+        value = apr_pstrmemdup(info->pool,
+                               info->prop_value->data, info->prop_value->len);
 
       /* Set our property. */
       apr_hash_set(info->props, info->prop_name, APR_HASH_KEY_STRING,
-                   info->prop_val);
+                   value);
 
       info->prop_ns = NULL;
       info->prop_name = NULL;
-      info->prop_val = NULL;
-      info->prop_val_len = 0;
+      svn_stringbuf_setempty(info->prop_value);
 
       svn_ra_serf__xml_pop_state(parser);
     }
@@ -376,11 +376,11 @@ end_merge(svn_ra_serf__xml_parser_t *par
 
 static svn_error_t *
 cdata_merge(svn_ra_serf__xml_parser_t *parser,
-            void *userData,
             const char *data,
-            apr_size_t len)
+            apr_size_t len,
+            apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__merge_context_t *ctx = userData;
+  svn_ra_serf__merge_context_t *ctx = parser->user_data;
   merge_state_e state;
   merge_info_t *info;
 
@@ -390,10 +390,7 @@ cdata_merge(svn_ra_serf__xml_parser_t *p
   info = parser->state->private;
 
   if (state == PROP_VAL)
-    {
-      svn_ra_serf__expand_string(&info->prop_val, &info->prop_val_len,
-                                 data, len, parser->state->pool);
-    }
+    svn_stringbuf_appendbytes(info->prop_value, data, len);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c Tue Apr  3 13:32:48 2012
@@ -66,11 +66,11 @@ typedef struct mergeinfo_context_t {
 
 static svn_error_t *
 start_element(svn_ra_serf__xml_parser_t *parser,
-              void *userData,
               svn_ra_serf__dav_props_t name,
-              const char **attrs)
+              const char **attrs,
+              apr_pool_t *scratch_pool)
 {
-  mergeinfo_context_t *mergeinfo_ctx = userData;
+  mergeinfo_context_t *mergeinfo_ctx = parser->user_data;
   mergeinfo_state_e state;
 
   state = parser->state->current_state;
@@ -99,10 +99,11 @@ start_element(svn_ra_serf__xml_parser_t 
 }
 
 static svn_error_t *
-end_element(svn_ra_serf__xml_parser_t *parser, void *userData,
-            svn_ra_serf__dav_props_t name)
+end_element(svn_ra_serf__xml_parser_t *parser,
+            svn_ra_serf__dav_props_t name,
+            apr_pool_t *scratch_pool)
 {
-  mergeinfo_context_t *mergeinfo_ctx = userData;
+  mergeinfo_context_t *mergeinfo_ctx = parser->user_data;
   mergeinfo_state_e state;
 
   state = parser->state->current_state;
@@ -149,10 +150,12 @@ end_element(svn_ra_serf__xml_parser_t *p
 
 
 static svn_error_t *
-cdata_handler(svn_ra_serf__xml_parser_t *parser, void *userData,
-              const char *data, apr_size_t len)
+cdata_handler(svn_ra_serf__xml_parser_t *parser,
+              const char *data,
+              apr_size_t len,
+              apr_pool_t *scratch_pool)
 {
-  mergeinfo_context_t *mergeinfo_ctx = userData;
+  mergeinfo_context_t *mergeinfo_ctx = parser->user_data;
   mergeinfo_state_e state;
 
   state = parser->state->current_state;

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c Tue Apr  3 13:32:48 2012
@@ -66,8 +66,8 @@ struct svn_ra_serf__options_context_t {
   /* pool to allocate memory from */
   apr_pool_t *pool;
 
-  const char *attr_val;
-  apr_size_t attr_val_len;
+  /* Buffer for the activity-collection  */
+  svn_stringbuf_t *acbuf;
   svn_boolean_t collect_cdata;
 
   /* Current state we're in */
@@ -127,11 +127,11 @@ static void pop_state(svn_ra_serf__optio
 
 static svn_error_t *
 start_options(svn_ra_serf__xml_parser_t *parser,
-              void *userData,
               svn_ra_serf__dav_props_t name,
-              const char **attrs)
+              const char **attrs,
+              apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__options_context_t *options_ctx = userData;
+  svn_ra_serf__options_context_t *options_ctx = parser->user_data;
 
   if (!options_ctx->state && strcmp(name.name, "options-response") == 0)
     {
@@ -159,10 +159,10 @@ start_options(svn_ra_serf__xml_parser_t 
 
 static svn_error_t *
 end_options(svn_ra_serf__xml_parser_t *parser,
-            void *userData,
-            svn_ra_serf__dav_props_t name)
+            svn_ra_serf__dav_props_t name,
+            apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__options_context_t *options_ctx = userData;
+  svn_ra_serf__options_context_t *options_ctx = parser->user_data;
   options_state_list_t *cur_state;
 
   if (!options_ctx->state)
@@ -187,7 +187,7 @@ end_options(svn_ra_serf__xml_parser_t *p
     {
       options_ctx->collect_cdata = FALSE;
       options_ctx->activity_collection =
-        svn_urlpath__canonicalize(options_ctx->attr_val, options_ctx->pool);
+        svn_urlpath__canonicalize(options_ctx->acbuf->data, options_ctx->pool);
       pop_state(options_ctx);
     }
 
@@ -196,16 +196,14 @@ end_options(svn_ra_serf__xml_parser_t *p
 
 static svn_error_t *
 cdata_options(svn_ra_serf__xml_parser_t *parser,
-              void *userData,
               const char *data,
-              apr_size_t len)
+              apr_size_t len,
+              apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__options_context_t *ctx = userData;
+  svn_ra_serf__options_context_t *ctx = parser->user_data;
+
   if (ctx->collect_cdata)
-    {
-      svn_ra_serf__expand_string(&ctx->attr_val, &ctx->attr_val_len,
-                                 data, len, ctx->pool);
-    }
+    svn_stringbuf_appendbytes(ctx->acbuf, data, len);
 
   return SVN_NO_ERROR;
 }
@@ -442,6 +440,8 @@ svn_ra_serf__create_options_req(svn_ra_s
 
   new_ctx->pool = pool;
 
+  new_ctx->acbuf = svn_stringbuf_create_empty(pool);
+
   new_ctx->path = path;
   new_ctx->youngest_rev = SVN_INVALID_REVNUM;
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c Tue Apr  3 13:32:48 2012
@@ -33,6 +33,7 @@
 
 #include "private/svn_dav_protocol.h"
 #include "private/svn_fspath.h"
+#include "private/svn_string_private.h"
 #include "svn_private_config.h"
 
 #include "ra_serf.h"
@@ -51,11 +52,8 @@ typedef struct prop_info_t {
 
   /* Current ns, attribute name, and value of the property we're parsing */
   const char *ns;
-
   const char *name;
-
-  const char *val;
-  apr_size_t val_len;
+  svn_stringbuf_t *value;
 
   const char *encoding;
 
@@ -243,6 +241,7 @@ push_state(svn_ra_serf__xml_parser_t *pa
 
       info = apr_pcalloc(parser->state->pool, sizeof(*info));
       info->pool = parser->state->pool;
+      info->value = svn_stringbuf_create_empty(info->pool);
 
       parser->state->private = info;
     }
@@ -255,11 +254,11 @@ push_state(svn_ra_serf__xml_parser_t *pa
  */
 static svn_error_t *
 start_propfind(svn_ra_serf__xml_parser_t *parser,
-               void *userData,
                svn_ra_serf__dav_props_t name,
-               const char **attrs)
+               const char **attrs,
+               apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__propfind_context_t *ctx = userData;
+  svn_ra_serf__propfind_context_t *ctx = parser->user_data;
   prop_state_e state;
   prop_info_t *info;
 
@@ -273,7 +272,7 @@ start_propfind(svn_ra_serf__xml_parser_t
     {
       info = push_state(parser, ctx, PROPVAL);
       info->ns = name.namespace;
-      info->name = apr_pstrdup(info->pool, name.name);
+      info->name = "href";
     }
   else if (state == RESPONSE && strcmp(name.name, "prop") == 0)
     {
@@ -296,10 +295,10 @@ start_propfind(svn_ra_serf__xml_parser_t
  */
 static svn_error_t *
 end_propfind(svn_ra_serf__xml_parser_t *parser,
-             void *userData,
-             svn_ra_serf__dav_props_t name)
+             svn_ra_serf__dav_props_t name,
+             apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__propfind_context_t *ctx = userData;
+  svn_ra_serf__propfind_context_t *ctx = parser->user_data;
   prop_state_e state;
   prop_info_t *info;
 
@@ -316,24 +315,20 @@ end_propfind(svn_ra_serf__xml_parser_t *
     }
   else if (state == PROPVAL)
     {
-      const char *ns, *pname, *val;
-      svn_string_t *val_str;
+      const char *ns;
+      const char *pname;
+      const svn_string_t *val_str = NULL;
 
       /* if we didn't see a CDATA element, we may want the tag name
        * as long as it isn't equivalent to the property name.
        */
-      if (!info->val)
+      /* ### gstein sez: I have no idea what this is about.  */
+      if (*info->value->data == '\0')
         {
           if (strcmp(info->name, name.name) != 0)
-            {
-              info->val = name.name;
-              info->val_len = strlen(info->val);
-            }
+            val_str = svn_string_create(name.name, ctx->pool);
           else
-            {
-              info->val = "";
-              info->val_len = 0;
-            }
+            val_str = svn_string_create_empty(ctx->pool);
         }
 
       if (parser->state->prev->current_state == RESPONSE &&
@@ -342,7 +337,7 @@ end_propfind(svn_ra_serf__xml_parser_t *
           if (strcmp(ctx->depth, "1") == 0)
             {
               ctx->current_path =
-                svn_urlpath__canonicalize(info->val, ctx->pool);
+                svn_urlpath__canonicalize(info->value->data, ctx->pool);
             }
           else
             {
@@ -353,15 +348,13 @@ end_propfind(svn_ra_serf__xml_parser_t *
         {
           if (strcmp(info->encoding, "base64") == 0)
             {
-              svn_string_t encoded;
-              const svn_string_t *decoded;
-
-              encoded.data = info->val;
-              encoded.len = info->val_len;
+              const svn_string_t *morph;
 
-              decoded = svn_base64_decode_string(&encoded, parser->state->pool);
-              info->val = decoded->data;
-              info->val_len = decoded->len;
+              morph = svn_stringbuf__morph_into_string(info->value);
+#ifdef SVN_DEBUG
+              info->value = NULL;  /* morph killed the stringbuf.  */
+#endif
+              val_str = svn_base64_decode_string(morph, ctx->pool);
             }
           else
             {
@@ -372,10 +365,13 @@ end_propfind(svn_ra_serf__xml_parser_t *
             }
         }
 
+      /* ### there may be better logic to ensure this is set above, but just
+         ### going for the easy win here.  */
+      if (val_str == NULL)
+        val_str = svn_string_create_from_buf(info->value, ctx->pool);
+
       ns = apr_pstrdup(ctx->pool, info->ns);
       pname = apr_pstrdup(ctx->pool, info->name);
-      val = apr_pmemdup(ctx->pool, info->val, info->val_len);
-      val_str = svn_string_ncreate(val, info->val_len, ctx->pool);
 
       /* set the return props and update our cache too. */
       svn_ra_serf__set_ver_prop(ctx->ret_props,
@@ -396,11 +392,11 @@ end_propfind(svn_ra_serf__xml_parser_t *
  */
 static svn_error_t *
 cdata_propfind(svn_ra_serf__xml_parser_t *parser,
-               void *userData,
                const char *data,
-               apr_size_t len)
+               apr_size_t len,
+               apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__propfind_context_t *ctx = userData;
+  svn_ra_serf__propfind_context_t *ctx = parser->user_data;
   prop_state_e state;
   prop_info_t *info;
 
@@ -410,10 +406,7 @@ cdata_propfind(svn_ra_serf__xml_parser_t
   info = parser->state->private;
 
   if (state == PROPVAL)
-    {
-      svn_ra_serf__expand_string(&info->val, &info->val_len, data, len,
-                                 info->pool);
-    }
+    svn_stringbuf_appendbytes(info->value, data, len);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h Tue Apr  3 13:32:48 2012
@@ -39,6 +39,7 @@
 #include "svn_dirent_uri.h"
 
 #include "private/svn_dav_protocol.h"
+#include "private/svn_subr_private.h"
 
 #include "blncache.h"
 
@@ -70,6 +71,10 @@ typedef struct svn_ra_serf__connection_t
   /* Our connection to a server. */
   serf_connection_t *conn;
 
+  /* The server is not Apache/mod_dav_svn (directly) and only supports
+     HTTP/1.0. Thus, we cannot send chunked requests.  */
+  svn_boolean_t http10;
+
   /* Bucket allocator for this connection. */
   serf_bucket_alloc_t *bkt_alloc;
 
@@ -319,12 +324,6 @@ svn_ra_serf__conn_setup(apr_socket_t *so
                         void *baton,
                         apr_pool_t *pool);
 
-serf_bucket_t*
-svn_ra_serf__accept_response(serf_request_t *request,
-                             serf_bucket_t *stream,
-                             void *acceptor_baton,
-                             apr_pool_t *pool);
-
 void
 svn_ra_serf__conn_closed(serf_connection_t *conn,
                          void *closed_baton,
@@ -351,24 +350,6 @@ svn_ra_serf__handle_client_cert_pw(void 
                                    const char *cert_path,
                                    const char **password);
 
-/*
- * Create a REQUEST with an associated REQ_BKT in the SESSION.
- *
- * If HDRS_BKT is not-NULL, it will be set to a headers_bucket that
- * corresponds to the new request.
- *
- * The request will be METHOD at URL.
- *
- * If BODY_BKT is not-NULL, it will be sent as the request body.
- *
- * If CONTENT_TYPE is not-NULL, it will be sent as the Content-Type header.
- */
-svn_error_t *
-svn_ra_serf__setup_serf_req(serf_request_t *request,
-                            serf_bucket_t **req_bkt, serf_bucket_t **hdrs_bkt,
-                            svn_ra_serf__connection_t *conn,
-                            const char *method, const char *url,
-                            serf_bucket_t *body_bkt, const char *content_type);
 
 /*
  * This function will run the serf context in SESS until *DONE is TRUE.
@@ -385,29 +366,20 @@ typedef svn_error_t *
                                    void *handler_baton,
                                    apr_pool_t *pool);
 
-/* Callback for setting up a complete serf request */
-typedef svn_error_t *
-(*svn_ra_serf__request_setup_t)(serf_request_t *request,
-                                void *setup_baton,
-                                serf_bucket_t **req_bkt,
-                                serf_response_acceptor_t *acceptor,
-                                void **acceptor_baton,
-                                svn_ra_serf__response_handler_t *handler,
-                                void **handler_baton,
-                                apr_pool_t *pool);
-
 /* Callback for when a request body is needed. */
+/* ### should pass a scratch_pool  */
 typedef svn_error_t *
 (*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
                                         void *baton,
                                         serf_bucket_alloc_t *alloc,
-                                        apr_pool_t *pool);
+                                        apr_pool_t *request_pool);
 
 /* Callback for when request headers are needed. */
+/* ### should pass a scratch_pool  */
 typedef svn_error_t *
 (*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
                                           void *baton,
-                                          apr_pool_t *pool);
+                                          apr_pool_t *request_pool);
 
 /* Callback for when a response has an error. */
 typedef svn_error_t *
@@ -441,15 +413,6 @@ typedef struct svn_ra_serf__handler_t {
   svn_ra_serf__response_error_t response_error;
   void *response_error_baton;
 
-  /* This function and baton will be executed when the request is about
-   * to be delivered by serf.
-   *
-   * This just passes through serf's raw request creation parameters.
-   * None of the other parameters will be utilized if this field is set.
-   */
-  svn_ra_serf__request_setup_t setup;
-  void *setup_baton;
-
   /* This function and baton pair allows for custom request headers to
    * be set.
    *
@@ -513,30 +476,28 @@ typedef struct svn_ra_serf__xml_parser_t
  */
 typedef svn_error_t *
 (*svn_ra_serf__xml_start_element_t)(svn_ra_serf__xml_parser_t *parser,
-                                    void *baton,
                                     svn_ra_serf__dav_props_t name,
-                                    const char **attrs);
+                                    const char **attrs,
+                                    apr_pool_t *scratch_pool);
 
 /* Callback invoked with @a baton by our XML @a parser when an element with
  * the @a name is closed.
  */
 typedef svn_error_t *
 (*svn_ra_serf__xml_end_element_t)(svn_ra_serf__xml_parser_t *parser,
-                                  void *baton,
-                                  svn_ra_serf__dav_props_t name);
+                                  svn_ra_serf__dav_props_t name,
+                                  apr_pool_t *scratch_pool);
 
 /* Callback invoked with @a baton by our XML @a parser when a CDATA portion
  * of @a data with size @a len is encountered.
  *
  * This may be invoked multiple times for the same tag.
- *
- * @see svn_ra_serf__expand_string
  */
 typedef svn_error_t *
 (*svn_ra_serf__xml_cdata_chunk_handler_t)(svn_ra_serf__xml_parser_t *parser,
-                                          void *baton,
                                           const char *data,
-                                          apr_size_t len);
+                                          apr_size_t len,
+                                          apr_pool_t *scratch_pool);
 
 /*
  * Helper structure associated with handle_xml_parser handler that will
@@ -885,16 +846,6 @@ svn_ra_serf__expand_ns(svn_ra_serf__dav_
                        svn_ra_serf__ns_t *ns_list,
                        const char *name);
 
-/*
- * Expand the string represented by @a cur with a current size of @a
- * cur_len by appending @a new with a size of @a new_len.
- *
- * The reallocated string is made in @a pool.
- */
-void
-svn_ra_serf__expand_string(const char **cur, apr_size_t *cur_len,
-                           const char *new, apr_size_t new_len,
-                           apr_pool_t *pool);
 
 /** PROPFIND-related functions **/
 
@@ -1462,6 +1413,18 @@ svn_ra_serf__register_editor_shim_callba
                                     svn_delta_shim_callbacks_t *callbacks);
 
 
+svn_error_t *
+svn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf,
+                                serf_bucket_t *bkt,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
+serf_bucket_t *
+svn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf,
+                              serf_bucket_alloc_t *allocator,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c Tue Apr  3 13:32:48 2012
@@ -40,6 +40,8 @@
 #include "svn_path.h"
 #include "svn_private_config.h"
 
+#include "private/svn_string_private.h"
+
 #include "ra_serf.h"
 
 
@@ -83,8 +85,7 @@ typedef struct prop_info_t {
   const char *name;
   svn_boolean_t del_prop;
 
-  const char *data;
-  apr_size_t len;
+  svn_stringbuf_t *prop_value;
 
   replay_info_t *parent;
 } prop_info_t;
@@ -165,6 +166,7 @@ push_state(svn_ra_serf__xml_parser_t *pa
 
       info->pool = replay_ctx->dst_rev_pool;
       info->parent = parser->state->private;
+      info->prop_value = svn_stringbuf_create_empty(info->pool);
 
       parser->state->private = info;
     }
@@ -174,11 +176,11 @@ push_state(svn_ra_serf__xml_parser_t *pa
 
 static svn_error_t *
 start_replay(svn_ra_serf__xml_parser_t *parser,
-             void *userData,
              svn_ra_serf__dav_props_t name,
-             const char **attrs)
+             const char **attrs,
+             apr_pool_t *scratch_pool)
 {
-  replay_context_t *ctx = userData;
+  replay_context_t *ctx = parser->user_data;
   replay_state_e state;
 
   state = parser->state->current_state;
@@ -471,14 +473,12 @@ start_replay(svn_ra_serf__xml_parser_t *
 
 static svn_error_t *
 end_replay(svn_ra_serf__xml_parser_t *parser,
-           void *userData,
-           svn_ra_serf__dav_props_t name)
+           svn_ra_serf__dav_props_t name,
+           apr_pool_t *scratch_pool)
 {
-  replay_context_t *ctx = userData;
+  replay_context_t *ctx = parser->user_data;
   replay_state_e state;
 
-  UNUSED_CTX(ctx);
-
   state = parser->state->current_state;
 
   if (state == REPORT &&
@@ -535,15 +535,17 @@ end_replay(svn_ra_serf__xml_parser_t *pa
         }
       else
         {
-          svn_string_t tmp_prop;
+          const svn_string_t *morph;
 
-          tmp_prop.data = info->data;
-          tmp_prop.len = info->len;
+          morph = svn_stringbuf__morph_into_string(info->prop_value);
+#ifdef SVN_DEBUG
+          info->prop_value = NULL;  /* morph killed the stringbuf.  */
+#endif
 
           if (strcmp(name.name, "change-file-prop") == 0)
-            prop_val = svn_base64_decode_string(&tmp_prop, ctx->file_pool);
+            prop_val = svn_base64_decode_string(morph, ctx->file_pool);
           else
-            prop_val = svn_base64_decode_string(&tmp_prop, ctx->dst_rev_pool);
+            prop_val = svn_base64_decode_string(morph, ctx->dst_rev_pool);
         }
 
       SVN_ERR(info->change(info->parent->baton, info->name, prop_val,
@@ -556,11 +558,11 @@ end_replay(svn_ra_serf__xml_parser_t *pa
 
 static svn_error_t *
 cdata_replay(svn_ra_serf__xml_parser_t *parser,
-             void *userData,
              const char *data,
-             apr_size_t len)
+             apr_size_t len,
+             apr_pool_t *scratch_pool)
 {
-  replay_context_t *replay_ctx = userData;
+  replay_context_t *replay_ctx = parser->user_data;
   replay_state_e state;
 
   UNUSED_CTX(replay_ctx);
@@ -584,8 +586,7 @@ cdata_replay(svn_ra_serf__xml_parser_t *
     {
       prop_info_t *info = parser->state->private;
 
-      svn_ra_serf__expand_string(&info->data, &info->len,
-                                 data, len, parser->state->pool);
+      svn_stringbuf_appendbytes(info->prop_value, data, len);
     }
 
   return SVN_NO_ERROR;
@@ -845,7 +846,26 @@ svn_ra_serf__replay_range(svn_ra_session
 
       /* Run the serf loop, send outgoing and process incoming requests.
          This request will block when there are no more requests to send or
-         responses to receive, so we have to be careful on our bookkeeping. */
+         responses to receive, so we have to be careful on our bookkeeping.
+
+         ### we should probably adjust this timeout. if we get (say) 3
+         ### requests completed, then we want to exit immediately rather
+         ### than block for a few seconds. that will allow us to clear up
+         ### those 3 requests. if we have queued all of our revisions,
+         ### then we may want to block until timeout since we really don't
+         ### have much work other than destroying memory. (though that
+         ### is important, as we could end up with 50 src_rev_pool pools)
+
+         ### idea: when a revision is marked DONE, we can probably destroy
+         ### most of the memory. that will reduce pressue to have serf
+         ### return control to us, to complete the major memory disposal.
+
+         ### theoretically, we should use an iterpool here, but it turns
+         ### out that serf doesn't even use the pool param. if we grow
+         ### an iterpool in this loop for other purposes, then yeah: go
+         ### ahead and apply it here, too, in case serf eventually uses
+         ### that parameter.
+      */
       status = serf_context_run(session->context, session->timeout,
                                 pool);
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c Tue Apr  3 13:32:48 2012
@@ -397,16 +397,16 @@ svn_ra_serf__open(svn_ra_session_t *sess
 
   serf_sess->conns[0] = apr_pcalloc(serf_sess->pool,
                                     sizeof(*serf_sess->conns[0]));
+  serf_sess->conns[0]->http10 = TRUE;  /* until we confirm HTTP/1.1  */
+  serf_sess->conns[0]->http10 = FALSE; /* ### don't change behavior yet  */
   serf_sess->conns[0]->bkt_alloc =
           serf_bucket_allocator_create(serf_sess->pool, NULL, NULL);
   serf_sess->conns[0]->session = serf_sess;
   serf_sess->conns[0]->last_status_code = -1;
 
   serf_sess->conns[0]->using_ssl = serf_sess->using_ssl;
-  serf_sess->conns[0]->server_cert_failures = 0;
   serf_sess->conns[0]->using_compression = serf_sess->using_compression;
   serf_sess->conns[0]->hostname = url.hostname;
-  serf_sess->conns[0]->useragent = NULL;
 
   /* create the user agent string */
   if (callbacks->get_client_string)
@@ -1196,6 +1196,7 @@ svn_ra_serf__init(const svn_version_t *l
       || serf_minor < SERF_MINOR_VERSION)
     {
       return svn_error_createf(
+         /* ### should return a unique error  */
          SVN_ERR_VERSION_MISMATCH, NULL,
          _("ra_serf was compiled for serf %d.%d.%d but loaded "
            "an incompatible %d.%d.%d library"),

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c Tue Apr  3 13:32:48 2012
@@ -43,6 +43,7 @@
 #include "svn_private_config.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_fspath.h"
+#include "private/svn_string_private.h"
 
 #include "ra_serf.h"
 #include "../libsvn_ra/ra_loader.h"
@@ -241,8 +242,7 @@ typedef struct report_info_t
    */
   const char *prop_ns;
   const char *prop_name;
-  const char *prop_val;
-  apr_size_t prop_val_len;
+  svn_stringbuf_t *prop_value;
   const char *prop_encoding;
 } report_info_t;
 
@@ -397,6 +397,7 @@ push_state(svn_ra_serf__xml_parser_t *pa
       new_info = apr_pcalloc(info_parent_pool, sizeof(*new_info));
       new_info->pool = svn_pool_create(info_parent_pool);
       new_info->lock_token = NULL;
+      new_info->prop_value = svn_stringbuf_create_empty(new_info->pool);
 
       new_info->dir = apr_pcalloc(new_info->pool, sizeof(*new_info->dir));
       new_info->dir->pool = new_info->pool;
@@ -441,6 +442,7 @@ push_state(svn_ra_serf__xml_parser_t *pa
       new_info->file_baton = NULL;
       new_info->lock_token = NULL;
       new_info->fetch_file = FALSE;
+      new_info->prop_value = svn_stringbuf_create_empty(new_info->pool);
 
       /* Point at our parent's directory state. */
       new_info->dir = info->dir;
@@ -1327,11 +1329,11 @@ fetch_file(report_context_t *ctx, report
 
 static svn_error_t *
 start_report(svn_ra_serf__xml_parser_t *parser,
-             void *userData,
              svn_ra_serf__dav_props_t name,
-             const char **attrs)
+             const char **attrs,
+             apr_pool_t *scratch_pool)
 {
-  report_context_t *ctx = userData;
+  report_context_t *ctx = parser->user_data;
   report_state_e state;
 
   state = parser->state->current_state;
@@ -1645,8 +1647,7 @@ start_report(svn_ra_serf__xml_parser_t *
           info->prop_ns = name.namespace;
           info->prop_name = apr_pstrdup(parser->state->pool, name.name);
           info->prop_encoding = NULL;
-          info->prop_val = NULL;
-          info->prop_val_len = 0;
+          svn_stringbuf_setempty(info->prop_value);
         }
       else if (strcmp(name.name, "set-prop") == 0 ||
                strcmp(name.name, "remove-prop") == 0)
@@ -1675,8 +1676,7 @@ start_report(svn_ra_serf__xml_parser_t *
                                          colon - full_prop_name);
           info->prop_name = apr_pstrdup(parser->state->pool, colon);
           info->prop_encoding = svn_xml_get_attr_value("encoding", attrs);
-          info->prop_val = NULL;
-          info->prop_val_len = 0;
+          svn_stringbuf_setempty(info->prop_value);
         }
       else if (strcmp(name.name, "prop") == 0)
         {
@@ -1707,8 +1707,7 @@ start_report(svn_ra_serf__xml_parser_t *
           info->prop_ns = name.namespace;
           info->prop_name = apr_pstrdup(parser->state->pool, name.name);
           info->prop_encoding = NULL;
-          info->prop_val = NULL;
-          info->prop_val_len = 0;
+          svn_stringbuf_setempty(info->prop_value);
         }
       else if (strcmp(name.name, "prop") == 0)
         {
@@ -1763,8 +1762,7 @@ start_report(svn_ra_serf__xml_parser_t *
                                          colon - full_prop_name);
           info->prop_name = apr_pstrdup(parser->state->pool, colon);
           info->prop_encoding = svn_xml_get_attr_value("encoding", attrs);
-          info->prop_val = NULL;
-          info->prop_val_len = 0;
+          svn_stringbuf_setempty(info->prop_value);
         }
       else
         {
@@ -1787,8 +1785,7 @@ start_report(svn_ra_serf__xml_parser_t *
       info->prop_ns = name.namespace;
       info->prop_name = apr_pstrdup(parser->state->pool, name.name);
       info->prop_encoding = svn_xml_get_attr_value("encoding", attrs);
-      info->prop_val = NULL;
-      info->prop_val_len = 0;
+      svn_stringbuf_setempty(info->prop_value);
     }
 
   return SVN_NO_ERROR;
@@ -1796,10 +1793,10 @@ start_report(svn_ra_serf__xml_parser_t *
 
 static svn_error_t *
 end_report(svn_ra_serf__xml_parser_t *parser,
-           void *userData,
-           svn_ra_serf__dav_props_t name)
+           svn_ra_serf__dav_props_t name,
+           apr_pool_t *scratch_pool)
 {
-  report_context_t *ctx = userData;
+  report_context_t *ctx = parser->user_data;
   report_state_e state;
 
   state = parser->state->current_state;
@@ -1950,7 +1947,7 @@ end_report(svn_ra_serf__xml_parser_t *pa
     }
   else if (state == PROP)
     {
-      /* We need to move the prop_ns, prop_name, and prop_val into the
+      /* We need to move the prop_ns, prop_name, and prop_value into the
        * same lifetime as the dir->pool.
        */
       svn_ra_serf__ns_t *ns, *ns_name_match;
@@ -1958,8 +1955,7 @@ end_report(svn_ra_serf__xml_parser_t *pa
       report_info_t *info;
       report_dir_t *dir;
       apr_hash_t *props;
-      const char *set_val;
-      svn_string_t *set_val_str;
+      const svn_string_t *set_val_str;
       apr_pool_t *pool;
 
       info = parser->state->private;
@@ -2009,24 +2005,21 @@ end_report(svn_ra_serf__xml_parser_t *pa
         {
           props = dir->removed_props;
           pool = dir->pool;
-          info->prop_val = "";
-          info->prop_val_len = 1;
+          svn_stringbuf_setempty(info->prop_value);
         }
 
       if (info->prop_encoding)
         {
           if (strcmp(info->prop_encoding, "base64") == 0)
             {
-              svn_string_t encoded;
-              const svn_string_t *decoded;
+              svn_string_t tmp;
 
-              encoded.data = info->prop_val;
-              encoded.len = info->prop_val_len;
+              /* Don't use morph_info_string cuz we need prop_value to
+                 remain usable.  */
+              tmp.data = info->prop_value->data;
+              tmp.len = info->prop_value->len;
 
-              decoded = svn_base64_decode_string(&encoded, parser->state->pool);
-
-              info->prop_val = decoded->data;
-              info->prop_val_len = decoded->len;
+              set_val_str = svn_base64_decode_string(&tmp, pool);
             }
           else
             {
@@ -2035,11 +2028,11 @@ end_report(svn_ra_serf__xml_parser_t *pa
                                        _("Got unrecognized encoding '%s'"),
                                        info->prop_encoding);
             }
-
         }
-
-      set_val = apr_pmemdup(pool, info->prop_val, info->prop_val_len);
-      set_val_str = svn_string_ncreate(set_val, info->prop_val_len, pool);
+      else
+        {
+          set_val_str = svn_string_create_from_buf(info->prop_value, pool);
+        }
 
       svn_ra_serf__set_ver_prop(props, info->base_name, info->base_rev,
                                 ns->namespace, ns->url, set_val_str, pool);
@@ -2055,11 +2048,11 @@ end_report(svn_ra_serf__xml_parser_t *pa
 
 static svn_error_t *
 cdata_report(svn_ra_serf__xml_parser_t *parser,
-             void *userData,
              const char *data,
-             apr_size_t len)
+             apr_size_t len,
+             apr_pool_t *scratch_pool)
 {
-  report_context_t *ctx = userData;
+  report_context_t *ctx = parser->user_data;
 
   UNUSED_CTX(ctx);
 
@@ -2067,8 +2060,7 @@ cdata_report(svn_ra_serf__xml_parser_t *
     {
       report_info_t *info = parser->state->private;
 
-      svn_ra_serf__expand_string(&info->prop_val, &info->prop_val_len,
-                                 data, len, parser->state->pool);
+      svn_stringbuf_appendbytes(info->prop_value, data, len);
     }
 
   return SVN_NO_ERROR;
@@ -2226,16 +2218,17 @@ open_connection_if_needed(svn_ra_serf__s
       int cur = sess->num_conns;
       apr_status_t status;
 
-      sess->conns[cur] = apr_palloc(sess->pool, sizeof(*sess->conns[cur]));
+      sess->conns[cur] = apr_pcalloc(sess->pool, sizeof(*sess->conns[cur]));
+      sess->conns[cur]->http10 = TRUE;  /* until we confirm HTTP/1.1  */
+      sess->conns[cur]->http10 = FALSE; /* ### don't change behavior yet  */
       sess->conns[cur]->bkt_alloc = serf_bucket_allocator_create(sess->pool,
                                                                  NULL, NULL);
       sess->conns[cur]->hostname  = sess->conns[0]->hostname;
       sess->conns[cur]->using_ssl = sess->conns[0]->using_ssl;
       sess->conns[cur]->using_compression = sess->conns[0]->using_compression;
-      sess->conns[cur]->useragent = sess->conns[0]->useragent;
       sess->conns[cur]->last_status_code = -1;
-      sess->conns[cur]->ssl_context = NULL;
       sess->conns[cur]->session = sess;
+      sess->conns[cur]->useragent = sess->conns[0]->useragent;
       status = serf_connection_create2(&sess->conns[cur]->conn,
                                        sess->context,
                                        sess->session_url,

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c Tue Apr  3 13:32:48 2012
@@ -38,9 +38,11 @@
 #include "svn_private_config.h"
 #include "svn_string.h"
 #include "svn_xml.h"
+
 #include "../libsvn_ra/ra_loader.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_fspath.h"
+#include "private/svn_subr_private.h"
 
 #include "ra_serf.h"
 
@@ -54,124 +56,29 @@
 #endif
 
 
+/* Read/write chunks of this size into the spillbuf.  */
 #define PARSE_CHUNK_SIZE 8000
 
-/* As chunks of content arrive from the server, and we need to hold them
-   in memory (because the XML parser is paused), they are copied into
-   these buffers. The buffers are arranged into a linked list.  */
-struct pending_buffer_t {
-  apr_size_t size;
-  char data[PARSE_CHUNK_SIZE];
-
-  struct pending_buffer_t *next;
-};
+/* We will store one megabyte in memory, before switching to store content
+   into a temporary file.  */
+#define SPILL_SIZE 1000000
 
 
 /* This structure records pending data for the parser in memory blocks,
    and possibly into a temporary file if "too much" content arrives.  */
 struct svn_ra_serf__pending_t {
-  /* The amount of content in memory.  */
-  apr_size_t memory_size;
-
-  /* HEAD points to the first block of the linked list of buffers.
-     TAIL points to the last block, for quickly appending more blocks
-     to the overall list.  */
-  struct pending_buffer_t *head;
-  struct pending_buffer_t *tail;
-
-  /* Available blocks for storing pending data. These were allocated
-     previously, then the data consumed and returned to this list.  */
-  struct pending_buffer_t *avail;
-
-  /* Once MEMORY_SIZE exceeds SPILL_SIZE, then arriving content will be
-     appended to the (temporary) file indicated by SPILL.  */
-  apr_file_t *spill;
-
-  /* As we consume content from SPILL, this value indicates where we
-     will begin reading.  */
-  apr_off_t spill_start;
+  /* The spillbuf where we record the pending data.  */
+  svn_spillbuf_t *buf;
 
   /* This flag is set when the network has reached EOF. The PENDING
      processing can then properly detect when parsing has completed.  */
   svn_boolean_t network_eof;
 };
 
-#define HAS_PENDING_DATA(p) ((p) != NULL \
-                             && ((p)->head != NULL || (p)->spill != NULL))
-
-/* We will store one megabyte in memory, before switching to store content
-   into a temporary file.  */
-#define SPILL_SIZE 1000000
+#define HAS_PENDING_DATA(p) ((p) != NULL && (p)->buf != NULL \
+                             && svn_spillbuf__get_size((p)->buf) != 0)
 
-/* See notes/ra-serf-testing.txt for some information on testing this
-   new "paused" feature (aka network pushback).
 
-   Define PBTEST_ACTIVE, if you would like to run the pushback tests.  */
-#undef PBTEST_ACTIVE
-#ifdef PBTEST_ACTIVE
-
-static int pbtest_step = 0;
-
-/* Note: this cannot resolve states 5 and 7.  */
-#define PBTEST_STATE(p) \
-  ((p) == NULL ? 1                                                 \
-               : ((p)->spill == NULL ? ((p)->head == NULL ? 2 : 3) \
-                                     : ((p)->head == NULL ? 6 : 4)))
-
-/* Note: INJECT and COMPLETED are only used for debug output.  */
-typedef struct {
-  svn_boolean_t paused;   /* pause the parser on this step?  */
-  svn_boolean_t inject;   /* inject pending content on this step?  */
-  int when_next;          /* when to move to the next step?  */
-  const char *completed;  /* what test was completed?  */
-} pbtest_desc_t;
-
-static const pbtest_desc_t pbtest_description[] = {
-  { 0 }, /* unused */
-  { TRUE,  FALSE, 3, "1.1" },
-  { TRUE,  FALSE, 3, "1.3" },
-  { FALSE, FALSE, 3, "2.3" },
-  { FALSE, TRUE,  2, "3.3" },  /* WHEN_NEXT is ignored due to INJECT  */
-  { TRUE,  FALSE, 3, "1.2" },
-  { TRUE,  FALSE, 4, NULL  },
-  { TRUE,  FALSE, 4, "1.4" },
-  { FALSE, FALSE, 4, "2.4" },
-  { FALSE, TRUE,  6, "3.4" },  /* WHEN_NEXT is ignored due to INJECT  */
-  { TRUE,  FALSE, 6, "1.6" },
-  { FALSE, FALSE, 6, "2.6" },
-  { FALSE, TRUE,  7, "3.6" },  /* WHEN_NEXT is ignored due to INJECT  */
-  { TRUE,  FALSE, 6, "1.7" },
-  { 0 } /* unused */
-};
-
-#define PBTEST_SET_PAUSED(ctx) \
-  (PBTEST_THIS_REQ(ctx) && pbtest_step < 14                  \
-   ? (ctx)->paused = pbtest_description[pbtest_step].paused  \
-   : FALSE)
-
-#define PBTEST_MAYBE_STEP(ctx, force) maybe_next_step(ctx, force)
-
-#define PBTEST_FORCE_SPILL(ctx) (PBTEST_THIS_REQ(ctx) && pbtest_step == 6)
-
-#define PBTEST_THIS_REQ(ctx) \
-  ((ctx)->response_type != NULL \
-   && strcmp((ctx)->response_type, "update-report") == 0)
-
-#else /* PBTEST_ACTIVE  */
-
-/* Be wary with the definition of these macros so that we don't
-   end up with "statement with no effect" warnings. Obviously, this
-   depends upon particular usage, which is easy to verify.  */
-#define PBTEST_SET_PAUSED(ctx)  /* empty */
-#define PBTEST_MAYBE_STEP(ctx, force)  /* empty */
-
-#define PBTEST_FORCE_SPILL(ctx) FALSE
-#define PBTEST_THIS_REQ(ctx) FALSE
-
-#endif /* PBTEST_ACTIVE  */
-
-
-
 static const apr_uint32_t serf_failure_map[][2] =
 {
   { SERF_SSL_CERT_NOTYETVALID,   SVN_AUTH_SSL_NOTYETVALID },
@@ -504,11 +411,13 @@ svn_ra_serf__conn_setup(apr_socket_t *so
   return status;
 }
 
-serf_bucket_t*
-svn_ra_serf__accept_response(serf_request_t *request,
-                             serf_bucket_t *stream,
-                             void *acceptor_baton,
-                             apr_pool_t *pool)
+
+/* Our default serf response acceptor.  */
+static serf_bucket_t *
+accept_response(serf_request_t *request,
+                serf_bucket_t *stream,
+                void *acceptor_baton,
+                apr_pool_t *pool)
 {
   serf_bucket_t *c;
   serf_bucket_alloc_t *bkt_alloc;
@@ -519,7 +428,9 @@ svn_ra_serf__accept_response(serf_reques
   return serf_bucket_response_create(c, bkt_alloc);
 }
 
-static serf_bucket_t*
+
+/* Custom response acceptor for HEAD requests.  */
+static serf_bucket_t *
 accept_head(serf_request_t *request,
             serf_bucket_t *stream,
             void *acceptor_baton,
@@ -527,8 +438,7 @@ accept_head(serf_request_t *request,
 {
   serf_bucket_t *response;
 
-  response = svn_ra_serf__accept_response(request, stream, acceptor_baton,
-                                          pool);
+  response = accept_response(request, stream, acceptor_baton, pool);
 
   /* We know we shouldn't get a response body. */
   serf_bucket_response_set_head(response);
@@ -698,41 +608,91 @@ apr_status_t svn_ra_serf__handle_client_
 }
 
 
-svn_error_t *
-svn_ra_serf__setup_serf_req(serf_request_t *request,
-                            serf_bucket_t **req_bkt,
-                            serf_bucket_t **ret_hdrs_bkt,
-                            svn_ra_serf__connection_t *conn,
-                            const char *method, const char *url,
-                            serf_bucket_t *body_bkt, const char *content_type)
-{
-  serf_bucket_t *hdrs_bkt;
+/*
+ * Given a REQUEST on connection CONN, construct a request bucket for it,
+ * returning the bucket in *REQ_BKT.
+ *
+ * If HDRS_BKT is not-NULL, it will be set to a headers_bucket that
+ * corresponds to the new request.
+ *
+ * The request will be METHOD at URL.
+ *
+ * If BODY_BKT is not-NULL, it will be sent as the request body.
+ *
+ * If CONTENT_TYPE is not-NULL, it will be sent as the Content-Type header.
+ *
+ * REQUEST_POOL should live for the duration of the request. Serf will
+ * construct this and provide it to the request_setup callback, so we
+ * should just use that one.
+ */
+static svn_error_t *
+setup_serf_req(serf_request_t *request,
+               serf_bucket_t **req_bkt,
+               serf_bucket_t **hdrs_bkt,
+               svn_ra_serf__connection_t *conn,
+               const char *method, const char *url,
+               serf_bucket_t *body_bkt, const char *content_type,
+               apr_pool_t *request_pool,
+               apr_pool_t *scratch_pool)
+{
+  serf_bucket_alloc_t *allocator = serf_request_get_alloc(request);
+
+#if SERF_VERSION_AT_LEAST(1, 1, 0)
+  svn_spillbuf_t *buf;
+
+  if (conn->http10 && body_bkt != NULL)
+    {
+      /* Ugh. Use HTTP/1.0 to talk to the server because we don't know if
+         it speaks HTTP/1.1 (and thus, chunked requests), or because the
+         server actually responded as only supporting HTTP/1.0.
+
+         We'll take the existing body_bkt, spool it into a spillbuf, and
+         then wrap a bucket around that spillbuf. The spillbuf will give
+         us the Content-Length value.  */
+      SVN_ERR(svn_ra_serf__copy_into_spillbuf(&buf, body_bkt,
+                                              request_pool,
+                                              scratch_pool));
+      body_bkt = svn_ra_serf__create_sb_bucket(buf, allocator,
+                                               request_pool,
+                                               scratch_pool);
+    }
+#endif
 
   /* Create a request bucket.  Note that this sucker is kind enough to
      add a "Host" header for us.  */
-  *req_bkt =
-    serf_request_bucket_request_create(request, method, url, body_bkt,
-                                       serf_request_get_alloc(request));
+  *req_bkt = serf_request_bucket_request_create(request, method, url,
+                                                body_bkt, allocator);
+
+  /* Set the Content-Length value. This will also trigger an HTTP/1.0
+     request (rather than the default chunked request).  */
+#if SERF_VERSION_AT_LEAST(1, 1, 0)
+  if (conn->http10)
+    {
+      if (body_bkt == NULL)
+        serf_bucket_request_set_CL(*req_bkt, 0);
+      else
+        serf_bucket_request_set_CL(*req_bkt, svn_spillbuf__get_size(buf));
+    }
+#endif
+
+  *hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);
 
-  hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);
-  serf_bucket_headers_setn(hdrs_bkt, "User-Agent", conn->useragent);
+  /* We use serf_bucket_headers_setn() because the string below have a
+     lifetime longer than this bucket. Thus, there is no need to copy
+     the header values.  */
+  serf_bucket_headers_setn(*hdrs_bkt, "User-Agent", conn->useragent);
 
   if (content_type)
     {
-      serf_bucket_headers_setn(hdrs_bkt, "Content-Type", content_type);
+      serf_bucket_headers_setn(*hdrs_bkt, "Content-Type", content_type);
     }
 
   /* These headers need to be sent with every request; see issue #3255
      ("mod_dav_svn does not pass client capabilities to start-commit
      hooks") for why. */
-  serf_bucket_headers_set(hdrs_bkt, "DAV", SVN_DAV_NS_DAV_SVN_DEPTH);
-  serf_bucket_headers_set(hdrs_bkt, "DAV", SVN_DAV_NS_DAV_SVN_MERGEINFO);
-  serf_bucket_headers_set(hdrs_bkt, "DAV", SVN_DAV_NS_DAV_SVN_LOG_REVPROPS);
-
-  if (ret_hdrs_bkt)
-    {
-      *ret_hdrs_bkt = hdrs_bkt;
-    }
+  serf_bucket_headers_setn(*hdrs_bkt, "DAV", SVN_DAV_NS_DAV_SVN_DEPTH);
+  serf_bucket_headers_setn(*hdrs_bkt, "DAV", SVN_DAV_NS_DAV_SVN_MERGEINFO);
+  serf_bucket_headers_setn(*hdrs_bkt, "DAV", SVN_DAV_NS_DAV_SVN_LOG_REVPROPS);
 
   return SVN_NO_ERROR;
 }
@@ -801,11 +761,11 @@ svn_ra_serf__context_run_wait(svn_boolea
  */
 static svn_error_t *
 start_error(svn_ra_serf__xml_parser_t *parser,
-            void *userData,
             svn_ra_serf__dav_props_t name,
-            const char **attrs)
+            const char **attrs,
+            apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__server_error_t *ctx = userData;
+  svn_ra_serf__server_error_t *ctx = parser->user_data;
 
   if (!ctx->in_error &&
       strcmp(name.namespace, "DAV:") == 0 &&
@@ -843,10 +803,10 @@ start_error(svn_ra_serf__xml_parser_t *p
  */
 static svn_error_t *
 end_error(svn_ra_serf__xml_parser_t *parser,
-          void *userData,
-          svn_ra_serf__dav_props_t name)
+          svn_ra_serf__dav_props_t name,
+          apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__server_error_t *ctx = userData;
+  svn_ra_serf__server_error_t *ctx = parser->user_data;
 
   if (ctx->in_error &&
       strcmp(name.namespace, "DAV:") == 0 &&
@@ -881,11 +841,11 @@ end_error(svn_ra_serf__xml_parser_t *par
  */
 static svn_error_t *
 cdata_error(svn_ra_serf__xml_parser_t *parser,
-            void *userData,
             const char *data,
-            apr_size_t len)
+            apr_size_t len,
+            apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__server_error_t *ctx = userData;
+  svn_ra_serf__server_error_t *ctx = parser->user_data;
 
   if (ctx->collect_cdata)
     {
@@ -1068,11 +1028,11 @@ parse_dav_status(int *status_code_out, s
  */
 static svn_error_t *
 start_207(svn_ra_serf__xml_parser_t *parser,
-          void *userData,
           svn_ra_serf__dav_props_t name,
-          const char **attrs)
+          const char **attrs,
+          apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__server_error_t *ctx = userData;
+  svn_ra_serf__server_error_t *ctx = parser->user_data;
 
   if (!ctx->in_error &&
       strcmp(name.namespace, "DAV:") == 0 &&
@@ -1103,10 +1063,10 @@ start_207(svn_ra_serf__xml_parser_t *par
  */
 static svn_error_t *
 end_207(svn_ra_serf__xml_parser_t *parser,
-        void *userData,
-        svn_ra_serf__dav_props_t name)
+        svn_ra_serf__dav_props_t name,
+        apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__server_error_t *ctx = userData;
+  svn_ra_serf__server_error_t *ctx = parser->user_data;
 
   if (ctx->in_error &&
       strcmp(name.namespace, "DAV:") == 0 &&
@@ -1147,11 +1107,11 @@ end_207(svn_ra_serf__xml_parser_t *parse
  */
 static svn_error_t *
 cdata_207(svn_ra_serf__xml_parser_t *parser,
-          void *userData,
           const char *data,
-          apr_size_t len)
+          apr_size_t len,
+          apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__server_error_t *ctx = userData;
+  svn_ra_serf__server_error_t *ctx = parser->user_data;
 
   if (ctx->collect_cdata)
     {
@@ -1252,11 +1212,14 @@ svn_ra_serf__handle_multistatus_only(ser
   return svn_error_trace(err);
 }
 
+
+/* Conforms to Expat's XML_StartElementHandler  */
 static void
 start_xml(void *userData, const char *raw_name, const char **attrs)
 {
   svn_ra_serf__xml_parser_t *parser = userData;
   svn_ra_serf__dav_props_t name;
+  apr_pool_t *scratch_pool;
 
   if (parser->error)
     return;
@@ -1264,31 +1227,43 @@ start_xml(void *userData, const char *ra
   if (!parser->state)
     svn_ra_serf__xml_push_state(parser, 0);
 
+  /* ### get a real scratch_pool  */
+  scratch_pool = parser->state->pool;
+
   svn_ra_serf__define_ns(&parser->state->ns_list, attrs, parser->state->pool);
 
   svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
 
-  parser->error = parser->start(parser, parser->user_data, name, attrs);
+  parser->error = parser->start(parser, name, attrs, scratch_pool);
 }
 
+
+/* Conforms to Expat's XML_EndElementHandler  */
 static void
 end_xml(void *userData, const char *raw_name)
 {
   svn_ra_serf__xml_parser_t *parser = userData;
   svn_ra_serf__dav_props_t name;
+  apr_pool_t *scratch_pool;
 
   if (parser->error)
     return;
 
+  /* ### get a real scratch_pool  */
+  scratch_pool = parser->state->pool;
+
   svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
 
-  parser->error = parser->end(parser, parser->user_data, name);
+  parser->error = parser->end(parser, name, scratch_pool);
 }
 
+
+/* Conforms to Expat's XML_CharacterDataHandler  */
 static void
 cdata_xml(void *userData, const char *data, int len)
 {
   svn_ra_serf__xml_parser_t *parser = userData;
+  apr_pool_t *scratch_pool;
 
   if (parser->error)
     return;
@@ -1296,7 +1271,10 @@ cdata_xml(void *userData, const char *da
   if (!parser->state)
     svn_ra_serf__xml_push_state(parser, 0);
 
-  parser->error = parser->cdata(parser, parser->user_data, data, len);
+  /* ### get a real scratch_pool  */
+  scratch_pool = parser->state->pool;
+
+  parser->error = parser->cdata(parser, data, len, scratch_pool);
 }
 
 /* Flip the requisite bits in CTX to indicate that processing of the
@@ -1319,157 +1297,24 @@ add_done_item(svn_ra_serf__xml_parser_t 
 }
 
 
-#ifdef PBTEST_ACTIVE
-
-/* Determine whether we should move to the next step. Print out the
-   transition for debugging purposes. If FORCE is TRUE, then we
-   definitely make a step (injection has completed).  */
-static void
-maybe_next_step(svn_ra_serf__xml_parser_t *parser, svn_boolean_t force)
-{
-  const pbtest_desc_t *desc;
-  int state;
-
-  /* This would fail the state transition, but for clarity... just return
-     when the testing has completed.  */
-  if (pbtest_step == 14)
-    return;
-
-  /* If this is not the request running the test, then exit.  */
-  if (!PBTEST_THIS_REQ(parser))
-    return;
-
-  desc = &pbtest_description[pbtest_step];
-  state = PBTEST_STATE(parser->pending);
-
-  /* Forced? ... or reached target state?  */
-  if (force || state == desc->when_next)
-    {
-      ++pbtest_step;
-
-      if (desc->completed != NULL)
-        SVN_DBG(("PBTEST: completed TEST %s\n", desc->completed));
-
-      /* Pause the parser based on the new step's config.  */
-      ++desc;
-      parser->paused = desc->paused;
-
-      SVN_DBG(("PBTEST: advanced: step=%d  paused=%d  inject=%d  state=%d\n",
-               pbtest_step, desc->paused, desc->inject, state));
-    }
-  else
-    {
-      SVN_DBG(("PBTEST: step[%d]: state=%d  waiting_for=%d\n",
-               pbtest_step, state, desc->when_next));
-    }
-}
-
-#endif /* PBTEST_ACTIVE  */
-
-
-/* Get a buffer from the parsing context. It will come from the free list,
-   or allocated as necessary.  */
-static struct pending_buffer_t *
-get_buffer(svn_ra_serf__xml_parser_t *parser)
-{
-  struct pending_buffer_t *pb;
-
-  if (parser->pending->avail == NULL)
-    return apr_palloc(parser->pool, sizeof(*pb));
-
-  pb = parser->pending->avail;
-  parser->pending->avail = pb->next;
-  return pb;
-}
-
-
-/* Return PB to the list of available buffers in PARSER.  */
-static void
-return_buffer(svn_ra_serf__xml_parser_t *parser,
-              struct pending_buffer_t *pb)
-{
-  pb->next = parser->pending->avail;
-  parser->pending->avail = pb;
-}
-
-
 static svn_error_t *
 write_to_pending(svn_ra_serf__xml_parser_t *ctx,
                  const char *data,
                  apr_size_t len,
                  apr_pool_t *scratch_pool)
 {
-  struct pending_buffer_t *pb;
-
-  /* The caller should not have provided us more than we can store into
-     a single memory block.  */
-  SVN_ERR_ASSERT(len <= PARSE_CHUNK_SIZE);
-
   if (ctx->pending == NULL)
-    ctx->pending = apr_pcalloc(ctx->pool, sizeof(*ctx->pending));
-
-  /* We do not (yet) have a spill file, but the amount stored in memory
-     has grown too large. Create the file and place the pending data into
-     the temporary file.
-
-     For testing purposes, there are points when we may want to
-     create the spill file, regardless.  */
-  if (PBTEST_FORCE_SPILL(ctx)
-      || (ctx->pending->spill == NULL
-          && ctx->pending->memory_size > SPILL_SIZE))
-    {
-#ifdef PBTEST_ACTIVE
-      /* Only allow a spill file for steps 6 or later.  */
-      if (!PBTEST_THIS_REQ(ctx) || pbtest_step >= 6)
-#endif
-      SVN_ERR(svn_io_open_unique_file3(&ctx->pending->spill,
-                                       NULL /* temp_path */,
-                                       NULL /* dirpath */,
-                                       svn_io_file_del_on_pool_cleanup,
-                                       ctx->pool, scratch_pool));
-    }
-
-  /* Once a spill file has been constructed, then we need to put all
-     arriving data into the file. We will no longer attempt to hold it
-     in memory.  */
-  if (ctx->pending->spill != NULL)
-    {
-      /* NOTE: we assume the file position is at the END. The caller should
-         ensure this, so that we will append.  */
-      SVN_ERR(svn_io_file_write_full(ctx->pending->spill, data, len,
-                                     NULL, scratch_pool));
-      return SVN_NO_ERROR;
-    }
-
-  /* We're still within bounds of holding the pending information in
-     memory. Get a buffer, copy the data there, and link it into our
-     pending data.  */
-  pb = get_buffer(ctx);
-  /* NOTE: *pb is uninitialized. All fields must be stored.  */
-
-  pb->size = len;
-  memcpy(pb->data, data, len);
-  pb->next = NULL;
-
-  /* Start a list of buffers, or append to the end of the linked list
-     of buffers.  */
-  if (ctx->pending->tail == NULL)
-    {
-      ctx->pending->head = pb;
-      ctx->pending->tail = pb;
-    }
-  else
     {
-      ctx->pending->tail->next = pb;
-      ctx->pending->tail = pb;
+      ctx->pending = apr_pcalloc(ctx->pool, sizeof(*ctx->pending));
+      ctx->pending->buf = svn_spillbuf__create(PARSE_CHUNK_SIZE,
+                                               SPILL_SIZE,
+                                               ctx->pool);
     }
 
-  /* We need to record how much is buffered in memory. Once we reach
-     SPILL_SIZE (or thereabouts, it doesn't have to be precise), then
-     we'll switch to putting the content into a file.  */
-  ctx->pending->memory_size += len;
-
-  return SVN_NO_ERROR;
+  /* Copy the data into one or more chunks in the spill buffer.  */
+  return svn_error_trace(svn_spillbuf__write(ctx->pending->buf,
+                                             data, len,
+                                             scratch_pool));
 }
 
 
@@ -1496,10 +1341,6 @@ inject_to_parser(svn_ra_serf__xml_parser
   if (ctx->error && !ctx->ignore_errors)
     return svn_error_trace(ctx->error);
 
-  /* We may want to ignore the callbacks choice for the PAUSED flag.
-     Set this value, as appropriate.  */
-  PBTEST_SET_PAUSED(ctx);
-
   return SVN_NO_ERROR;
 }
 
@@ -1523,23 +1364,6 @@ svn_error_t *
 svn_ra_serf__process_pending(svn_ra_serf__xml_parser_t *parser,
                              apr_pool_t *scratch_pool)
 {
-  struct pending_buffer_t *pb;
-  svn_error_t *err;
-  apr_off_t output_unused;
-
-  /* We may need to repair the PAUSED state when testing.  */
-  PBTEST_SET_PAUSED(parser);
-
-#ifdef PBTEST_ACTIVE
-  /* If this step should not inject content, then fast-path exit.  */
-  if (PBTEST_THIS_REQ(parser)
-      && pbtest_step < 14 && !pbtest_description[pbtest_step].inject)
-    {
-      SVN_DBG(("PBTEST: process: injection disabled\n"));
-      return SVN_NO_ERROR;
-    }
-#endif
-
   /* Fast path exit: already paused, nothing to do, or already done.  */
   if (parser->paused || parser->pending == NULL || *parser->done)
     return SVN_NO_ERROR;
@@ -1547,107 +1371,35 @@ svn_ra_serf__process_pending(svn_ra_serf
   /* ### it is possible that the XML parsing of the pending content is
      ### so slow, and that we don't return to reading the connection
      ### fast enough... that the server will disconnect us. right now,
-     ### that is highly improbably, but is noted for future's sake.
+     ### that is highly improbable, but is noted for future's sake.
      ### should that ever happen, the loops in this function can simply
      ### terminate after N seconds.  */
 
-  /* Empty out memory buffers until we run out, or we get paused again.  */
-  while (parser->pending->head != NULL)
-    {
-      /* Pull the HEAD buffer out of the list.  */
-      pb = parser->pending->head;
-      if (parser->pending->tail == pb)
-        parser->pending->head = parser->pending->tail = NULL;
-      else
-        parser->pending->head = pb->next;
-
-      /* We're using less memory now. If we haven't hit the spill file,
-         then we may be able to keep using memory.  */
-      parser->pending->memory_size -= pb->size;
-
-      err = inject_to_parser(parser, pb->data, pb->size, NULL);
-
-      return_buffer(parser, pb);
-
-      if (err)
-        return svn_error_trace(err);
-
-      /* If the callbacks paused us, then we're done for now.  */
-      if (parser->paused)
-        return SVN_NO_ERROR;
-    }
-
-#ifdef PBTEST_ACTIVE
-  /* For steps 4 and 9, we wait until all of the memory content has been
-     injected. At that point, we can take another step which will pause
-     the parser, and we'll need to exit.  */
-  if (PBTEST_THIS_REQ(parser)
-      && (pbtest_step == 4 || pbtest_step == 9))
-    {
-      PBTEST_MAYBE_STEP(parser, TRUE);
-      return SVN_NO_ERROR;
-    }
-#endif
-
-  /* If we don't have a spill file, then we've exhausted all
-     pending content.  */
-  if (parser->pending->spill == NULL)
-    goto pending_empty;
-
-  /* Seek once to where we left off reading.  */
-  output_unused = parser->pending->spill_start;  /* ### stupid API  */
-  SVN_ERR(svn_io_file_seek(parser->pending->spill,
-                           APR_SET, &output_unused,
-                           scratch_pool));
-
-  /* We need a buffer for reading out of the file. One of these will always
-     exist by the time we start reading from the spill file.  */
-  pb = get_buffer(parser);
-
-  /* Keep reading until we hit EOF, or get paused again.  */
+  /* Try to read everything from the spillbuf.  */
   while (TRUE)
     {
-      apr_size_t len = sizeof(pb->data);
-      apr_status_t status;
-
-      /* Read some data and remember where we left off.  */
-      status = apr_file_read(parser->pending->spill, pb->data, &len);
-      if (status && !APR_STATUS_IS_EOF(status))
-        {
-          err = svn_error_wrap_apr(status, NULL);
-          break;
-        }
-      parser->pending->spill_start += len;
+      const char *data;
+      apr_size_t len;
 
-      err = inject_to_parser(parser, pb->data, len, NULL);
-      if (err)
+      /* Get a block of content, stopping the loop when we run out.  */
+      SVN_ERR(svn_spillbuf__read(&data, &len, parser->pending->buf,
+                                 scratch_pool));
+      if (data == NULL)
         break;
 
-      /* If we just consumed everything in the spill file, then we may
-         be done with the parsing.  */
-      /* ### future change: when we hit EOF, then remove the spill file.
-         ### we could go back to using memory for a while.  */
-      if (APR_STATUS_IS_EOF(status))
-        goto pending_empty;
+      /* Inject the content into the XML parser.  */
+      SVN_ERR(inject_to_parser(parser, data, len, NULL));
 
-      /* If the callbacks paused the parsing, then we're done for now.  */
+      /* If the XML parsing callbacks paused us, then we're done for now.  */
       if (parser->paused)
-        break;
+        return SVN_NO_ERROR;
     }
+  /* All stored content (memory and file) has now been exhausted.  */
 
-  return_buffer(parser, pb);
-  return svn_error_trace(err);  /* may be SVN_NO_ERROR  */
-
- pending_empty:
   /* If the PENDING structures are empty *and* we consumed all content from
      the network, then we're completely done with the parsing.  */
   if (parser->pending->network_eof)
     {
-#ifdef PBTEST_ACTIVE
-      if (PBTEST_THIS_REQ(parser))
-        SVN_DBG(("process: terminating parse.\n"));
-#endif
-
       SVN_ERR_ASSERT(parser->xmlp != NULL);
 
       /* Tell the parser that no more content will be parsed. Ignore the
@@ -1659,10 +1411,6 @@ svn_ra_serf__process_pending(svn_ra_serf
       add_done_item(parser);
     }
 
-  /* For testing step 12, we have written all of the disk content. This
-     will advance to step 13 and pause the parser again.  */
-  PBTEST_MAYBE_STEP(parser, TRUE);
-
   return SVN_NO_ERROR;
 }
 
@@ -1738,25 +1486,6 @@ svn_ra_serf__handle_xml_parser(serf_requ
         {
           XML_SetCharacterDataHandler(ctx->xmlp, cdata_xml);
         }
-
-      /* This is the first invocation. If we're looking at an update
-         report, then move to step 1 of the testing sequence.  */
-#ifdef PBTEST_ACTIVE
-      if (PBTEST_THIS_REQ(ctx))
-        PBTEST_MAYBE_STEP(ctx, TRUE);
-#endif
-    }
-
-  /* If we are storing content into a spill file, then move to the end of
-     the file. We need to pre-position the file so that write_to_pending()
-     will always append the content.  */
-  if (ctx->pending != NULL && ctx->pending->spill != NULL)
-    {
-      apr_off_t output_unused = 0;  /* ### stupid API  */
-
-      SVN_ERR(svn_io_file_seek(ctx->pending->spill,
-                               APR_END, &output_unused,
-                               pool));
     }
 
   while (1)
@@ -1800,24 +1529,6 @@ svn_ra_serf__handle_xml_parser(serf_requ
           ctx->skip_size = 0;
         }
 
-      /* Ensure that the parser's PAUSED state is correct before we test
-         the flag.  */
-      PBTEST_SET_PAUSED(ctx);
-
-#ifdef PBTEST_ACTIVE
-      if (PBTEST_THIS_REQ(ctx))
-        {
-          SVN_DBG(("response: len=%d  paused=%d  status=%08x\n",
-                   (int)len, ctx->paused, status));
-#if 0
-          /* ### DATA is not necessarily NUL-terminated, but this
-             ### generally works. so if you want to see content... */
-          if (len > 0)
-            SVN_DBG(("content=%s\n", data));
-#endif
-        }
-#endif
-
       /* Note: once the callbacks invoked by inject_to_parser() sets the
          PAUSED flag, then it will not be cleared. write_to_pending() will
          only save the content. Logic outside of serf_context_run() will
@@ -1830,13 +1541,6 @@ svn_ra_serf__handle_xml_parser(serf_requ
       if (ctx->paused || HAS_PENDING_DATA(ctx->pending))
         {
           err = write_to_pending(ctx, data, len, pool);
-
-          /* We may have a transition to a next step.
-
-             Note: this only happens on writing to PENDING. If the
-             parser is unpaused, then we will never change state within
-             this network-reading loop.  */
-          PBTEST_MAYBE_STEP(ctx, FALSE);
         }
       else
         {
@@ -1866,20 +1570,10 @@ svn_ra_serf__handle_xml_parser(serf_requ
           if (ctx->pending != NULL)
             ctx->pending->network_eof = TRUE;
 
-#ifdef PBTEST_ACTIVE
-          if (PBTEST_THIS_REQ(ctx))
-            SVN_DBG(("network: reached EOF.\n"));
-#endif
-
           /* We just hit the end of the network content. If we have nothing
              in the PENDING structures, then we're completely done.  */
           if (!HAS_PENDING_DATA(ctx->pending))
             {
-#ifdef PBTEST_ACTIVE
-              if (PBTEST_THIS_REQ(ctx))
-                SVN_DBG(("network: terminating parse.\n"));
-#endif
-
               SVN_ERR_ASSERT(ctx->xmlp != NULL);
 
               /* Ignore the return status. We just don't care.  */
@@ -2153,68 +1847,55 @@ handle_response_cb(serf_request_t *reque
   return serf_status;
 }
 
-/* If the CTX->setup() callback is non-NULL, invoke it to carry out the
-   majority of the serf_request_setup_t implementation.  Otherwise, perform
-   default setup, with special handling for HEAD requests, and finer-grained
-   callbacks invoked (if non-NULL) to produce the request headers and
-   body. */
+/* Perform basic request setup, with special handling for HEAD requests,
+   and finer-grained callbacks invoked (if non-NULL) to produce the request
+   headers and body. */
 static svn_error_t *
 setup_request(serf_request_t *request,
-                 svn_ra_serf__handler_t *ctx,
-                 serf_bucket_t **req_bkt,
-                 serf_response_acceptor_t *acceptor,
-                 void **acceptor_baton,
-                 serf_response_handler_t *handler,
-                 void **handler_baton,
-                 apr_pool_t *pool)
+              svn_ra_serf__handler_t *ctx,
+              serf_bucket_t **req_bkt,
+              serf_response_acceptor_t *acceptor,
+              void **acceptor_baton,
+              serf_response_handler_t *handler,
+              void **handler_baton,
+              apr_pool_t *request_pool,
+              apr_pool_t *scratch_pool)
 {
+  serf_bucket_t *body_bkt;
   serf_bucket_t *headers_bkt;
 
-  *acceptor = svn_ra_serf__accept_response;
+  /* Default response acceptor.  */
+  *acceptor = accept_response;
   *acceptor_baton = ctx->session;
 
-  if (ctx->setup)
+  if (strcmp(ctx->method, "HEAD") == 0)
     {
-      svn_ra_serf__response_handler_t response_handler;
-      void *response_baton;
+      *acceptor = accept_head;
+    }
 
-      SVN_ERR(ctx->setup(request, ctx->setup_baton, req_bkt,
-                         acceptor, acceptor_baton,
-                         &response_handler, &response_baton,
-                         pool));
+  if (ctx->body_delegate)
+    {
+      serf_bucket_alloc_t *bkt_alloc = serf_request_get_alloc(request);
 
-      ctx->response_handler = response_handler;
-      ctx->response_baton = response_baton;
+      /* ### should pass the scratch_pool  */
+      SVN_ERR(ctx->body_delegate(&body_bkt, ctx->body_delegate_baton,
+                                 bkt_alloc, request_pool));
     }
   else
     {
-      serf_bucket_t *body_bkt;
-      serf_bucket_alloc_t *bkt_alloc = serf_request_get_alloc(request);
-
-      if (strcmp(ctx->method, "HEAD") == 0)
-        {
-          *acceptor = accept_head;
-        }
-
-      if (ctx->body_delegate)
-        {
-          SVN_ERR(ctx->body_delegate(&body_bkt, ctx->body_delegate_baton,
-                                     bkt_alloc, pool));
-        }
-      else
-        {
-          body_bkt = NULL;
-        }
+      body_bkt = NULL;
+    }
 
-      SVN_ERR(svn_ra_serf__setup_serf_req(request, req_bkt, &headers_bkt,
-                                          ctx->conn, ctx->method, ctx->path,
-                                          body_bkt, ctx->body_type));
+  SVN_ERR(setup_serf_req(request, req_bkt, &headers_bkt,
+                         ctx->conn, ctx->method, ctx->path,
+                         body_bkt, ctx->body_type,
+                         request_pool, scratch_pool));
 
-      if (ctx->header_delegate)
-        {
-          SVN_ERR(ctx->header_delegate(headers_bkt, ctx->header_delegate_baton,
-                                       pool));
-        }
+  if (ctx->header_delegate)
+    {
+      /* ### should pass the scratch_pool  */
+      SVN_ERR(ctx->header_delegate(headers_bkt, ctx->header_delegate_baton,
+                                   request_pool));
     }
 
   *handler = handle_response_cb;
@@ -2239,11 +1920,15 @@ setup_request_cb(serf_request_t *request
   svn_ra_serf__handler_t *ctx = setup_baton;
   svn_error_t *err;
 
+  /* ### construct a scratch_pool? serf gives us a pool that will live for
+     ### the duration of the request.  */
+  apr_pool_t *scratch_pool = pool;
+
   err = setup_request(request, ctx,
                       req_bkt,
                       acceptor, acceptor_baton,
                       handler, handler_baton,
-                      pool);
+                      pool /* request_pool */, scratch_pool);
 
   if (err)
     {

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c Tue Apr  3 13:32:48 2012
@@ -124,34 +124,6 @@ svn_ra_serf__expand_ns(svn_ra_serf__dav_
   return;
 }
 
-void
-svn_ra_serf__expand_string(const char **cur, apr_size_t *cur_len,
-                           const char *new, apr_size_t new_len,
-                           apr_pool_t *pool)
-{
-  if (!*cur)
-    {
-      *cur = apr_pstrmemdup(pool, new, new_len);
-      *cur_len = new_len;
-    }
-  else
-    {
-      char *new_cur;
-
-      /* append the data we received before. */
-      new_cur = apr_palloc(pool, *cur_len + new_len + 1);
-
-      memcpy(new_cur, *cur, *cur_len);
-      memcpy(new_cur + *cur_len, new, new_len);
-
-      /* NULL-term our new string */
-      new_cur[*cur_len + new_len] = '\0';
-
-      /* update our length */
-      *cur_len += new_len;
-      *cur = new_cur;
-    }
-}
 
 #define XML_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_svn/client.c Tue Apr  3 13:32:48 2012
@@ -1152,7 +1152,18 @@ static svn_error_t *ra_svn_get_dir(svn_r
       dirent->size = size;/* FIXME: svn_filesize_t */
       dirent->has_props = has_props;
       dirent->created_rev = crev;
-      SVN_ERR(svn_time_from_cstring(&dirent->time, cdate, pool));
+      /* NOTE: the tuple's format string says CDATE may be NULL. But this
+         function does not allow that. The server has always sent us some
+         random date, however, so this just happens to work. But let's
+         be wary of servers that are (improperly) fixed to send NULL.
+
+         Note: they should NOT be "fixed" to send NULL, as that would break
+         any older clients which received that NULL. But we may as well
+         be defensive against a malicous server.  */
+      if (cdate == NULL)
+        dirent->time = 0;
+      else
+        SVN_ERR(svn_time_from_cstring(&dirent->time, cdate, pool));
       dirent->last_author = cauthor;
       apr_hash_set(*dirents, name, APR_HASH_KEY_STRING, dirent);
     }

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/dump.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/dump.c Tue Apr  3 13:32:48 2012
@@ -1406,7 +1406,7 @@ svn_repos_verify_fs2(svn_repos_t *repos,
 
   for (rev = start_rev; rev <= end_rev; rev++)
     {
-      svn_delta_editor_t *dump_editor;
+      const svn_delta_editor_t *dump_editor;
       void *dump_edit_baton;
       const svn_delta_editor_t *cancel_editor;
       void *cancel_edit_baton;
@@ -1416,8 +1416,8 @@ svn_repos_verify_fs2(svn_repos_t *repos,
       svn_pool_clear(iterpool);
 
       /* Get cancellable dump editor, but with our close_directory handler. */
-      SVN_ERR(get_dump_editor((const svn_delta_editor_t **)&dump_editor,
-                              &dump_edit_baton, fs, rev, "",
+      SVN_ERR(get_dump_editor(&dump_editor, &dump_edit_baton,
+                              fs, rev, "",
                               svn_stream_empty(iterpool),
                               NULL, NULL,
                               verify_close_directory,

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/fs-wrap.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/fs-wrap.c Tue Apr  3 13:32:48 2012
@@ -162,7 +162,7 @@ svn_repos__validate_prop(const char *nam
                          const svn_string_t *value,
                          apr_pool_t *pool)
 {
-  svn_prop_kind_t kind = svn_property_kind(NULL, name);
+  svn_prop_kind_t kind = svn_property_kind2(name);
 
   /* Disallow setting non-regular properties. */
   if (kind != svn_prop_regular_kind)

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/hooks.c Tue Apr  3 13:32:48 2012
@@ -172,7 +172,7 @@ env_from_env_hash(apr_hash_t *env_hash,
   const char **env;
   const char **envp;
 
-  if (!env_hash || apr_hash_count(env_hash) == 0)
+  if (!env_hash)
     return NULL;
 
   env = apr_palloc(result_pool,

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/log.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/log.c Tue Apr  3 13:32:48 2012
@@ -1742,7 +1742,7 @@ reduce_search(apr_array_header_t *paths,
       if (!ranges)
         continue;
 
-      /* ranges is ordered, could we use some sort of binay search
+      /* ranges is ordered, could we use some sort of binary search
          rather than iterating? */
       for (j = 0; j < ranges->nelts; ++j)
         {

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cache-inprocess.c Tue Apr  3 13:32:48 2012
@@ -304,7 +304,7 @@ inprocess_cache_set_internal(inprocess_c
       cache->data_size -= existing_entry->size;
       if (value)
         {
-          SVN_ERR(cache->serialize_func((char **)&existing_entry->value,
+          SVN_ERR(cache->serialize_func(&existing_entry->value,
                                         &existing_entry->size,
                                         value,
                                         page->page_pool));
@@ -356,7 +356,7 @@ inprocess_cache_set_internal(inprocess_c
     new_entry->key = duplicate_key(cache, key, page->page_pool);
     if (value)
       {
-        SVN_ERR(cache->serialize_func((char **)&new_entry->value,
+        SVN_ERR(cache->serialize_func(&new_entry->value,
                                       &new_entry->size,
                                       value,
                                       page->page_pool));
@@ -512,10 +512,10 @@ inprocess_cache_set_partial_internal(inp
       SVN_ERR(move_page_to_front(cache, entry->page));
 
       cache->data_size -= entry->size;
-      SVN_ERR(func((char **)&entry->value,
-                  &entry->size,
-                  baton,
-                  entry->page->page_pool));
+      SVN_ERR(func(&entry->value,
+                   &entry->size,
+                   baton,
+                   entry->page->page_pool));
       cache->data_size += entry->size;
     }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cache-membuffer.c Tue Apr  3 13:32:48 2012
@@ -311,7 +311,7 @@ typedef struct entry_t
   /* Size of the serialized item data. May be 0.
    * Only valid for used entries.
    */
-  apr_uint32_t size;
+  apr_size_t size;
 
   /* Number of (read) hits for this entry. Will be reset upon write.
    * Only valid for used entries.
@@ -1162,7 +1162,7 @@ membuffer_cache_set(svn_membuffer_t *cac
 {
   apr_uint32_t group_index;
   unsigned char to_find[KEY_SIZE];
-  char *buffer = NULL;
+  void *buffer = NULL;
   apr_size_t size;
 
   /* find the entry group that will hold the key.
@@ -1457,7 +1457,7 @@ membuffer_cache_set_partial_internal(svn
 
       /* modify it, preferrably in-situ.
        */
-      err = func(&data, &size, baton, scratch_pool);
+      err = func((void **)&data, &size, baton, scratch_pool);
 
       if (err)
         {
@@ -2014,7 +2014,7 @@ static svn_cache__vtable_t membuffer_cac
  * Implements svn_cache__serialize_func_t.
  */
 static svn_error_t *
-serialize_svn_stringbuf(char **buffer,
+serialize_svn_stringbuf(void **buffer,
                         apr_size_t *buffer_size,
                         void *item,
                         apr_pool_t *result_pool)
@@ -2032,7 +2032,7 @@ serialize_svn_stringbuf(char **buffer,
  */
 static svn_error_t *
 deserialize_svn_stringbuf(void **item,
-                          char *buffer,
+                          void *buffer,
                           apr_size_t buffer_size,
                           apr_pool_t *result_pool)
 {

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cache-memcache.c Tue Apr  3 13:32:48 2012
@@ -247,7 +247,7 @@ memcache_set(void *cache_void,
 {
   memcache_t *cache = cache_void;
   apr_pool_t *subpool = svn_pool_create(scratch_pool);
-  char *data;
+  void *data;
   apr_size_t data_len;
   svn_error_t *err;
 
@@ -307,12 +307,12 @@ memcache_set_partial(void *cache_void,
 {
   svn_error_t *err = SVN_NO_ERROR;
 
-  char *data;
+  void *data;
   apr_size_t size;
   svn_boolean_t found = FALSE;
 
   apr_pool_t *subpool = svn_pool_create(scratch_pool);
-  SVN_ERR(memcache_internal_get(&data,
+  SVN_ERR(memcache_internal_get((char **)&data,
                                 &size,
                                 &found,
                                 cache_void,

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/checksum.c?rev=1308894&r1=1308893&r2=1308894&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/checksum.c Tue Apr  3 13:32:48 2012
@@ -278,7 +278,7 @@ svn_checksum(svn_checksum_t **checksum,
 
       case svn_checksum_sha1:
         apr_sha1_init(&sha1_ctx);
-        apr_sha1_update(&sha1_ctx, data, len);
+        apr_sha1_update(&sha1_ctx, data, (unsigned int)len);
         apr_sha1_final((unsigned char *)(*checksum)->digest, &sha1_ctx);
         break;
 
@@ -359,7 +359,7 @@ svn_checksum_update(svn_checksum_ctx_t *
         break;
 
       case svn_checksum_sha1:
-        apr_sha1_update(ctx->apr_ctx, data, len);
+        apr_sha1_update(ctx->apr_ctx, data, (unsigned int)len);
         break;
 
       default: