You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2011/01/13 21:03:51 UTC

svn commit: r1058723 - in /subversion/trunk/subversion/libsvn_ra_serf: commit.c merge.c options.c property.c ra_serf.h serf.c util.c

Author: cmpilato
Date: Thu Jan 13 20:03:50 2011
New Revision: 1058723

URL: http://svn.apache.org/viewvc?rev=1058723&view=rev
Log:
Fix issue #3601 ("ra_serf gets PROPFIND failure on certain non-ASCII
paths") by introducing into libsvn_ra_serf a utility function which
can canonicalize the various ways that URI-encoded paths get used
throughout this library.

* subversion/libsvn_ra_serf/ra_serf.h
  (svn_ra_serf__uri_canonicalize): New prototype.

* subversion/libsvn_ra_serf/util.c
  (relative_uri_normalize, svn_ra_serf__uri_canonicalize): New functions.
  (): Change all callers of svn_uri_canonicalize() to use
    svn_ra_serf__uri_canonicalize() instead.

* subversion/libsvn_ra_serf/commit.c,
* subversion/libsvn_ra_serf/merge.c,
* subversion/libsvn_ra_serf/options.c,
* subversion/libsvn_ra_serf/property.c,
* subversion/libsvn_ra_serf/serf.c
  Change all callers of svn_uri_canonicalize() to use
  svn_ra_serf__uri_canonicalize() instead.

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/commit.c
    subversion/trunk/subversion/libsvn_ra_serf/merge.c
    subversion/trunk/subversion/libsvn_ra_serf/options.c
    subversion/trunk/subversion/libsvn_ra_serf/property.c
    subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
    subversion/trunk/subversion/libsvn_ra_serf/serf.c
    subversion/trunk/subversion/libsvn_ra_serf/util.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/commit.c?rev=1058723&r1=1058722&r2=1058723&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/commit.c Thu Jan 13 20:03:50 2011
@@ -311,7 +311,8 @@ handle_checkout(serf_request_t *request,
       if (status)
         err = svn_error_compose_create(svn_error_wrap_apr(status, NULL), err);
 
-      ctx->resource_url = svn_uri_canonicalize(uri.path, ctx->pool);
+      ctx->resource_url = svn_ra_serf__uri_canonicalize(uri.path, pool,
+                                                        ctx->pool);
     }
 
   return err;
@@ -487,7 +488,8 @@ get_version_url(const char **checked_in_
 
       if (current_version)
         {
-          *checked_in_url = svn_uri_canonicalize(current_version->data, pool);
+          *checked_in_url =
+            svn_ra_serf__uri_canonicalize(current_version->data, pool, pool);
           return SVN_NO_ERROR;
         }
     }
@@ -542,7 +544,7 @@ get_version_url(const char **checked_in_
                                  _("Path '%s' not present"),
                                  session->repos_url.path);
 
-      root_checkout = svn_uri_canonicalize(root_checkout, pool);
+      root_checkout = svn_ra_serf__uri_canonicalize(root_checkout, pool, pool);
     }
 
   *checked_in_url = svn_path_url_add_component2(root_checkout, relpath, pool);

