You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/01/27 11:51:53 UTC
svn commit: r1655005 [2/3] - in /subversion/branches/pin-externals: ./
subversion/libsvn_fs_fs/ subversion/libsvn_ra_serf/
subversion/libsvn_repos/ subversion/libsvn_subr/ subversion/libsvn_wc/
subversion/mod_dav_svn/ subversion/svnrdump/ subversion/te...
Modified: subversion/branches/pin-externals/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_ra_serf/ra_serf.h?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/pin-externals/subversion/libsvn_ra_serf/ra_serf.h Tue Jan 27 10:51:52 2015
@@ -378,7 +378,7 @@ typedef svn_error_t *
/* Callback when the request is done */
typedef svn_error_t *
(*svn_ra_serf__response_done_delegate_t)(serf_request_t *request,
- void *handler_baton,
+ void *done_baton,
apr_pool_t *scratch_pool);
/* Callback for when a request body is needed. */
@@ -639,9 +639,11 @@ typedef struct svn_ra_serf__xml_transiti
} svn_ra_serf__xml_transition_t;
-/* Constructor for */
+/* Constructor for svn_ra_serf__handler_t. Initializes a new handler
+ with default settings for SESSION. */
svn_ra_serf__handler_t *
-svn_ra_serf__create_handler(apr_pool_t *result_pool);
+svn_ra_serf__create_handler(svn_ra_serf__session_t *session,
+ apr_pool_t *result_pool);
/* Construct an XML parsing context, based on the TTABLE transition table.
As content is parsed, the CLOSED_CB callback will be invoked according
@@ -685,7 +687,8 @@ svn_ra_serf__xml_context_done(svn_ra_ser
This also initializes HANDLER_POOL to the given RESULT_POOL. */
svn_ra_serf__handler_t *
-svn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx,
+svn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session,
+ svn_ra_serf__xml_context_t *xmlctx,
const int *expected_status,
apr_pool_t *result_pool);
@@ -924,15 +927,15 @@ svn_ra_serf__keep_only_regular_props(apr
/* Callback used via svn_ra_serf__deliver_props2 */
typedef svn_error_t *
-(*svn_ra_serf__prop_func)(void *baton,
- const char *path,
- const char *ns,
- const char *name,
- const svn_string_t *value,
- apr_pool_t *scratch_pool);
+(*svn_ra_serf__prop_func_t)(void *baton,
+ const char *path,
+ const char *ns,
+ const char *name,
+ const svn_string_t *value,
+ apr_pool_t *scratch_pool);
/*
- * Implementation of svn_ra_serf__prop_func that just delivers svn compatible
+ * Implementation of svn_ra_serf__prop_func_t that just delivers svn compatible
* properties in the apr_hash_t * that is used as baton.
*/
svn_error_t *
@@ -944,48 +947,23 @@ svn_ra_serf__deliver_svn_props(void *bat
apr_pool_t *scratch_pool);
/*
- * Implementation of svn_ra_serf__prop_func that delivers all DAV properties
- * in (const char * -> apr_hash_t *) on Namespace pointing to a second hash
- * (const char * -> svn_string_t *) to the values.
- */
-svn_error_t *
-svn_ra_serf__deliver_node_props(void *baton,
- const char *path,
- const char *ns,
- const char *name,
- const svn_string_t *value,
- apr_pool_t *scratch_pool);
+ * This function will create a handler for a PROPFIND request, which will deliver
+ * properties to PROP_FUNC() with PROP_BATON for the properties listed in LOOKUP_PROPS
+ * at URL for DEPTH ("0","1","infinity").
+ */
+svn_error_t *
+svn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **handler,
+ svn_ra_serf__session_t *session,
+ const char *path,
+ svn_revnum_t rev,
+ const char *depth,
+ const svn_ra_serf__dav_props_t *find_props,
+ svn_ra_serf__prop_func_t prop_func,
+ void *prop_func_baton,
+ apr_pool_t *result_pool);
-/*
- * This function will deliver a PROP_CTX PROPFIND request in the SESS
- * serf context for the properties listed in LOOKUP_PROPS at URL for
- * DEPTH ("0","1","infinity").
- *
- * This function will not block waiting for the response. Callers are
- * expected to call svn_ra_serf__wait_for_props().
- */
-svn_error_t *
-svn_ra_serf__deliver_props2(svn_ra_serf__handler_t **propfind_handler,
- svn_ra_serf__session_t *sess,
- svn_ra_serf__connection_t *conn,
- const char *path,
- svn_revnum_t rev,
- const char *depth,
- const svn_ra_serf__dav_props_t *find_props,
- svn_ra_serf__prop_func prop_func,
- void *prop_func_baton,
- apr_pool_t *pool);
-/*
- * This helper function will block until PROPFIND_HANDLER indicates that is
- * done or another error is returned.
- */
-svn_error_t *
-svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
- apr_pool_t *scratch_pool);
-
-
-/* Using CONN, fetch the properties specified by WHICH_PROPS using CONN
+/* Using SESSION, fetch the properties specified by WHICH_PROPS using CONN
for URL at REVISION. The resulting properties are placed into a 2-level
hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which
is allocated in RESULT_POOL.
@@ -998,7 +976,7 @@ svn_ra_serf__wait_for_props(svn_ra_serf_
Temporary allocations are made in SCRATCH_POOL. */
svn_error_t *
svn_ra_serf__fetch_node_props(apr_hash_t **results,
- svn_ra_serf__connection_t *conn,
+ svn_ra_serf__session_t *session,
const char *url,
svn_revnum_t revision,
const svn_ra_serf__dav_props_t *which_props,
@@ -1006,7 +984,7 @@ svn_ra_serf__fetch_node_props(apr_hash_t
apr_pool_t *scratch_pool);
-/* Using CONN, fetch a DAV: property from the resource identified by URL
+/* Using SESSION, fetch a DAV: property from the resource identified by URL
within REVISION. The PROPNAME may be one of:
"checked-in"
@@ -1020,31 +998,13 @@ svn_ra_serf__fetch_node_props(apr_hash_t
Temporary allocations are made in SCRATCH_POOL. */
svn_error_t *
svn_ra_serf__fetch_dav_prop(const char **value,
- svn_ra_serf__connection_t *conn,
+ svn_ra_serf__session_t *session,
const char *url,
svn_revnum_t revision,
const char *propname,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-
-/** Property walker functions **/
-
-typedef svn_error_t *
-(*svn_ra_serf__walker_visitor_t)(void *baton,
- const char *ns,
- const char *name,
- const svn_string_t *val,
- apr_pool_t *pool);
-
-/* Like walk_all_props(), but a 2-level hash. */
-svn_error_t *
-svn_ra_serf__walk_node_props(apr_hash_t *props,
- svn_ra_serf__walker_visitor_t walker,
- void *baton,
- apr_pool_t *scratch_pool);
-
-
/* Map a property name, as passed over the wire, into its corresponding
Subversion-internal name. The returned name will be a static value,
or allocated within RESULT_POOL.
@@ -1056,30 +1016,6 @@ svn_ra_serf__svnname_from_wirename(const
const char *name,
apr_pool_t *result_pool);
-
-/* PROPS is nested hash tables mapping NS -> NAME -> VALUE.
- This function takes the NS:NAME:VALUE hashes and flattens them into a set of
- names to VALUE. The names are composed of NS:NAME, with specific
- rewrite from wire names (DAV) to SVN names. This mapping is managed
- by the svn_ra_serf__set_baton_props() function.
-
- FLAT_PROPS is allocated in RESULT_POOL.
- ### right now, we do a shallow copy from PROPS to FLAT_PROPS. therefore,
- ### the names and values in PROPS must be in the proper pool.
-
- Temporary allocations are made in SCRATCH_POOL. */
-svn_error_t *
-svn_ra_serf__flatten_props(apr_hash_t **flat_props,
- apr_hash_t *props,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
-
-svn_error_t *
-svn_ra_serf__get_resource_type(svn_node_kind_t *kind,
- apr_hash_t *props);
-
-
/** MERGE-related functions **/
/* Create an MERGE request aimed at the SESSION url, requesting the
@@ -1090,7 +1026,6 @@ svn_ra_serf__get_resource_type(svn_node_
svn_error_t *
svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
const char *merge_resource_url,
apr_hash_t *lock_tokens,
svn_boolean_t keep_locks,
@@ -1118,7 +1053,7 @@ svn_ra_serf__probe_proxy(svn_ra_serf__se
All temporary allocations will be made in SCRATCH_POOL. */
svn_error_t *
svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
- svn_ra_serf__connection_t *conn,
+ svn_ra_serf__session_t *session,
apr_pool_t *scratch_pool);
@@ -1133,35 +1068,29 @@ svn_ra_serf__v2_get_youngest_revnum(svn_
All temporary allocations will be made in SCRATCH_POOL. */
svn_error_t *
svn_ra_serf__v1_get_activity_collection(const char **activity_url,
- svn_ra_serf__connection_t *conn,
+ svn_ra_serf__session_t *session,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
/* Set @a VCC_URL to the default VCC for our repository based on @a
* ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and
- * repository root URLs are cached in @a SESSION. Use @a CONN for any
- * required network communications if it is non-NULL; otherwise use the
- * default connection.
+ * repository root URLs are cached in @a SESSION.
*
- * All temporary allocations will be made in @a POOL. */
+ * All temporary allocations will be made in @a SCRATCH_POOL. */
svn_error_t *
svn_ra_serf__discover_vcc(const char **vcc_url,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
- apr_pool_t *pool);
+ apr_pool_t *scratch_pool);
/* Set @a REPORT_TARGET to the URI of the resource at which generic
- * (path-agnostic) REPORTs should be aimed for @a SESSION. Use @a
- * CONN for any required network communications if it is non-NULL;
- * otherwise use the default connection.
+ * (path-agnostic) REPORTs should be aimed for @a SESSION.
*
* All temporary allocations will be made in @a POOL.
*/
svn_error_t *
svn_ra_serf__report_resource(const char **report_target,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
apr_pool_t *pool);
/* Set @a REL_PATH to a path (not URI-encoded) relative to the root of
@@ -1173,7 +1102,6 @@ svn_error_t *
svn_ra_serf__get_relative_path(const char **rel_path,
const char *orig_path,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
apr_pool_t *pool);
@@ -1200,11 +1128,9 @@ svn_ra_serf__get_youngest_revnum(svn_rev
The DAV RA provider(s) solve this by generating a URL that is specific
to a revision by using a URL into a "baseline collection".
- For a specified SESSION, with an optional CONN (if NULL, then the
- session's default connection will be used; specifically SESSION->conns[0]),
- generate a revision-stable URL for URL at REVISION. If REVISION is
- SVN_INVALID_REVNUM, then the stable URL will refer to the youngest
- revision at the time this function was called.
+ For a specified SESSION, generate a revision-stable URL for URL at
+ REVISION. If REVISION is SVN_INVALID_REVNUM, then the stable URL will
+ refer to the youngest revision at the time this function was called.
If URL is NULL, then the session root will be used.
@@ -1223,7 +1149,6 @@ svn_error_t *
svn_ra_serf__get_stable_url(const char **stable_url,
svn_revnum_t *latest_revnum,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
const char *url,
svn_revnum_t revision,
apr_pool_t *result_pool,
Modified: subversion/branches/pin-externals/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_ra_serf/replay.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_ra_serf/replay.c Tue Jan 27 10:51:52 2015
@@ -112,14 +112,6 @@ static const svn_ra_serf__xml_transition
{ 0 }
};
-/*
- * An incredibly simple list.
- */
-typedef struct ra_serf_list_t {
- void *data;
- struct ra_serf_list_t *next;
-} svn_ra_serf__list_t;
-
/* Per directory/file state */
typedef struct replay_node_t {
apr_pool_t *pool; /* pool allocating this node's data */
@@ -141,8 +133,7 @@ typedef struct revision_report_t {
/* Are we done fetching this file?
Handles book-keeping in multi-report case */
svn_boolean_t *done;
- svn_ra_serf__list_t **done_list;
- svn_ra_serf__list_t done_item;
+ int *replay_reports; /* NULL or number of outstanding reports */
/* callback to get an editor */
svn_ra_replay_revstart_callback_t revstart_func;
@@ -173,7 +164,7 @@ typedef struct revision_report_t {
/* Handlers for the PROPFIND and REPORT for the current revision. */
svn_ra_serf__handler_t *propfind_handler;
- svn_ra_serf__handler_t *report_handler;
+ svn_ra_serf__handler_t *report_handler; /* For done handler */
} revision_report_t;
@@ -478,29 +469,6 @@ replay_cdata(svn_ra_serf__xml_estate_t *
return SVN_NO_ERROR;
}
-/* Conforms to svn_ra_serf__response_done_delegate_t */
-static svn_error_t *
-replay_done(serf_request_t *request,
- void *baton,
- apr_pool_t *scratch_pool)
-{
- struct revision_report_t *ctx = baton;
- svn_ra_serf__handler_t *handler = ctx->report_handler;
-
- if (handler->server_error)
- return svn_ra_serf__server_error_create(handler, scratch_pool);
- else if (handler->sline.code != 200)
- return svn_error_trace(svn_ra_serf__unexpected_status(handler));
-
- *ctx->done = TRUE; /* Breaks out svn_ra_serf__context_run_wait */
-
- ctx->done_item.data = ctx;
- ctx->done_item.next = *ctx->done_list;
- *ctx->done_list = &ctx->done_item;
-
- return SVN_NO_ERROR;
-}
-
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_replay_body(serf_bucket_t **bkt,
@@ -566,7 +534,7 @@ svn_ra_serf__replay(svn_ra_session_t *ra
svn_ra_serf__xml_context_t *xmlctx;
const char *report_target;
- SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL,
+ SVN_ERR(svn_ra_serf__report_resource(&report_target, session,
scratch_pool));
ctx.pool = svn_pool_create(scratch_pool);
@@ -584,20 +552,17 @@ svn_ra_serf__replay(svn_ra_session_t *ra
&ctx,
scratch_pool);
- handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, scratch_pool);
+ handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
+ scratch_pool);
handler->method = "REPORT";
handler->path = session->session_url.path;
handler->body_delegate = create_replay_body;
handler->body_delegate_baton = &ctx;
handler->body_type = "text/xml";
- handler->conn = session->conns[0];
- handler->session = session;
/* Not setting up done handler as we don't use a global context */
- ctx.report_handler = handler; /* unused */
-
SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
return svn_error_trace(
@@ -637,6 +602,33 @@ svn_ra_serf__replay(svn_ra_session_t *ra
*/
#define MAX_OUTSTANDING_REQUESTS 50
+/* Implements svn_ra_serf__response_done_delegate_t for svn_ra_serf__replay_range */
+static svn_error_t *
+replay_done(serf_request_t *request,
+ void *baton,
+ apr_pool_t *scratch_pool)
+{
+ struct revision_report_t *ctx = baton;
+ svn_ra_serf__handler_t *handler = ctx->report_handler;
+
+ if (handler->server_error)
+ return svn_ra_serf__server_error_create(handler, scratch_pool);
+ else if (handler->sline.code != 200)
+ return svn_error_trace(svn_ra_serf__unexpected_status(handler));
+
+ *ctx->done = TRUE; /* Breaks out svn_ra_serf__context_run_wait */
+
+ /* Are re replaying multiple revisions? */
+ if (ctx->replay_reports)
+ {
+ (*ctx->replay_reports)--;
+ }
+
+ svn_pool_destroy(ctx->pool); /* Destroys handler and request! */
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_ra_serf__replay_range(svn_ra_session_t *ra_session,
svn_revnum_t start_revision,
@@ -646,7 +638,7 @@ svn_ra_serf__replay_range(svn_ra_session
svn_ra_replay_revstart_callback_t revstart_func,
svn_ra_replay_revfinish_callback_t revfinish_func,
void *replay_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
svn_ra_serf__session_t *session = ra_session->priv;
svn_revnum_t rev = start_revision;
@@ -654,9 +646,9 @@ svn_ra_serf__replay_range(svn_ra_session
int active_reports = 0;
const char *include_path;
svn_boolean_t done;
- svn_ra_serf__list_t *done_reports = NULL;
- SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool));
+ SVN_ERR(svn_ra_serf__report_resource(&report_target, session,
+ scratch_pool));
/* Prior to 1.8, mod_dav_svn expect to get replay REPORT requests
aimed at the session URL. But that's incorrect -- these reports
@@ -679,8 +671,7 @@ svn_ra_serf__replay_range(svn_ra_session
{
SVN_ERR(svn_ra_serf__get_relative_path(&include_path,
session->session_url.path,
- session, session->conns[0],
- pool));
+ session, scratch_pool));
}
else
{
@@ -698,30 +689,29 @@ svn_ra_serf__replay_range(svn_ra_session
{
struct revision_report_t *rev_ctx;
svn_ra_serf__handler_t *handler;
- apr_pool_t *ctx_pool = svn_pool_create(pool);
+ apr_pool_t *rev_pool = svn_pool_create(scratch_pool);
svn_ra_serf__xml_context_t *xmlctx;
const char *replay_target;
- rev_ctx = apr_pcalloc(ctx_pool, sizeof(*rev_ctx));
- rev_ctx->pool = ctx_pool;
+ rev_ctx = apr_pcalloc(rev_pool, sizeof(*rev_ctx));
+ rev_ctx->pool = rev_pool;
rev_ctx->revstart_func = revstart_func;
rev_ctx->revfinish_func = revfinish_func;
rev_ctx->replay_baton = replay_baton;
rev_ctx->done = &done;
- rev_ctx->done_list = &done_reports;
+ rev_ctx->replay_reports = &active_reports;
rev_ctx->include_path = include_path;
rev_ctx->revision = rev;
rev_ctx->low_water_mark = low_water_mark;
rev_ctx->send_deltas = send_deltas;
- rev_ctx->done_item.data = rev_ctx;
/* Request all properties of a certain revision. */
rev_ctx->rev_props = apr_hash_make(rev_ctx->pool);
if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
{
- rev_ctx->revprop_target = apr_psprintf(pool, "%s/%ld",
- session->rev_stub, rev);
+ rev_ctx->revprop_target = apr_psprintf(rev_pool, "%s/%ld",
+ session->rev_stub, rev);
rev_ctx->revprop_rev = SVN_INVALID_REVNUM;
}
else
@@ -730,14 +720,15 @@ svn_ra_serf__replay_range(svn_ra_session
rev_ctx->revprop_rev = rev;
}
- SVN_ERR(svn_ra_serf__deliver_props2(&rev_ctx->propfind_handler,
- session, session->conns[0],
+ SVN_ERR(svn_ra_serf__create_propfind_handler(
+ &rev_ctx->propfind_handler,
+ session,
rev_ctx->revprop_target,
rev_ctx->revprop_rev,
"0", all_props,
svn_ra_serf__deliver_svn_props,
rev_ctx->rev_props,
- rev_ctx->pool));
+ rev_pool));
/* Spin up the serf request for the PROPFIND. */
svn_ra_serf__request_create(rev_ctx->propfind_handler);
@@ -745,7 +736,7 @@ svn_ra_serf__replay_range(svn_ra_session
/* Send the replay REPORT request. */
if (session->supports_rev_rsrc_replay)
{
- replay_target = apr_psprintf(pool, "%s/%ld",
+ replay_target = apr_psprintf(rev_pool, "%s/%ld",
session->rev_stub, rev);
}
else
@@ -756,16 +747,15 @@ svn_ra_serf__replay_range(svn_ra_session
xmlctx = svn_ra_serf__xml_context_create(replay_ttable,
replay_opened, replay_closed,
replay_cdata, rev_ctx,
- ctx_pool);
+ rev_pool);
- handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, ctx_pool);
+ handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
+ rev_pool);
handler->method = "REPORT";
handler->path = replay_target;
handler->body_delegate = create_replay_body;
handler->body_delegate_baton = rev_ctx;
- handler->conn = session->conns[0];
- handler->session = session;
handler->done_delegate = replay_done;
handler->done_delegate_baton = rev_ctx;
@@ -779,31 +769,11 @@ svn_ra_serf__replay_range(svn_ra_session
/* Run the serf loop. */
done = FALSE;
- SVN_ERR(svn_ra_serf__context_run_wait(&done, session, pool));
+ SVN_ERR(svn_ra_serf__context_run_wait(&done, session, scratch_pool));
- /* Substract the number of completely handled responses from our
- total nr. of open requests', so we'll know when to stop this loop.
- Since the message is completely handled, we can destroy its pool. */
- {
- svn_ra_serf__list_t *done_list;
-
- done_list = done_reports;
-
- done_reports = NULL;
-
- while (done_list)
- {
- revision_report_t *ctx = (revision_report_t *)done_list->data;
- svn_ra_serf__handler_t *done_handler = ctx->report_handler;
-
- done_list = done_list->next;
- SVN_ERR(svn_ra_serf__error_on_status(done_handler->sline,
- done_handler->path,
- done_handler->location));
- svn_pool_clear(ctx->pool);
- active_reports--;
- }
- }
+ /* The done handler of reports decrements active_reports when a report
+ is done. This same handler reports (fatal) report errors, so we can
+ just loop here. */
}
return SVN_NO_ERROR;
Modified: subversion/branches/pin-externals/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_ra_serf/serf.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_ra_serf/serf.c Tue Jan 27 10:51:52 2015
@@ -801,7 +801,7 @@ svn_ra_serf__reparent(svn_ra_session_t *
if (!session->repos_root_str)
{
const char *vcc_url;
- SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, NULL, pool));
+ SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, pool));
}
if (!svn_uri__is_ancestor(session->repos_root_str, url))
@@ -887,16 +887,19 @@ 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,
+ SVN_ERR(svn_ra_serf__discover_vcc(&propfind_path, session,
scratch_pool));
}
props = apr_hash_make(result_pool);
- SVN_ERR(svn_ra_serf__deliver_props2(&handler, session, session->conns[0],
- propfind_path, rev, "0", fetch_props,
- svn_ra_serf__deliver_svn_props, props,
- scratch_pool));
- SVN_ERR(svn_ra_serf__wait_for_props(handler, scratch_pool));
+ SVN_ERR(svn_ra_serf__create_propfind_handler(&handler, session,
+ propfind_path, rev, "0",
+ fetch_props,
+ svn_ra_serf__deliver_svn_props,
+ props,
+ scratch_pool));
+
+ SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
svn_ra_serf__keep_only_regular_props(props, scratch_pool);
@@ -971,7 +974,7 @@ svn_ra_serf__get_repos_root(svn_ra_sessi
if (!session->repos_root_str)
{
const char *vcc_url;
- SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, NULL, pool));
+ SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, pool));
}
*url = session->repos_root_str;
@@ -1007,7 +1010,7 @@ svn_ra_serf__get_uuid(svn_ra_session_t *
/* We're not interested in vcc_url and relative_url, but this call also
stores the repository's uuid in the session. */
- SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, NULL, pool));
+ SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, pool));
if (!session->uuid)
{
return svn_error_create(SVN_ERR_RA_DAV_RESPONSE_HEADER_BADNESS, NULL,
Modified: subversion/branches/pin-externals/subversion/libsvn_ra_serf/stat.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_ra_serf/stat.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_ra_serf/stat.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_ra_serf/stat.c Tue Jan 27 10:51:52 2015
@@ -48,57 +48,41 @@
-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)
+/* Implements svn_ra__vtable_t.check_path(). */
+svn_error_t *
+svn_ra_serf__check_path(svn_ra_session_t *ra_session,
+ const char *relpath,
+ svn_revnum_t revision,
+ svn_node_kind_t *kind,
+ apr_pool_t *scratch_pool)
{
+ svn_ra_serf__session_t *session = ra_session->priv;
+ apr_hash_t *props;
+ svn_error_t *err;
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 (relpath)
+ url = svn_path_url_add_component2(url, 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 */,
+ session,
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(). */
-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);
+ err = svn_ra_serf__fetch_node_props(&props, session,
+ url, SVN_INVALID_REVNUM,
+ check_path_props,
+ scratch_pool, scratch_pool);
if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
{
@@ -107,18 +91,35 @@ svn_ra_serf__check_path(svn_ra_session_t
}
else
{
+ apr_hash_t *dav_props;
+ const char *res_type;
+
/* Any other error, raise to caller. */
- if (err)
- return svn_error_trace(err);
+ SVN_ERR(err);
- SVN_ERR(svn_ra_serf__get_resource_type(kind, props));
+ dav_props = apr_hash_get(props, "DAV:", 4);
+ res_type = svn_prop_get_value(dav_props, "resourcetype");
+ if (!res_type)
+ {
+ /* How did this happen? */
+ return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
+ _("The PROPFIND response did not include the "
+ "requested resourcetype value"));
+ }
+
+ if (strcmp(res_type, "collection") == 0)
+ *kind = svn_node_dir;
+ else
+ *kind = svn_node_file;
}
return SVN_NO_ERROR;
}
-struct dirent_walker_baton_t {
+/* Baton for fill_dirent_propfunc() */
+struct fill_dirent_baton_t
+{
/* Update the fields in this entry. */
svn_dirent_t *entry;
@@ -128,76 +129,78 @@ struct dirent_walker_baton_t {
apr_pool_t *result_pool;
};
+/* Implements svn_ra_serf__prop_func_t */
static svn_error_t *
-dirent_walker(void *baton,
- const char *ns,
- const char *name,
- const svn_string_t *val,
- apr_pool_t *scratch_pool)
+fill_dirent_propfunc(void *baton,
+ const char *path,
+ const char *ns,
+ const char *name,
+ const svn_string_t *val,
+ apr_pool_t *scratch_pool)
{
- struct dirent_walker_baton_t *dwb = baton;
+ struct fill_dirent_baton_t *fdb = 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(ns, "DAV:") == 0)
{
if (strcmp(name, SVN_DAV__VERSION_NAME) == 0)
{
apr_int64_t rev;
SVN_ERR(svn_cstring_atoi64(&rev, val->data));
- dwb->entry->created_rev = (svn_revnum_t)rev;
+ fdb->entry->created_rev = (svn_revnum_t)rev;
}
else if (strcmp(name, "creator-displayname") == 0)
{
- dwb->entry->last_author = apr_pstrdup(dwb->result_pool, val->data);
+ fdb->entry->last_author = apr_pstrdup(fdb->result_pool, val->data);
}
else if (strcmp(name, SVN_DAV__CREATIONDATE) == 0)
{
- SVN_ERR(svn_time_from_cstring(&dwb->entry->time,
+ SVN_ERR(svn_time_from_cstring(&fdb->entry->time,
val->data,
- dwb->result_pool));
+ fdb->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));
+ SVN_ERR(svn_cstring_atoi64(&fdb->entry->size, val->data));
}
}
else if (strcmp(name, "resourcetype") == 0)
{
if (strcmp(val->data, "collection") == 0)
{
- dwb->entry->kind = svn_node_dir;
+ fdb->entry->kind = svn_node_dir;
}
else
{
- dwb->entry->kind = svn_node_file;
+ fdb->entry->kind = svn_node_file;
+ }
+ }
+ }
+ else if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
+ {
+ fdb->entry->has_props = TRUE;
+ }
+ else if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
+ {
+ fdb->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));
+ fdb->entry->has_props = deadprop_count > 0;
+ if (fdb->supports_deadprop_count)
+ *fdb->supports_deadprop_count = svn_tristate_true;
}
+ else if (fdb->supports_deadprop_count)
+ *fdb->supports_deadprop_count = svn_tristate_false;
}
}
@@ -279,21 +282,47 @@ get_dirent_props(apr_uint32_t dirent_fie
/* Implements svn_ra__vtable_t.stat(). */
svn_error_t *
svn_ra_serf__stat(svn_ra_session_t *ra_session,
- const char *rel_path,
+ const char *relpath,
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;
+ struct fill_dirent_baton_t fdb;
svn_tristate_t deadprop_count = svn_tristate_unknown;
+ svn_ra_serf__handler_t *handler;
+ const char *url;
+
+ url = session->session_url.path;
+
+ /* If we have a relative path, append it. */
+ if (relpath)
+ url = svn_path_url_add_component2(url, relpath, 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,
+ url, revision,
+ pool, pool));
+ }
+
+ fdb.entry = svn_dirent_create(pool);
+ fdb.supports_deadprop_count = &deadprop_count;
+ fdb.result_pool = pool;
+
+ SVN_ERR(svn_ra_serf__create_propfind_handler(&handler, session, url,
+ SVN_INVALID_REVNUM, "0",
+ get_dirent_props(SVN_DIRENT_ALL,
+ session,
+ pool),
+ fill_dirent_propfunc, &fdb, pool));
+
+ err = svn_ra_serf__context_run_one(handler, pool);
- 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)
@@ -306,31 +335,22 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
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)
+ && !fdb.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));
+ /* Run the same handler again */
+ SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
}
if (deadprop_count != svn_tristate_unknown)
session->supports_deadprop_count = deadprop_count;
- *dirent = dwb.entry;
+ *dirent = fdb.entry;
return SVN_NO_ERROR;
}
@@ -346,7 +366,7 @@ struct get_dir_baton_t
const char *path;
};
-/* Implements svn_ra_serf__prop_func */
+/* Implements svn_ra_serf__prop_func_t */
static svn_error_t *
get_dir_dirents_cb(void *baton,
const char *path,
@@ -362,22 +382,22 @@ get_dir_dirents_cb(void *baton,
if (relpath && relpath[0] != '\0')
{
- struct dirent_walker_baton_t dwb;
+ struct fill_dirent_baton_t fdb;
relpath = svn_path_uri_decode(relpath, scratch_pool);
- dwb.entry = svn_hash_gets(db->dirents, relpath);
+ fdb.entry = svn_hash_gets(db->dirents, relpath);
- if (!dwb.entry)
+ if (!fdb.entry)
{
- dwb.entry = svn_dirent_create(db->result_pool);
+ fdb.entry = svn_dirent_create(db->result_pool);
svn_hash_sets(db->dirents,
apr_pstrdup(db->result_pool, relpath),
- dwb.entry);
+ fdb.entry);
}
- dwb.result_pool = db->result_pool;
- dwb.supports_deadprop_count = &db->supports_deadprop_count;
- SVN_ERR(dirent_walker(&dwb, ns, name, value, scratch_pool));
+ fdb.result_pool = db->result_pool;
+ fdb.supports_deadprop_count = &db->supports_deadprop_count;
+ SVN_ERR(fill_dirent_propfunc(&fdb, path, ns, name, value, scratch_pool));
}
else if (relpath && !db->is_directory)
{
@@ -471,7 +491,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
if (SVN_IS_VALID_REVNUM(revision) || fetched_rev)
{
SVN_ERR(svn_ra_serf__get_stable_url(&path, fetched_rev,
- session, NULL /* conn */,
+ session,
path, revision,
scratch_pool, scratch_pool));
revision = SVN_INVALID_REVNUM;
@@ -491,8 +511,8 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
gdb.dirents = apr_hash_make(result_pool);
- SVN_ERR(svn_ra_serf__deliver_props2(&dirent_handler,
- session, session->conns[0],
+ SVN_ERR(svn_ra_serf__create_propfind_handler(
+ &dirent_handler, session,
path, SVN_INVALID_REVNUM, "1",
get_dirent_props(dirent_fields,
session,
@@ -508,8 +528,8 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
if (ret_props)
{
gdb.ret_props = apr_hash_make(result_pool);
- SVN_ERR(svn_ra_serf__deliver_props2(&props_handler,
- session, session->conns[0],
+ SVN_ERR(svn_ra_serf__create_propfind_handler(
+ &props_handler, session,
path, SVN_INVALID_REVNUM, "0",
all_props,
get_dir_props_cb, &gdb,
@@ -526,9 +546,6 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
session,
scratch_pool));
- if (dirent_handler->sline.code != 207)
- return svn_error_trace(svn_ra_serf__unexpected_status(dirent_handler));
-
if (gdb.supports_deadprop_count == svn_tristate_false
&& session->supports_deadprop_count == svn_tristate_unknown
&& dirent_fields & SVN_DIRENT_HAS_PROPS)
@@ -539,8 +556,8 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
apr_hash_clear(gdb.dirents);
- SVN_ERR(svn_ra_serf__deliver_props2(&dirent_handler,
- session, session->conns[0],
+ SVN_ERR(svn_ra_serf__create_propfind_handler(
+ &dirent_handler, session,
path, SVN_INVALID_REVNUM, "1",
get_dirent_props(dirent_fields,
session,
@@ -557,9 +574,6 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
SVN_ERR(svn_ra_serf__context_run_wait(&props_handler->done,
session,
scratch_pool));
-
- if (props_handler->sline.code != 207)
- return svn_error_trace(svn_ra_serf__unexpected_status(props_handler));
}
/* And dirent again for the case when we had to send the request again */
@@ -568,9 +582,6 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
SVN_ERR(svn_ra_serf__context_run_wait(&dirent_handler->done,
session,
scratch_pool));
-
- if (dirent_handler->sline.code != 207)
- return svn_error_trace(svn_ra_serf__unexpected_status(dirent_handler));
}
if (gdb.supports_deadprop_count != svn_tristate_unknown)
Modified: subversion/branches/pin-externals/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_ra_serf/update.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_ra_serf/update.c Tue Jan 27 10:51:52 2015
@@ -1429,7 +1429,7 @@ fetch_for_file(file_baton_t *file,
file->base_rev,
svn_path_uri_encode(
file->repos_relpath,
- file->pool));
+ scratch_pool));
}
else if (file->copyfrom_path)
{
@@ -1440,7 +1440,7 @@ fetch_for_file(file_baton_t *file,
file->copyfrom_rev,
svn_path_uri_encode(
file->copyfrom_path+1,
- file->pool));
+ scratch_pool));
}
}
else if (ctx->sess->wc_callbacks->get_wc_prop)
@@ -1461,13 +1461,12 @@ fetch_for_file(file_baton_t *file,
: NULL;
}
- handler = svn_ra_serf__create_handler(file->pool);
+ handler = svn_ra_serf__create_handler(ctx->sess, file->pool);
handler->method = "GET";
handler->path = file->url;
- handler->conn = conn;
- handler->session = ctx->sess;
+ handler->conn = conn; /* Explicit scheduling */
handler->custom_accept_encoding = TRUE;
handler->no_dav_headers = TRUE;
@@ -1494,12 +1493,13 @@ fetch_for_file(file_baton_t *file,
/* If needed, create the PROPFIND to retrieve the file's properties. */
if (file->fetch_props)
{
- SVN_ERR(svn_ra_serf__deliver_props2(&file->propfind_handler,
- ctx->sess, conn, file->url,
- ctx->target_rev, "0", all_props,
- set_file_props, file,
- file->pool));
- SVN_ERR_ASSERT(file->propfind_handler);
+ SVN_ERR(svn_ra_serf__create_propfind_handler(&file->propfind_handler,
+ ctx->sess, file->url,
+ ctx->target_rev, "0",
+ all_props,
+ set_file_props, file,
+ file->pool));
+ file->propfind_handler->conn = conn; /* Explicit scheduling */
file->propfind_handler->done_delegate = file_props_done;
file->propfind_handler->done_delegate_baton = file;
@@ -1591,13 +1591,14 @@ fetch_for_dir(dir_baton_t *dir,
/* If needed, create the PROPFIND to retrieve the file's properties. */
if (dir->fetch_props)
{
- SVN_ERR(svn_ra_serf__deliver_props2(&dir->propfind_handler,
- ctx->sess, conn, dir->url,
- ctx->target_rev, "0", all_props,
- set_dir_prop, dir,
- dir->pool));
- SVN_ERR_ASSERT(dir->propfind_handler);
+ SVN_ERR(svn_ra_serf__create_propfind_handler(&dir->propfind_handler,
+ ctx->sess, dir->url,
+ ctx->target_rev, "0",
+ all_props,
+ set_dir_prop, dir,
+ dir->pool));
+ dir->propfind_handler->conn = conn;
dir->propfind_handler->done_delegate = dir_props_done;
dir->propfind_handler->done_delegate_baton = dir;
@@ -2262,10 +2263,8 @@ link_path(void *report_baton,
_("Unable to parse URL '%s'"), url);
}
- SVN_ERR(svn_ra_serf__report_resource(&report_target, report->sess,
- NULL, pool));
- SVN_ERR(svn_ra_serf__get_relative_path(&link, uri.path, report->sess,
- NULL, pool));
+ SVN_ERR(svn_ra_serf__report_resource(&report_target, report->sess, pool));
+ SVN_ERR(svn_ra_serf__get_relative_path(&link, uri.path, report->sess, pool));
link = apr_pstrcat(pool, "/", link, SVN_VA_NULL);
@@ -2657,15 +2656,15 @@ finish_report(void *report_baton,
SVN_ERR(svn_stream_write(report->body_template, buf->data, &buf->len));
SVN_ERR(svn_stream_close(report->body_template));
- SVN_ERR(svn_ra_serf__report_resource(&report_target, sess, NULL,
- scratch_pool));
+ SVN_ERR(svn_ra_serf__report_resource(&report_target, sess, scratch_pool));
xmlctx = svn_ra_serf__xml_context_create(update_ttable,
update_opened, update_closed,
update_cdata,
report,
scratch_pool);
- handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, scratch_pool);
+ handler = svn_ra_serf__create_expat_handler(sess, xmlctx, NULL,
+ scratch_pool);
handler->method = "REPORT";
handler->path = report_target;
@@ -2675,8 +2674,6 @@ finish_report(void *report_baton,
handler->custom_accept_encoding = TRUE;
handler->header_delegate = setup_update_report_headers;
handler->header_delegate_baton = report;
- handler->conn = sess->conns[0];
- handler->session = sess;
svn_ra_serf__request_create(handler);
Modified: subversion/branches/pin-externals/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_ra_serf/util.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_ra_serf/util.c Tue Jan 27 10:51:52 2015
@@ -567,6 +567,7 @@ accept_response(serf_request_t *request,
void *acceptor_baton,
apr_pool_t *pool)
{
+ /* svn_ra_serf__handler_t *handler = acceptor_baton; */
serf_bucket_t *c;
serf_bucket_alloc_t *bkt_alloc;
@@ -584,6 +585,7 @@ accept_head(serf_request_t *request,
void *acceptor_baton,
apr_pool_t *pool)
{
+ /* svn_ra_serf__handler_t *handler = acceptor_baton; */
serf_bucket_t *response;
response = accept_response(request, stream, acceptor_baton, pool);
@@ -601,7 +603,7 @@ connection_closed(svn_ra_serf__connectio
{
if (why)
{
- return svn_error_wrap_apr(why, NULL);
+ return svn_ra_serf__wrap_err(why, NULL);
}
if (conn->session->using_ssl)
@@ -831,9 +833,14 @@ setup_serf_req(serf_request_t *request,
serf_bucket_headers_setn(*hdrs_bkt, "Accept-Encoding", accept_encoding);
}
- /* These headers need to be sent with every request except GET; see
+ /* These headers need to be sent with every request that might need
+ capability processing (e.g. during commit, reports, etc.), see
issue #3255 ("mod_dav_svn does not pass client capabilities to
- start-commit hooks") for why. */
+ start-commit hooks") for why.
+
+ Some request types like GET/HEAD/PROPFIND are unaware of capability
+ handling; and in some cases the responses can even be cached by
+ proxies, so we don't have to send these hearders there. */
if (dav_headers)
{
serf_bucket_headers_setn(*hdrs_bkt, "DAV", SVN_DAV_NS_DAV_SVN_DEPTH);
@@ -1534,7 +1541,7 @@ setup_request_cb(serf_request_t *request
*acceptor = accept_head;
else
*acceptor = accept_response;
- *acceptor_baton = handler->session;
+ *acceptor_baton = handler;
*s_handler = handle_response_cb;
*s_handler_baton = handler;
@@ -1580,8 +1587,7 @@ svn_ra_serf__request_create(svn_ra_serf_
svn_error_t *
svn_ra_serf__discover_vcc(const char **vcc_url,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
const char *path;
const char *relative_path;
@@ -1594,12 +1600,6 @@ svn_ra_serf__discover_vcc(const char **v
return SVN_NO_ERROR;
}
- /* If no connection is provided, use the default one. */
- if (! conn)
- {
- conn = session->conns[0];
- }
-
path = session->session_url.path;
*vcc_url = NULL;
uuid = NULL;
@@ -1609,9 +1609,10 @@ svn_ra_serf__discover_vcc(const char **v
apr_hash_t *props;
svn_error_t *err;
- err = svn_ra_serf__fetch_node_props(&props, conn,
+ err = svn_ra_serf__fetch_node_props(&props, session,
path, SVN_INVALID_REVNUM,
- base_props, pool, pool);
+ base_props,
+ scratch_pool, scratch_pool);
if (! err)
{
apr_hash_t *ns_props;
@@ -1639,7 +1640,7 @@ svn_ra_serf__discover_vcc(const char **v
svn_error_clear(err);
/* Okay, strip off a component from PATH. */
- path = svn_urlpath__dirname(path, pool);
+ path = svn_urlpath__dirname(path, scratch_pool);
}
}
}
@@ -1665,7 +1666,7 @@ svn_ra_serf__discover_vcc(const char **v
{
svn_stringbuf_t *url_buf;
- url_buf = svn_stringbuf_create(path, pool);
+ url_buf = svn_stringbuf_create(path, scratch_pool);
svn_path_remove_components(url_buf,
svn_path_component_count(relative_path));
@@ -1693,7 +1694,6 @@ svn_error_t *
svn_ra_serf__get_relative_path(const char **rel_path,
const char *orig_path,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
apr_pool_t *pool)
{
const char *decoded_root, *decoded_orig;
@@ -1710,7 +1710,6 @@ svn_ra_serf__get_relative_path(const cha
promises to populate the session's root-url cache, and that's
what we really want. */
SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session,
- conn ? conn : session->conns[0],
pool));
}
@@ -1724,7 +1723,6 @@ svn_ra_serf__get_relative_path(const cha
svn_error_t *
svn_ra_serf__report_resource(const char **report_target,
svn_ra_serf__session_t *session,
- svn_ra_serf__connection_t *conn,
apr_pool_t *pool)
{
/* If we have HTTP v2 support, we want to report against the 'me'
@@ -1734,7 +1732,7 @@ svn_ra_serf__report_resource(const char
/* Otherwise, we'll use the default VCC. */
else
- SVN_ERR(svn_ra_serf__discover_vcc(report_target, session, conn, pool));
+ SVN_ERR(svn_ra_serf__discover_vcc(report_target, session, pool));
return SVN_NO_ERROR;
}
@@ -1839,7 +1837,7 @@ svn_ra_serf__register_editor_shim_callba
return SVN_NO_ERROR;
}
-/* Shandard done_delegate handler */
+/* Shared/standard done_delegate handler */
static svn_error_t *
response_done(serf_request_t *request,
void *handler_baton,
@@ -1887,7 +1885,8 @@ handler_cleanup(void *baton)
}
svn_ra_serf__handler_t *
-svn_ra_serf__create_handler(apr_pool_t *result_pool)
+svn_ra_serf__create_handler(svn_ra_serf__session_t *session,
+ apr_pool_t *result_pool)
{
svn_ra_serf__handler_t *handler;
@@ -1897,6 +1896,9 @@ svn_ra_serf__create_handler(apr_pool_t *
apr_pool_cleanup_register(result_pool, handler, handler_cleanup,
apr_pool_cleanup_null);
+ handler->session = session;
+ handler->conn = session->conns[0];
+
/* Setup the default done handler, to handle server errors */
handler->done_delegate_baton = handler;
handler->done_delegate = response_done;
Modified: subversion/branches/pin-externals/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_ra_serf/xml.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_ra_serf/xml.c Tue Jan 27 10:51:52 2015
@@ -1087,7 +1087,8 @@ expat_response_handler(serf_request_t *r
svn_ra_serf__handler_t *
-svn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx,
+svn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session,
+ svn_ra_serf__xml_context_t *xmlctx,
const int *expected_status,
apr_pool_t *result_pool)
{
@@ -1100,7 +1101,7 @@ svn_ra_serf__create_expat_handler(svn_ra
ectx->expected_status = expected_status;
ectx->cleanup_pool = result_pool;
- handler = svn_ra_serf__create_handler(result_pool);
+ handler = svn_ra_serf__create_handler(session, result_pool);
handler->response_handler = expat_response_handler;
handler->response_baton = ectx;
Modified: subversion/branches/pin-externals/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_repos/dump.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_repos/dump.c Tue Jan 27 10:51:52 2015
@@ -990,6 +990,34 @@ check_mergeinfo_normalization(const char
}
+/* A special case of dump_node(), for a delete record.
+ *
+ * The only thing special about this version is it only writes one blank
+ * line, not two, after the headers. Why? Historical precedent for the
+ * case where a delete record is used as part of a (delete + add-with-history)
+ * in implementing a replacement.
+ *
+ * Also it doesn't do a path-tracker check.
+ */
+static svn_error_t *
+dump_node_delete(svn_stream_t *stream,
+ const char *node_relpath,
+ apr_pool_t *pool)
+{
+ apr_array_header_t *headers = svn_repos__dumpfile_headers_create(pool);
+
+ /* Node-path: ... */
+ svn_repos__dumpfile_header_push(
+ headers, SVN_REPOS_DUMPFILE_NODE_PATH, node_relpath);
+
+ /* Node-action: delete */
+ svn_repos__dumpfile_header_push(
+ headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
+
+ SVN_ERR(svn_repos__dump_headers(stream, headers, TRUE, pool));
+ return SVN_NO_ERROR;
+}
+
/* This helper is the main "meat" of the editor -- it does all the
work of writing a node record.
@@ -1069,8 +1097,9 @@ dump_node(struct edit_baton *eb,
compare_rev = cmp_rev;
}
- if (action == svn_node_action_change)
+ switch (action)
{
+ case svn_node_action_change:
if (eb->path_tracker)
SVN_ERR_W(node_must_exist(eb, path, eb->current_rev, kind, pool),
apr_psprintf(pool, _("Change invalid path '%s' in r%ld"),
@@ -1091,9 +1120,27 @@ dump_node(struct edit_baton *eb,
SVN_ERR(svn_fs_contents_different(&must_dump_text,
compare_root, compare_path,
eb->fs_root, path, pool));
- }
- else if (action == svn_node_action_replace)
- {
+ break;
+
+ case svn_node_action_delete:
+ if (eb->path_tracker)
+ {
+ SVN_ERR_W(node_must_exist(eb, path, eb->current_rev, kind, pool),
+ apr_psprintf(pool, _("Deleting invalid path '%s' in r%ld"),
+ path, eb->current_rev));
+ tracker_path_delete(eb->path_tracker, path);
+ }
+
+ svn_repos__dumpfile_header_push(
+ headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
+
+ /* we can leave this routine quietly now, don't need to dump
+ any content. */
+ must_dump_text = FALSE;
+ must_dump_props = FALSE;
+ break;
+
+ case svn_node_action_replace:
if (eb->path_tracker)
SVN_ERR_W(node_must_exist(eb, path, eb->current_rev,
svn_node_unknown, pool),
@@ -1114,63 +1161,28 @@ dump_node(struct edit_baton *eb,
if (kind == svn_node_file)
must_dump_text = TRUE;
must_dump_props = TRUE;
+ break;
}
else
{
+ /* more complex: delete original, then add-with-history. */
+ /* ### Why not write a 'replace' record? Don't know. */
+
if (eb->path_tracker)
{
- SVN_ERR_W(node_must_exist(eb, compare_path, compare_rev,
- kind, pool),
- apr_psprintf(pool,
- _("Replacing path '%s' in r%ld "
- "with invalid path"),
- path, eb->current_rev));
-
- /* we will call dump_node again with an addition further
- down the road */
tracker_path_delete(eb->path_tracker, path);
}
- /* more complex: delete original, then add-with-history. */
-
- /* the path & kind headers have already been printed; just
- add a delete action, and end the current record.*/
- svn_repos__dumpfile_header_push(
- headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
-
- SVN_ERR(svn_repos__dump_headers(eb->stream, headers, TRUE, pool));
- /* ### Unusually, here we end this node record with only a single
+ /* ### Unusually, we end this 'delete' node record with only a single
blank line after the header block -- no extra blank line. */
+ SVN_ERR(dump_node_delete(eb->stream, path, pool));
- /* recurse: print an additional add-with-history record. */
- SVN_ERR(dump_node(eb, path, kind, svn_node_action_add,
- is_copy, compare_path, compare_rev, pool));
-
- /* we can leave this routine quietly now, don't need to dump
- any content; that was already done in the second record. */
- return SVN_NO_ERROR;
+ /* The remaining action is a non-replacing add-with-history */
+ /* action = svn_node_action_add; */
}
- }
- else if (action == svn_node_action_delete)
- {
- if (eb->path_tracker)
- {
- SVN_ERR_W(node_must_exist(eb, path, eb->current_rev, kind, pool),
- apr_psprintf(pool, _("Deleting invalid path '%s' in r%ld"),
- path, eb->current_rev));
- tracker_path_delete(eb->path_tracker, path);
- }
-
- svn_repos__dumpfile_header_push(
- headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
+ /* FALL THROUGH to 'add' */
- /* we can leave this routine quietly now, don't need to dump
- any content. */
- must_dump_text = FALSE;
- must_dump_props = FALSE;
- }
- else if (action == svn_node_action_add)
- {
+ case svn_node_action_add:
if (eb->path_tracker)
SVN_ERR_W(node_must_not_exist(eb, path, eb->current_rev, pool),
apr_psprintf(pool,
@@ -1258,6 +1270,7 @@ dump_node(struct edit_baton *eb,
headers, SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_SHA1, hex_digest);
}
}
+ break;
}
if ((! must_dump_text) && (! must_dump_props))
Modified: subversion/branches/pin-externals/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_subr/checksum.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_subr/checksum.c Tue Jan 27 10:51:52 2015
@@ -165,12 +165,15 @@ checksum_create_without_digest(svn_check
return checksum;
}
+/* Return a checksum object, allocated in POOL. The checksum will be of
+ * type KIND and contain the given DIGEST.
+ */
static svn_checksum_t *
checksum_create(svn_checksum_kind_t kind,
- apr_size_t digest_size,
const unsigned char *digest,
apr_pool_t *pool)
{
+ apr_size_t digest_size = DIGESTSIZE(kind);
svn_checksum_t *checksum = checksum_create_without_digest(kind, digest_size,
pool);
memcpy((unsigned char *)checksum->digest, digest, digest_size);
@@ -206,32 +209,28 @@ svn_checksum_t *
svn_checksum__from_digest_md5(const unsigned char *digest,
apr_pool_t *result_pool)
{
- return checksum_create(svn_checksum_md5, APR_MD5_DIGESTSIZE, digest,
- result_pool);
+ return checksum_create(svn_checksum_md5, digest, result_pool);
}
svn_checksum_t *
svn_checksum__from_digest_sha1(const unsigned char *digest,
apr_pool_t *result_pool)
{
- return checksum_create(svn_checksum_sha1, APR_SHA1_DIGESTSIZE, digest,
- result_pool);
+ return checksum_create(svn_checksum_sha1, digest, result_pool);
}
svn_checksum_t *
svn_checksum__from_digest_fnv1a_32(const unsigned char *digest,
apr_pool_t *result_pool)
{
- return checksum_create(svn_checksum_fnv1a_32, sizeof(digest), digest,
- result_pool);
+ return checksum_create(svn_checksum_fnv1a_32, digest, result_pool);
}
svn_checksum_t *
svn_checksum__from_digest_fnv1a_32x4(const unsigned char *digest,
apr_pool_t *result_pool)
{
- return checksum_create(svn_checksum_fnv1a_32x4, sizeof(digest), digest,
- result_pool);
+ return checksum_create(svn_checksum_fnv1a_32x4, digest, result_pool);
}
svn_error_t *
@@ -428,10 +427,7 @@ svn_checksum_dup(const svn_checksum_t *c
case svn_checksum_sha1:
case svn_checksum_fnv1a_32:
case svn_checksum_fnv1a_32x4:
- return checksum_create(checksum->kind,
- digest_sizes[checksum->kind],
- checksum->digest,
- pool);
+ return checksum_create(checksum->kind, checksum->digest, pool);
default:
SVN_ERR_MALFUNCTION_NO_RETURN();
@@ -492,10 +488,7 @@ svn_checksum_empty_checksum(svn_checksum
case svn_checksum_sha1:
case svn_checksum_fnv1a_32:
case svn_checksum_fnv1a_32x4:
- return checksum_create(kind,
- digest_sizes[kind],
- empty_string_digests[kind],
- pool);
+ return checksum_create(kind, empty_string_digests[kind], pool);
default:
/* We really shouldn't get here, but if we do... */
Modified: subversion/branches/pin-externals/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_wc/wc_db.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_wc/wc_db.c Tue Jan 27 10:51:52 2015
@@ -1591,19 +1591,32 @@ svn_wc__db_init(svn_wc__db_t *db,
FALSE /* auto-upgrade */,
db->state_pool, scratch_pool));
- /* The WCROOT is complete. Stash it into DB. */
- svn_hash_sets(db->dir_data, wcroot->abspath, wcroot);
+ /* Any previously cached children may now have a new WCROOT, most likely that
+ of the new WCROOT, but there might be descendant directories that are their
+ own working copy, in which case setting WCROOT to our new WCROOT might
+ actually break things for those.
+
+ Clearing is the safest thing we can do in this case, as a test would lead
+ to unnecessary probing, while the standard code probes later anyway. So we
+ only lose a bit of memory
- /* Any previously cached children now have a new WCROOT. */
+ ### Perhaps we could check wcroot->abspath to detect which case we have
+ where, but currently it is already very hard to trigger this from
+ the short living 'svn' client. (GUI clients like TortoiseSVN are far
+ more likely to get in these cases)
+ */
for (hi = apr_hash_first(scratch_pool, db->dir_data);
hi;
hi = apr_hash_next(hi))
{
const char *abspath = apr_hash_this_key(hi);
if (svn_dirent_is_ancestor(wcroot->abspath, abspath))
- svn_hash_sets(db->dir_data, abspath, wcroot);
+ svn_hash_sets(db->dir_data, abspath, NULL);
}
+ /* The WCROOT is complete. Stash it into DB. */
+ svn_hash_sets(db->dir_data, wcroot->abspath, wcroot);
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/pin-externals/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/mod_dav_svn/liveprops.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/pin-externals/subversion/mod_dav_svn/liveprops.c Tue Jan 27 10:51:52 2015
@@ -36,6 +36,7 @@
#include "svn_time.h"
#include "svn_dav.h"
#include "svn_props.h"
+#include "svn_ctype.h"
#include "private/svn_dav_protocol.h"
@@ -422,7 +423,43 @@ insert_prop_internal(const dav_resource
if (last_author == NULL)
return DAV_PROP_INSERT_NOTDEF;
- value = apr_xml_quote_string(scratch_pool, last_author->data, 1);
+ if (svn_xml_is_xml_safe(last_author->data, last_author->len)
+ || !resource->info->repos->is_svn_client)
+ value = apr_xml_quote_string(scratch_pool, last_author->data, 1);
+ else
+ {
+ /* We are talking to a Subversion client, which will (like any proper
+ xml parser) error out if we produce control characters in XML.
+
+ However Subversion clients process both the generic
+ <creator-displayname /> as the custom element for svn:author.
+
+ Let's skip outputting the invalid characters here to make the XML
+ valid, so clients can see the custom element.
+
+ Subversion Clients will then either use a slightly invalid
+ author (unlikely) or more likely use the second result, which
+ will be transferred with full escaping capabilities.
+
+ We have tests in place to assert proper behavior over the RA layer.
+ */
+ apr_size_t i;
+ svn_stringbuf_t *buf;
+
+ buf = svn_stringbuf_create_from_string(last_author, scratch_pool);
+
+ for (i = 0; i < buf->len; i++)
+ {
+ char c = buf->data[i];
+
+ if (svn_ctype_iscntrl(c))
+ {
+ svn_stringbuf_remove(buf, i--, 1);
+ }
+ }
+
+ value = apr_xml_quote_string(scratch_pool, buf->data, 1);
+ }
break;
}
Modified: subversion/branches/pin-externals/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/svnrdump/dump_editor.c?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/pin-externals/subversion/svnrdump/dump_editor.c Tue Jan 27 10:51:52 2015
@@ -136,11 +136,10 @@ struct dump_edit_baton {
/* The revision we're currently dumping. */
svn_revnum_t current_revision;
- /* The kind (file or directory) and baton of the item whose block of
+ /* The baton of the directory node whose block of
dump stream data has not been fully completed; NULL if there's no
such item. */
- svn_node_kind_t pending_kind;
- void *pending_baton;
+ struct dir_baton *pending_db;
};
/* Make a directory baton to represent the directory at PATH (relative
@@ -252,16 +251,31 @@ get_props_content(apr_array_header_t *he
return SVN_NO_ERROR;
}
+/* A special case of dump_node(), for a delete record.
+ *
+ * The only thing special about this version is it only writes one blank
+ * line, not two, after the headers. Why? Historical precedent for the
+ * case where a delete record is used as part of a (delete + add-with-history)
+ * in implementing a replacement.
+ */
static svn_error_t *
-do_dump_newlines(struct dump_edit_baton *eb,
- svn_boolean_t *trigger_var,
+dump_node_delete(svn_stream_t *stream,
+ const char *node_relpath,
apr_pool_t *pool)
{
- if (trigger_var && *trigger_var)
- {
- SVN_ERR(svn_stream_puts(eb->stream, "\n\n"));
- *trigger_var = FALSE;
- }
+ apr_array_header_t *headers = svn_repos__dumpfile_headers_create(pool);
+
+ assert(svn_relpath_is_canonical(node_relpath));
+
+ /* Node-path: ... */
+ svn_repos__dumpfile_header_push(
+ headers, SVN_REPOS_DUMPFILE_NODE_PATH, node_relpath);
+
+ /* Node-action: delete */
+ svn_repos__dumpfile_header_push(
+ headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
+
+ SVN_ERR(svn_repos__dump_headers(stream, headers, TRUE, pool));
return SVN_NO_ERROR;
}
@@ -327,24 +341,20 @@ dump_node(struct dump_edit_baton *eb,
headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "change");
break;
- case svn_node_action_replace:
- if (is_copy)
- {
- /* More complex case: is_copy is true, and copyfrom_path/
- copyfrom_rev are present: delete the original, and then re-add
- it */
-
- svn_repos__dumpfile_header_push(
- headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
+ case svn_node_action_delete:
+ /* Node-action: delete */
+ svn_repos__dumpfile_header_push(
+ headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
- SVN_ERR(svn_repos__dump_headers(eb->stream, headers, TRUE, pool));
+ /* We can leave this routine quietly now. Nothing more to do-
+ print the headers terminated by one blank line, and an extra
+ blank line because we're not dumping props or text. */
+ SVN_ERR(svn_repos__dump_headers(eb->stream, headers, TRUE, pool));
+ SVN_ERR(svn_stream_puts(eb->stream, "\n"));
+ return SVN_NO_ERROR;
- /* Recurse: Print an additional add-with-history record. */
- SVN_ERR(dump_node(eb, repos_relpath, db, fb, svn_node_action_add,
- is_copy, copyfrom_path, copyfrom_rev, pool));
- return SVN_NO_ERROR;
- }
- else
+ case svn_node_action_replace:
+ if (! is_copy)
{
/* Node-action: replace */
svn_repos__dumpfile_header_push(
@@ -356,21 +366,23 @@ dump_node(struct dump_edit_baton *eb,
fb->dump_props = TRUE;
else if (db)
db->dump_props = TRUE;
+ break;
}
- break;
-
- case svn_node_action_delete:
- /* Node-action: delete */
- svn_repos__dumpfile_header_push(
- headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");
+ else
+ {
+ /* More complex case: is_copy is true, and copyfrom_path/
+ copyfrom_rev are present: delete the original, and then re-add
+ it */
+ /* ### Why not write a 'replace' record? Don't know. */
- /* We can leave this routine quietly now. Nothing more to do-
- print the headers terminated by one blank line, and an extra
- blank line because we're not dumping props or text. */
- SVN_ERR(svn_repos__dump_headers(eb->stream, headers, TRUE, pool));
- SVN_ERR(svn_stream_puts(eb->stream, "\n"));
+ /* ### Unusually, we end this 'delete' node record with only a single
+ blank line after the header block -- no extra blank line. */
+ SVN_ERR(dump_node_delete(eb->stream, repos_relpath, pool));
- return SVN_NO_ERROR;
+ /* The remaining action is a non-replacing add-with-history */
+ /* action = svn_node_action_add; */
+ }
+ /* FALL THROUGH to 'add' */
case svn_node_action_add:
/* Node-action: add */
@@ -466,55 +478,26 @@ dump_mkdir(struct dump_edit_baton *eb,
return SVN_NO_ERROR;
}
-/* Dump pending items from the specified node, to allow starting the dump
- of a child node */
+/* Dump pending headers and properties for the directory DB,
+ to allow starting the dump of a child node */
static svn_error_t *
-dump_pending(struct dump_edit_baton *eb,
- apr_pool_t *scratch_pool)
+dump_pending_dir(struct dump_edit_baton *eb,
+ apr_pool_t *scratch_pool)
{
- svn_boolean_t dump_props = FALSE;
- apr_hash_t *props, *deleted_props;
+ struct dir_baton *db = eb->pending_db;
- if (! eb->pending_baton)
+ if (! db)
return SVN_NO_ERROR;
/* Some pending properties to dump? */
- if (eb->pending_kind == svn_node_dir)
- {
- struct dir_baton *db = eb->pending_baton;
-
- if (db->dump_props)
- {
- dump_props = TRUE;
- props = db->props;
- deleted_props = db->deleted_props;
-
- db->dump_props = FALSE;
- }
- }
- else if (eb->pending_kind == svn_node_file)
- {
- struct file_baton *fb = eb->pending_baton;
-
- if (fb->dump_props)
- {
- dump_props = TRUE;
- props = fb->props;
- deleted_props = fb->deleted_props;
- fb->dump_props = FALSE;
- }
- }
- else
- abort();
-
- if (dump_props)
+ if (db->dump_props)
{
apr_array_header_t *headers
= svn_repos__dumpfile_headers_create(scratch_pool);
svn_stringbuf_t *content;
apr_size_t len;
- SVN_ERR(get_props_content(headers, &content, props, deleted_props,
+ SVN_ERR(get_props_content(headers, &content, db->props, db->deleted_props,
scratch_pool, scratch_pool));
/* Content-length: 14 */
@@ -533,21 +516,20 @@ dump_pending(struct dump_edit_baton *eb,
SVN_ERR(svn_stream_puts(eb->stream, "\n\n"));
/* Cleanup so that data is never dumped twice. */
- apr_hash_clear(props);
- apr_hash_clear(deleted_props);
+ apr_hash_clear(db->props);
+ apr_hash_clear(db->deleted_props);
+ db->dump_props = FALSE;
}
- if (eb->pending_kind == svn_node_dir)
+ /* Some pending newlines to dump? */
+ if (db->dump_newlines)
{
- struct dir_baton *db = eb->pending_baton;
-
- /* Some pending newlines to dump? */
- SVN_ERR(do_dump_newlines(eb, &(db->dump_newlines), scratch_pool));
+ SVN_ERR(svn_stream_puts(eb->stream, "\n\n"));
+ db->dump_newlines = FALSE;
}
/* Anything that was pending is pending no longer. */
- eb->pending_baton = NULL;
- eb->pending_kind = svn_node_none;
+ eb->pending_db = NULL;
return SVN_NO_ERROR;
}
@@ -607,8 +589,7 @@ open_root(void *edit_baton,
/* Remember that we've started but not yet finished
handling this directory. */
- eb->pending_baton = new_db;
- eb->pending_kind = svn_node_dir;
+ eb->pending_db = new_db;
}
}
svn_pool_destroy(iterpool);
@@ -632,7 +613,7 @@ delete_entry(const char *path,
{
struct dir_baton *pb = parent_baton;
- SVN_ERR(dump_pending(pb->eb, pool));
+ SVN_ERR(dump_pending_dir(pb->eb, pool));
/* We don't dump this deletion immediate. Rather, we add this path
to the deleted_entries of the parent directory baton. That way,
@@ -656,7 +637,7 @@ add_directory(const char *path,
struct dir_baton *new_db;
svn_boolean_t is_copy;
- SVN_ERR(dump_pending(pb->eb, pool));
+ SVN_ERR(dump_pending_dir(pb->eb, pool));
new_db = make_dir_baton(path, copyfrom_path, copyfrom_rev, pb->eb,
pb, pb->pool);
@@ -681,8 +662,7 @@ add_directory(const char *path,
/* Remember that we've started, but not yet finished handling this
directory. */
- pb->eb->pending_baton = new_db;
- pb->eb->pending_kind = svn_node_dir;
+ pb->eb->pending_db = new_db;
*child_baton = new_db;
return SVN_NO_ERROR;
@@ -700,7 +680,7 @@ open_directory(const char *path,
const char *copyfrom_path = NULL;
svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
- SVN_ERR(dump_pending(pb->eb, pool));
+ SVN_ERR(dump_pending_dir(pb->eb, pool));
/* If the parent directory has explicit comparison path and rev,
record the same for this one. */
@@ -728,9 +708,9 @@ close_directory(void *dir_baton,
svn_boolean_t this_pending;
/* Remember if this directory is the one currently pending. */
- this_pending = (db->eb->pending_baton == db);
+ this_pending = (db->eb->pending_db == db);
- SVN_ERR(dump_pending(db->eb, pool));
+ SVN_ERR(dump_pending_dir(db->eb, pool));
/* If this directory was pending, then dump_pending() should have
taken care of all the props and such. Of course, the only way
@@ -746,9 +726,8 @@ close_directory(void *dir_baton,
SVN_ERR(dump_node(db->eb, db->repos_relpath, db, NULL,
svn_node_action_change, FALSE,
NULL, SVN_INVALID_REVNUM, pool));
- db->eb->pending_baton = db;
- db->eb->pending_kind = svn_node_dir;
- SVN_ERR(dump_pending(db->eb, pool));
+ db->eb->pending_db = db;
+ SVN_ERR(dump_pending_dir(db->eb, pool));
}
/* Dump the deleted directory entries */
@@ -779,7 +758,7 @@ add_file(const char *path,
struct file_baton *fb;
void *was_deleted;
- SVN_ERR(dump_pending(pb->eb, pool));
+ SVN_ERR(dump_pending_dir(pb->eb, pool));
/* Make the file baton. */
fb = make_file_baton(path, pb, pool);
@@ -814,7 +793,7 @@ open_file(const char *path,
struct dir_baton *pb = parent_baton;
struct file_baton *fb;
- SVN_ERR(dump_pending(pb->eb, pool));
+ SVN_ERR(dump_pending_dir(pb->eb, pool));
/* Make the file baton. */
fb = make_file_baton(path, pb, pool);
@@ -844,9 +823,9 @@ change_dir_prop(void *parent_baton,
/* This directory is not pending, but something else is, so handle
the "something else". */
- this_pending = (db->eb->pending_baton == db);
+ this_pending = (db->eb->pending_db == db);
if (! this_pending)
- SVN_ERR(dump_pending(db->eb, pool));
+ SVN_ERR(dump_pending_dir(db->eb, pool));
if (svn_property_kind2(name) != svn_prop_regular_kind)
return SVN_NO_ERROR;
@@ -928,7 +907,7 @@ close_file(void *file_baton,
svn_stringbuf_t *propstring;
apr_array_header_t *headers = svn_repos__dumpfile_headers_create(pool);
- SVN_ERR(dump_pending(eb, pool));
+ SVN_ERR(dump_pending_dir(eb, pool));
/* Dump the node. */
SVN_ERR(dump_node(eb, fb->repos_relpath, NULL, fb,
@@ -1158,7 +1137,7 @@ svn_rdump__get_dump_editor(const svn_del
eb->ra_session = ra_session;
eb->update_anchor_relpath = update_anchor_relpath;
eb->current_revision = revision;
- eb->pending_kind = svn_node_none;
+ eb->pending_db = NULL;
/* Create a special per-revision pool */
eb->pool = svn_pool_create(pool);
Modified: subversion/branches/pin-externals/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/prop_tests.py?rev=1655005&r1=1655004&r2=1655005&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/prop_tests.py Tue Jan 27 10:51:52 2015
@@ -2619,7 +2619,6 @@ def peg_rev_base_working(sbox):
sbox.ospath('iota') + '@BASE')
@Issue(4415)
-@XFail(svntest.main.is_ra_type_dav)
def xml_unsafe_author(sbox):
"svn:author with XML unsafe chars"
@@ -2646,22 +2645,70 @@ def xml_unsafe_author(sbox):
# mod_dav_svn sends svn:author (via PROPFIND for DAV)
# Since r1553367 this works correctly on ra_serf, since we now request
- # a single property value which somehow triggers different behavior
+ # a single property value which skips creating the creator-displayname property
svntest.actions.run_and_verify_svn(None, ['foo\bbar'], [],
'propget', '--revprop', '-r', '1',
'svn:author', '--strict', wc_dir)
+ # Ensure a stable date
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'propset', '--revprop', '-r', '1',
+ 'svn:date', '2015-01-01T00:00:00.0Z', wc_dir)
+
# But a proplist of this property value still fails via DAV.
- expected_output = [
+ expected_output = svntest.verify.UnorderedOutput([
'Unversioned properties on revision 1:\n',
' svn:author\n',
+ ' foo\bbar\n',
' svn:date\n',
- ' svn:log\n'
- ]
+ ' 2015-01-01T00:00:00.0Z\n',
+ ' svn:log\n',
+ ' Log message for revision 1.\n'
+ ])
svntest.actions.run_and_verify_svn(None, expected_output, [],
- 'proplist', '--revprop', '-r', '1',
+ 'proplist', '--revprop', '-r', '1', '-v',
wc_dir)
+@Issue(4415)
+def xml_unsafe_author2(sbox):
+ "svn:author with XML unsafe chars 2"
+
+ sbox.build(create_wc = False)
+ repo_url = sbox.repo_url
+
+ svntest.actions.enable_revprop_changes(sbox.repo_dir)
+
+ # client sends svn:author (via PROPPATCH for DAV)
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'propset', '--revprop', '-r', '1',
+ 'svn:author', 'foo\bbar', repo_url)
+
+ # Ensure a stable date
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'propset', '--revprop', '-r', '1',
+ 'svn:date', '2000-01-01T12:00:00.0Z',
+ repo_url)
+
+ if svntest.main.is_ra_type_dav():
+ # This receives the filtered author (but that is better than an Xml fail)
+ expected_author = 'foobar'
+ else:
+ expected_author = 'foo\bbar'
+
+ expected_output = svntest.verify.UnorderedOutput([
+ ' 1 %-8s Jan 01 2000 ./\n' % expected_author,
+ ' 1 %-8s Jan 01 2000 A/\n' % expected_author,
+ ' 1 %-8s 25 Jan 01 2000 iota\n' % expected_author
+ ])
+ svntest.actions.run_and_verify_svn(None, expected_output, [],
+ 'ls', '-v', repo_url)
+
+ expected_info = [{
+ 'Repository Root' : sbox.repo_url,
+ 'Last Changed Author' : expected_author,
+ }]
+ svntest.actions.run_and_verify_info(expected_info, repo_url)
+
def dir_prop_conflict_details(sbox):
"verify dir property conflict details"
@@ -2814,6 +2861,7 @@ test_list = [ None,
almost_known_prop_names,
peg_rev_base_working,
xml_unsafe_author,
+ xml_unsafe_author2,
dir_prop_conflict_details,
iprops_list_abspath,
wc_propop_on_url,