You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/01/15 18:47:24 UTC
svn commit: r1558485 [2/4] - in /subversion/branches/fsfs-ucsnorm: ./
subversion/bindings/javahl/native/
subversion/bindings/javahl/native/jniwrapper/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/javahl/tests/org/apa...
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c?rev=1558485&r1=1558484&r2=1558485&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/serf.c Wed Jan 15 17:47:23 2014
@@ -857,7 +857,8 @@ serf__rev_proplist(svn_ra_session_t *ra_
svn_revnum_t rev,
const svn_ra_serf__dav_props_t *fetch_props,
apr_hash_t **ret_props,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_ra_serf__session_t *session = ra_session->priv;
apr_hash_t *props;
@@ -865,7 +866,8 @@ serf__rev_proplist(svn_ra_session_t *ra_
if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
{
- propfind_path = apr_psprintf(pool, "%s/%ld", session->rev_stub, rev);
+ propfind_path = apr_psprintf(scratch_pool, "%s/%ld", session->rev_stub,
+ rev);
/* svn_ra_serf__retrieve_props() wants to added the revision as
a Label to the PROPFIND, which isn't really necessary when
@@ -876,16 +878,17 @@ serf__rev_proplist(svn_ra_session_t *ra_
else
{
/* Use the VCC as the propfind target path. */
- SVN_ERR(svn_ra_serf__discover_vcc(&propfind_path, session, NULL, pool));
+ SVN_ERR(svn_ra_serf__discover_vcc(&propfind_path, session, NULL,
+ scratch_pool));
}
/* ### fix: fetch hash of *just* the PATH@REV props. no nested hash. */
SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
propfind_path, rev, "0", fetch_props,
- pool, pool));
+ result_pool, scratch_pool));
SVN_ERR(svn_ra_serf__select_revprops(ret_props, propfind_path, rev, props,
- pool, pool));
+ result_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -895,11 +898,16 @@ static svn_error_t *
svn_ra_serf__rev_proplist(svn_ra_session_t *ra_session,
svn_revnum_t rev,
apr_hash_t **ret_props,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
- return svn_error_trace(
- serf__rev_proplist(ra_session, rev, all_props,
- ret_props, pool));
+ apr_pool_t *scratch_pool = svn_pool_create(result_pool);
+ svn_error_t *err;
+
+ err = serf__rev_proplist(ra_session, rev, all_props, ret_props,
+ result_pool, scratch_pool);
+
+ svn_pool_destroy(scratch_pool);
+ return svn_error_trace(err);
}
@@ -909,8 +917,9 @@ svn_ra_serf__rev_prop(svn_ra_session_t *
svn_revnum_t rev,
const char *name,
svn_string_t **value,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
+ apr_pool_t *scratch_pool = svn_pool_create(result_pool);
apr_hash_t *props;
svn_ra_serf__dav_props_t specific_props[2];
const svn_ra_serf__dav_props_t *fetch_props = all_props;
@@ -930,483 +939,12 @@ svn_ra_serf__rev_prop(svn_ra_session_t *
fetch_props = specific_props;
}
- SVN_ERR(serf__rev_proplist(session, rev, fetch_props, &props, pool));
+ SVN_ERR(serf__rev_proplist(session, rev, fetch_props, &props,
+ result_pool, scratch_pool));
*value = svn_hash_gets(props, name);
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-fetch_path_props(apr_hash_t **props,
- svn_ra_serf__session_t *session,
- const char *session_relpath,
- svn_revnum_t revision,
- const svn_ra_serf__dav_props_t *desired_props,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- const char *url;
-
- url = session->session_url.path;
-
- /* If we have a relative path, append it. */
- if (session_relpath)
- url = svn_path_url_add_component2(url, session_relpath, scratch_pool);
-
- /* If we were given a specific revision, get a URL that refers to that
- specific revision (rather than floating with HEAD). */
- if (SVN_IS_VALID_REVNUM(revision))
- {
- SVN_ERR(svn_ra_serf__get_stable_url(&url, NULL /* latest_revnum */,
- session, NULL /* conn */,
- url, revision,
- scratch_pool, scratch_pool));
- }
-
- /* URL is stable, so we use SVN_INVALID_REVNUM since it is now irrelevant.
- Or we started with SVN_INVALID_REVNUM and URL may be floating. */
- SVN_ERR(svn_ra_serf__fetch_node_props(props, session->conns[0],
- url, SVN_INVALID_REVNUM,
- desired_props,
- result_pool, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-/* Implements svn_ra__vtable_t.check_path(). */
-static svn_error_t *
-svn_ra_serf__check_path(svn_ra_session_t *ra_session,
- const char *rel_path,
- svn_revnum_t revision,
- svn_node_kind_t *kind,
- apr_pool_t *pool)
-{
- svn_ra_serf__session_t *session = ra_session->priv;
- apr_hash_t *props;
-
- svn_error_t *err = fetch_path_props(&props, session, rel_path,
- revision, check_path_props,
- pool, pool);
-
- if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
- {
- svn_error_clear(err);
- *kind = svn_node_none;
- }
- else
- {
- /* Any other error, raise to caller. */
- if (err)
- return svn_error_trace(err);
-
- SVN_ERR(svn_ra_serf__get_resource_type(kind, props));
- }
-
- return SVN_NO_ERROR;
-}
-
-
-struct dirent_walker_baton_t {
- /* Update the fields in this entry. */
- svn_dirent_t *entry;
-
- svn_tristate_t *supports_deadprop_count;
-
- /* If allocations are necessary, then use this pool. */
- apr_pool_t *result_pool;
-};
-
-static svn_error_t *
-dirent_walker(void *baton,
- const char *ns,
- const char *name,
- const svn_string_t *val,
- apr_pool_t *scratch_pool)
-{
- struct dirent_walker_baton_t *dwb = baton;
-
- if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
- {
- dwb->entry->has_props = TRUE;
- }
- else if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
- {
- dwb->entry->has_props = TRUE;
- }
- else if (strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0)
- {
- if(strcmp(name, "deadprop-count") == 0)
- {
- if (*val->data)
- {
- apr_int64_t deadprop_count;
- SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
- dwb->entry->has_props = deadprop_count > 0;
- if (dwb->supports_deadprop_count)
- *dwb->supports_deadprop_count = svn_tristate_true;
- }
- else if (dwb->supports_deadprop_count)
- *dwb->supports_deadprop_count = svn_tristate_false;
- }
- }
- else if (strcmp(ns, "DAV:") == 0)
- {
- if (strcmp(name, SVN_DAV__VERSION_NAME) == 0)
- {
- dwb->entry->created_rev = SVN_STR_TO_REV(val->data);
- }
- else if (strcmp(name, "creator-displayname") == 0)
- {
- dwb->entry->last_author = val->data;
- }
- else if (strcmp(name, SVN_DAV__CREATIONDATE) == 0)
- {
- SVN_ERR(svn_time_from_cstring(&dwb->entry->time,
- val->data,
- dwb->result_pool));
- }
- else if (strcmp(name, "getcontentlength") == 0)
- {
- /* 'getcontentlength' property is empty for directories. */
- if (val->len)
- {
- SVN_ERR(svn_cstring_atoi64(&dwb->entry->size, val->data));
- }
- }
- else if (strcmp(name, "resourcetype") == 0)
- {
- if (strcmp(val->data, "collection") == 0)
- {
- dwb->entry->kind = svn_node_dir;
- }
- else
- {
- dwb->entry->kind = svn_node_file;
- }
- }
- }
-
- return SVN_NO_ERROR;
-}
-
-struct path_dirent_visitor_t {
- apr_hash_t *full_paths;
- apr_hash_t *base_paths;
- const char *orig_path;
- svn_tristate_t supports_deadprop_count;
- apr_pool_t *result_pool;
-};
-
-static svn_error_t *
-path_dirent_walker(void *baton,
- const char *path, apr_ssize_t path_len,
- const char *ns, apr_ssize_t ns_len,
- const char *name, apr_ssize_t name_len,
- const svn_string_t *val,
- apr_pool_t *pool)
-{
- struct path_dirent_visitor_t *dirents = baton;
- struct dirent_walker_baton_t dwb;
- svn_dirent_t *entry;
-
- /* Skip our original path. */
- if (strcmp(path, dirents->orig_path) == 0)
- {
- return SVN_NO_ERROR;
- }
-
- entry = apr_hash_get(dirents->full_paths, path, path_len);
-
- if (!entry)
- {
- const char *base_name;
-
- entry = svn_dirent_create(pool);
-
- apr_hash_set(dirents->full_paths, path, path_len, entry);
-
- base_name = svn_path_uri_decode(svn_urlpath__basename(path, pool),
- pool);
-
- svn_hash_sets(dirents->base_paths, base_name, entry);
- }
-
- dwb.entry = entry;
- dwb.supports_deadprop_count = &dirents->supports_deadprop_count;
- dwb.result_pool = dirents->result_pool;
- return svn_error_trace(dirent_walker(&dwb, ns, name, val, pool));
-}
-
-static const svn_ra_serf__dav_props_t *
-get_dirent_props(apr_uint32_t dirent_fields,
- svn_ra_serf__session_t *session,
- apr_pool_t *pool)
-{
- svn_ra_serf__dav_props_t *prop;
- apr_array_header_t *props = apr_array_make
- (pool, 7, sizeof(svn_ra_serf__dav_props_t));
-
- if (session->supports_deadprop_count != svn_tristate_false
- || ! (dirent_fields & SVN_DIRENT_HAS_PROPS))
- {
- if (dirent_fields & SVN_DIRENT_KIND)
- {
- prop = apr_array_push(props);
- prop->xmlns = "DAV:";
- prop->name = "resourcetype";
- }
-
- if (dirent_fields & SVN_DIRENT_SIZE)
- {
- prop = apr_array_push(props);
- prop->xmlns = "DAV:";
- prop->name = "getcontentlength";
- }
-
- if (dirent_fields & SVN_DIRENT_HAS_PROPS)
- {
- prop = apr_array_push(props);
- prop->xmlns = SVN_DAV_PROP_NS_DAV;
- prop->name = "deadprop-count";
- }
-
- if (dirent_fields & SVN_DIRENT_CREATED_REV)
- {
- svn_ra_serf__dav_props_t *p = apr_array_push(props);
- p->xmlns = "DAV:";
- p->name = SVN_DAV__VERSION_NAME;
- }
-
- if (dirent_fields & SVN_DIRENT_TIME)
- {
- prop = apr_array_push(props);
- prop->xmlns = "DAV:";
- prop->name = SVN_DAV__CREATIONDATE;
- }
-
- if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
- {
- prop = apr_array_push(props);
- prop->xmlns = "DAV:";
- prop->name = "creator-displayname";
- }
- }
- else
- {
- /* We found an old subversion server that can't handle
- the deadprop-count property in the way we expect.
-
- The neon behavior is to retrieve all properties in this case */
- prop = apr_array_push(props);
- prop->xmlns = "DAV:";
- prop->name = "allprop";
- }
-
- prop = apr_array_push(props);
- prop->xmlns = NULL;
- prop->name = NULL;
-
- return (svn_ra_serf__dav_props_t *) props->elts;
-}
-
-/* Implements svn_ra__vtable_t.stat(). */
-static svn_error_t *
-svn_ra_serf__stat(svn_ra_session_t *ra_session,
- const char *rel_path,
- svn_revnum_t revision,
- svn_dirent_t **dirent,
- apr_pool_t *pool)
-{
- svn_ra_serf__session_t *session = ra_session->priv;
- apr_hash_t *props;
- svn_error_t *err;
- struct dirent_walker_baton_t dwb;
- svn_tristate_t deadprop_count = svn_tristate_unknown;
-
- err = fetch_path_props(&props,
- session, rel_path, revision,
- get_dirent_props(SVN_DIRENT_ALL, session, pool),
- pool, pool);
- if (err)
- {
- if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
- {
- svn_error_clear(err);
- *dirent = NULL;
- return SVN_NO_ERROR;
- }
- else
- return svn_error_trace(err);
- }
-
- dwb.entry = svn_dirent_create(pool);
- dwb.supports_deadprop_count = &deadprop_count;
- dwb.result_pool = pool;
- SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
-
- if (deadprop_count == svn_tristate_false
- && session->supports_deadprop_count == svn_tristate_unknown
- && !dwb.entry->has_props)
- {
- /* We have to requery as the server didn't give us the right
- information */
- session->supports_deadprop_count = svn_tristate_false;
-
- SVN_ERR(fetch_path_props(&props,
- session, rel_path, SVN_INVALID_REVNUM,
- get_dirent_props(SVN_DIRENT_ALL, session, pool),
- pool, pool));
-
- SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
- }
-
- if (deadprop_count != svn_tristate_unknown)
- session->supports_deadprop_count = deadprop_count;
-
- *dirent = dwb.entry;
-
- return SVN_NO_ERROR;
-}
-
-/* Reads the 'resourcetype' property from the list PROPS and checks if the
- * resource at PATH@REVISION really is a directory. Returns
- * SVN_ERR_FS_NOT_DIRECTORY if not.
- */
-static svn_error_t *
-resource_is_directory(apr_hash_t *props)
-{
- svn_node_kind_t kind;
-
- SVN_ERR(svn_ra_serf__get_resource_type(&kind, props));
-
- if (kind != svn_node_dir)
- {
- return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
- _("Can't get entries of non-directory"));
- }
-
- return SVN_NO_ERROR;
-}
-
-/* Implements svn_ra__vtable_t.get_dir(). */
-static svn_error_t *
-svn_ra_serf__get_dir(svn_ra_session_t *ra_session,
- apr_hash_t **dirents,
- svn_revnum_t *fetched_rev,
- apr_hash_t **ret_props,
- const char *rel_path,
- svn_revnum_t revision,
- apr_uint32_t dirent_fields,
- apr_pool_t *pool)
-{
- svn_ra_serf__session_t *session = ra_session->priv;
- const char *path;
-
- path = session->session_url.path;
-
- /* If we have a relative path, URI encode and append it. */
- if (rel_path)
- {
- path = svn_path_url_add_component2(path, rel_path, pool);
- }
-
- /* If the user specified a peg revision other than HEAD, we have to fetch
- the baseline collection url for that revision. If not, we can use the
- public url. */
- if (SVN_IS_VALID_REVNUM(revision) || fetched_rev)
- {
- SVN_ERR(svn_ra_serf__get_stable_url(&path, fetched_rev,
- session, NULL /* conn */,
- path, revision,
- pool, pool));
- revision = SVN_INVALID_REVNUM;
- }
- /* REVISION is always SVN_INVALID_REVNUM */
- SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));
-
- /* If we're asked for children, fetch them now. */
- if (dirents)
- {
- struct path_dirent_visitor_t dirent_walk;
- apr_hash_t *props;
- const char *rtype;
-
- /* Always request node kind to check that path is really a
- * directory.
- */
- dirent_fields |= SVN_DIRENT_KIND;
- SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
- path, SVN_INVALID_REVNUM, "1",
- get_dirent_props(dirent_fields,
- session, pool),
- pool, pool));
-
- /* Check if the path is really a directory. */
- rtype = svn_ra_serf__get_prop(props, path, "DAV:", "resourcetype");
- if (rtype == NULL || strcmp(rtype, "collection") != 0)
- return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
- _("Can't get entries of non-directory"));
-
- /* We're going to create two hashes to help the walker along.
- * We're going to return the 2nd one back to the caller as it
- * will have the basenames it expects.
- */
- dirent_walk.full_paths = apr_hash_make(pool);
- dirent_walk.base_paths = apr_hash_make(pool);
- dirent_walk.orig_path = svn_urlpath__canonicalize(path, pool);
- dirent_walk.supports_deadprop_count = svn_tristate_unknown;
- dirent_walk.result_pool = pool;
-
- SVN_ERR(svn_ra_serf__walk_all_paths(props, SVN_INVALID_REVNUM,
- path_dirent_walker, &dirent_walk,
- pool));
-
- if (dirent_walk.supports_deadprop_count == svn_tristate_false
- && session->supports_deadprop_count == svn_tristate_unknown
- && dirent_fields & SVN_DIRENT_HAS_PROPS)
- {
- /* We have to requery as the server didn't give us the right
- information */
- session->supports_deadprop_count = svn_tristate_false;
- SVN_ERR(svn_ra_serf__retrieve_props(&props, session,
- session->conns[0],
- path, SVN_INVALID_REVNUM, "1",
- get_dirent_props(dirent_fields,
- session, pool),
- pool, pool));
-
- apr_hash_clear(dirent_walk.full_paths);
- apr_hash_clear(dirent_walk.base_paths);
-
- SVN_ERR(svn_ra_serf__walk_all_paths(props, SVN_INVALID_REVNUM,
- path_dirent_walker,
- &dirent_walk, pool));
- }
-
- *dirents = dirent_walk.base_paths;
-
- if (dirent_walk.supports_deadprop_count != svn_tristate_unknown)
- session->supports_deadprop_count = dirent_walk.supports_deadprop_count;
- }
-
- /* If we're asked for the directory properties, fetch them too. */
- if (ret_props)
- {
- apr_hash_t *props;
-
- SVN_ERR(svn_ra_serf__fetch_node_props(&props, session->conns[0],
- path, SVN_INVALID_REVNUM,
- all_props,
- pool, pool));
-
- /* Check if the path is really a directory. */
- SVN_ERR(resource_is_directory(props));
-
- /* ### flatten_props() does not copy PROPVALUE, but fetch_node_props()
- ### put them into POOL, so we're okay. */
- SVN_ERR(svn_ra_serf__flatten_props(ret_props, props, pool, pool));
- }
+ svn_pool_destroy(scratch_pool);
return SVN_NO_ERROR;
}