Modified: subversion/trunk/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/merge.c?rev=1058723&r1=1058722&r2=1058723&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/merge.c Thu Jan 13 20:03:50 2011
@@ -364,7 +364,8 @@ end_merge(svn_ra_serf__xml_parser_t *par
       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_uri_canonicalize(info->prop_val, info->pool);
+        info->prop_val = svn_ra_serf__uri_canonicalize(info->prop_val, 
+                                                       info->pool, info->pool);
 
       /* Set our property. */
       apr_hash_set(info->props, info->prop_name, APR_HASH_KEY_STRING,

Modified: subversion/trunk/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/options.c?rev=1058723&r1=1058722&r2=1058723&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/options.c Thu Jan 13 20:03:50 2011
@@ -187,7 +187,9 @@ end_options(svn_ra_serf__xml_parser_t *p
     {
       options_ctx->collect_cdata = FALSE;
       options_ctx->activity_collection =
-                 svn_uri_canonicalize(options_ctx->attr_val, options_ctx->pool);
+        svn_ra_serf__uri_canonicalize(options_ctx->attr_val,
+                                      options_ctx->pool,
+                                      options_ctx->pool);
       pop_state(options_ctx);
     }
 
@@ -336,10 +338,12 @@ capabilities_headers_iterator_callback(v
           orc->session->repos_root = orc->session->repos_url;
           orc->session->repos_root.path = apr_pstrdup(orc->session->pool, val);
           orc->session->repos_root_str =
-            svn_uri_canonicalize(apr_uri_unparse(orc->session->pool,
-                                                 &orc->session->repos_root,
-                                                 0),
-                                  orc->session->pool);
+            svn_ra_serf__uri_canonicalize(
+                apr_uri_unparse(orc->session->pool,
+                                &orc->session->repos_root,
+                                0),
+                orc->session->pool,
+                orc->session->pool);
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_ME_RESOURCE_HEADER) == 0)
         {

Modified: subversion/trunk/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/property.c?rev=1058723&r1=1058722&r2=1058723&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/property.c Thu Jan 13 20:03:50 2011
@@ -25,6 +25,7 @@
 
 #include <serf.h>
 
+#include "svn_path.h"
 #include "svn_base64.h"
 #include "svn_xml.h"
 #include "svn_props.h"
@@ -342,7 +343,8 @@ end_propfind(svn_ra_serf__xml_parser_t *
         {
           if (strcmp(ctx->depth, "1") == 0)
             {
-              ctx->current_path = svn_uri_canonicalize(info->val, ctx->pool);
+              ctx->current_path =
+                svn_ra_serf__uri_canonicalize(info->val, ctx->pool, ctx->pool);
             }
           else
             {
@@ -1032,7 +1034,8 @@ svn_ra_serf__get_baseline_info(const cha
                                         "the requested checked-in value"));
             }
 
-          baseline_url = svn_uri_canonicalize(baseline_url, pool);
+          baseline_url = svn_ra_serf__uri_canonicalize(baseline_url,
+                                                       pool, pool);
 
           SVN_ERR(svn_ra_serf__retrieve_props(props, session, conn,
                                               baseline_url, revision, "0",
@@ -1049,7 +1052,8 @@ svn_ra_serf__get_baseline_info(const cha
                                     "requested baseline-collection value"));
         }
 
-      basecoll_url = svn_uri_canonicalize(basecoll_url, pool);
+      basecoll_url = svn_ra_serf__uri_canonicalize(basecoll_url,
+                                                   pool, pool);
 
       if (latest_revnum)
         {

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=1058723&r1=1058722&r2=1058723&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Thu Jan 13 20:03:50 2011
@@ -794,6 +794,17 @@ const char *
 svn_ra_serf__response_get_location(serf_bucket_t *response,
                                    apr_pool_t *pool);
 
+/* Canonicalize URI, in the general sense.  URI might be a full,
+ * absolute, schema-ful URL.  It might be just the path portion of a
+ * URL.  Or it might be a relative path.  Whatever the case, it is a
+ * URI-encoded identifier of *some sort*, as will be the returned form
+ * thereof.
+ */
+const char *
+svn_ra_serf__uri_canonicalize(const char *uri,
+                              apr_pool_t *scratch_pool,
+                              apr_pool_t *result_pool);
+
 /** XML helper functions. **/
 
 /*

Modified: subversion/trunk/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/serf.c?rev=1058723&r1=1058722&r2=1058723&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/serf.c Thu Jan 13 20:03:50 2011
@@ -906,7 +906,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
        */
       dirent_walk.full_paths = apr_hash_make(pool);
       dirent_walk.base_paths = apr_hash_make(pool);
-      dirent_walk.orig_path = svn_uri_canonicalize(path, pool);
+      dirent_walk.orig_path = svn_ra_serf__uri_canonicalize(path, pool, pool);
 
       SVN_ERR(svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
                                           &dirent_walk, pool));

Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=1058723&r1=1058722&r2=1058723&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Thu Jan 13 20:03:50 2011
@@ -914,7 +914,7 @@ svn_ra_serf__response_get_location(serf_
 
   headers = serf_bucket_response_get_headers(response);
   val = serf_bucket_headers_get(headers, "Location");
-  return val ? svn_uri_canonicalize(val, pool) : NULL;
+  return val ? svn_ra_serf__uri_canonicalize(val, pool, pool) : NULL;
 }
 
 /* Implements svn_ra_serf__response_handler_t */
@@ -1837,9 +1837,9 @@ svn_ra_serf__discover_vcc(const char **v
       session->repos_root = session->repos_url;
       session->repos_root.path = apr_pstrdup(session->pool, url_buf->data);
       session->repos_root_str =
-        svn_uri_canonicalize(apr_uri_unparse(session->pool,
-                                             &session->repos_root, 0),
-                             session->pool);
+        svn_ra_serf__uri_canonicalize(apr_uri_unparse(session->pool,
+                                                      &session->repos_root, 0),
+                                      pool, session->pool);
     }
 
   /* Store the repository UUID in the cache. */
@@ -1934,3 +1934,35 @@ svn_ra_serf__error_on_status(int status_
 
   return SVN_NO_ERROR;
 }
+
+
+static const char *
+relative_uri_normalize(const char *relpath,
+                       apr_pool_t *scratch_pool,
+                       apr_pool_t *result_pool)
+{
+  return svn_path_uri_encode(
+             svn_relpath_canonicalize(
+                 svn_path_uri_decode(relpath, scratch_pool),
+                 scratch_pool),
+             result_pool);
+}
+
+
+const char *
+svn_ra_serf__uri_canonicalize(const char *uri,
+                              apr_pool_t *scratch_pool,
+                              apr_pool_t *result_pool)
+{
+  if (svn_path_is_url(uri))
+    return svn_uri_canonicalize(uri, result_pool);
+
+  if (uri[0] == '/')
+    return apr_pstrcat(result_pool, "/", 
+                       relative_uri_normalize(uri + 1,
+                                              scratch_pool,
+                                              scratch_pool),
+                       NULL);
+  
+  return relative_uri_normalize(uri, scratch_pool, result_pool);
+}