You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/11 18:43:31 UTC
svn commit: r984468 [9/25] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/generator/ build/generator/templates/ notes/
notes/tree-conflicts/ notes/wc-ng/ subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversi...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c Wed Aug 11 16:43:22 2010
@@ -420,7 +420,7 @@ cdata_propfind(svn_ra_serf__xml_parser_t
return SVN_NO_ERROR;
}
-static apr_status_t
+static svn_error_t *
setup_propfind_headers(serf_bucket_t *headers,
void *setup_baton,
apr_pool_t *pool)
@@ -437,14 +437,15 @@ setup_propfind_headers(serf_bucket_t *he
serf_bucket_headers_setn(headers, "Label", ctx->label);
}
- return APR_SUCCESS;
+ return SVN_NO_ERROR;
}
#define PROPFIND_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propfind xmlns=\"DAV:\">"
#define PROPFIND_TRAILER "</propfind>"
-static serf_bucket_t*
-create_propfind_body(void *setup_baton,
+static svn_error_t *
+create_propfind_body(serf_bucket_t **bkt,
+ void *setup_baton,
serf_bucket_alloc_t *alloc,
apr_pool_t *pool)
{
@@ -515,7 +516,8 @@ create_propfind_body(void *setup_baton,
alloc);
serf_bucket_aggregate_append(body_bkt, tmp);
- return body_bkt;
+ *bkt = body_bkt;
+ return SVN_NO_ERROR;
}
static svn_boolean_t
@@ -700,7 +702,8 @@ svn_ra_serf__wait_for_props(svn_ra_serf_
err = svn_ra_serf__context_run_wait(&prop_ctx->done, sess, pool);
- err2 = svn_ra_serf__error_on_status(prop_ctx->status_code, prop_ctx->path);
+ err2 = svn_ra_serf__error_on_status(prop_ctx->status_code,
+ prop_ctx->path, NULL);
if (err2)
{
svn_error_clear(err);
@@ -735,7 +738,7 @@ svn_ra_serf__retrieve_props(apr_hash_t *
return SVN_NO_ERROR;
}
-void
+svn_error_t *
svn_ra_serf__walk_all_props(apr_hash_t *props,
const char *name,
svn_revnum_t rev,
@@ -750,14 +753,14 @@ svn_ra_serf__walk_all_props(apr_hash_t *
if (!ver_props)
{
- return;
+ return SVN_NO_ERROR;
}
path_props = apr_hash_get(ver_props, name, strlen(name));
if (!path_props)
{
- return;
+ return SVN_NO_ERROR;
}
for (ns_hi = apr_hash_first(pool, path_props); ns_hi;
@@ -777,9 +780,12 @@ svn_ra_serf__walk_all_props(apr_hash_t *
apr_hash_this(name_hi, &prop_name, &prop_len, &prop_val);
/* use a subpool? */
- walker(baton, ns_name, ns_len, prop_name, prop_len, prop_val, pool);
+ SVN_ERR(walker(baton, ns_name, ns_len, prop_name, prop_len,
+ prop_val, pool));
}
}
+
+ return SVN_NO_ERROR;
}
void
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h Wed Aug 11 16:43:22 2010
@@ -408,7 +408,7 @@ svn_ra_serf__handle_client_cert_pw(void
*
* If CONTENT_TYPE is not-NULL, it will be sent as the Content-Type header.
*/
-void
+svn_error_t *
svn_ra_serf__setup_serf_req(serf_request_t *request,
serf_bucket_t **req_bkt, serf_bucket_t **hdrs_bkt,
svn_ra_serf__connection_t *conn,
@@ -444,19 +444,20 @@ typedef svn_error_t *
apr_pool_t *pool);
/* Callback for when a request body is needed. */
-typedef serf_bucket_t*
-(*svn_ra_serf__request_body_delegate_t)(void *baton,
+typedef svn_error_t *
+(*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
+ void *baton,
serf_bucket_alloc_t *alloc,
apr_pool_t *pool);
/* Callback for when request headers are needed. */
-typedef apr_status_t
+typedef svn_error_t *
(*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
void *baton,
apr_pool_t *pool);
/* Callback for when a response has an error. */
-typedef apr_status_t
+typedef svn_error_t *
(*svn_ra_serf__response_error_t)(serf_request_t *request,
serf_bucket_t *response,
int status_code,
@@ -623,6 +624,10 @@ struct svn_ra_serf__xml_parser_t {
*/
int *status_code;
+ /* If non-NULL, this is the value of the response's Location header.
+ */
+ const char *location;
+
/* If non-NULL, this value will be set to TRUE when the response is
* completed.
*/
@@ -686,6 +691,10 @@ typedef struct svn_ra_serf__simple_reque
/* The HTTP status line of the response */
const char *reason;
+ /* The Location header value of the response, or NULL if there
+ wasn't one. */
+ const char *location;
+
/* This value is set to TRUE when the response is completed. */
svn_boolean_t done;
@@ -775,6 +784,13 @@ svn_ra_serf__response_discard_handler(se
void *baton,
apr_pool_t *pool);
+/* Return the value of the RESPONSE's Location header if any, or NULL
+ * otherwise. All allocations will be made in POOL.
+ */
+const char *
+svn_ra_serf__response_get_location(serf_bucket_t *response,
+ apr_pool_t *pool);
+
/** XML helper functions. **/
/*
@@ -963,7 +979,7 @@ typedef svn_error_t *
const svn_string_t *val,
apr_pool_t *pool);
-void
+svn_error_t *
svn_ra_serf__walk_all_props(apr_hash_t *props,
const char *name,
svn_revnum_t rev,
@@ -1359,11 +1375,20 @@ svn_error_t * svn_ra_serf__get_mergeinfo
apr_pool_t *pool);
/* Exchange capabilities with the server, by sending an OPTIONS
- request announcing the client's capabilities, and by filling
- SERF_SESS->capabilities with the server's capabilities as read
- from the response headers. Use POOL only for temporary allocation. */
+ * request announcing the client's capabilities, and by filling
+ * SERF_SESS->capabilities with the server's capabilities as read from
+ * the response headers. Use POOL only for temporary allocation.
+ *
+ * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to
+ * report a server-dictated redirect or relocation (HTTP 301 or 302
+ * error codes), setting *CORRECTED_URL to the value of the corrected
+ * repository URL. Otherwise, such responses from the server will
+ * generate an error. (In either case, no capabilities are exchanged
+ * if there is, in fact, such a response from the server.)
+ */
svn_error_t *
svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess,
+ const char **corrected_url,
apr_pool_t *pool);
/* Implements the has_capability RA layer function. */
@@ -1498,11 +1523,14 @@ svn_ra_serf__encode_auth_header(const ch
/*** General utility functions ***/
/**
- * Convert an HTTP status code resulting from a WebDAV request to the relevant
- * error code.
+ * Convert an HTTP STATUS_CODE resulting from a WebDAV request against
+ * PATH to the relevant error code. Use the response-supplied LOCATION
+ * where it necessary.
*/
svn_error_t *
-svn_ra_serf__error_on_status(int status_code, const char *path);
+svn_ra_serf__error_on_status(int status_code,
+ const char *path,
+ const char *location);
#ifdef __cplusplus
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c Wed Aug 11 16:43:22 2010
@@ -183,9 +183,10 @@ start_replay(svn_ra_serf__xml_parser_t *
/* Create a pool for the commit editor. */
ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
ctx->props = apr_hash_make(ctx->dst_rev_pool);
- svn_ra_serf__walk_all_props(ctx->revs_props, ctx->report_target,
- ctx->revision, svn_ra_serf__set_bare_props,
- ctx->props, ctx->dst_rev_pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(ctx->revs_props, ctx->report_target,
+ ctx->revision,
+ svn_ra_serf__set_bare_props,
+ ctx->props, ctx->dst_rev_pool));
if (ctx->revstart_func)
{
SVN_ERR(ctx->revstart_func(ctx->revision, ctx->replay_baton,
@@ -563,8 +564,9 @@ cdata_replay(svn_ra_serf__xml_parser_t *
return SVN_NO_ERROR;
}
-static serf_bucket_t *
-create_replay_body(void *baton,
+static svn_error_t *
+create_replay_body(serf_bucket_t **bkt,
+ void *baton,
serf_bucket_alloc_t *alloc,
apr_pool_t *pool)
{
@@ -594,7 +596,8 @@ create_replay_body(void *baton,
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "S:replay-report");
- return body_bkt;
+ *bkt = body_bkt;
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -717,6 +720,7 @@ svn_ra_serf__replay_range(svn_ra_session
while (active_reports || rev <= end_revision)
{
apr_status_t status;
+ svn_error_t *err;
svn_ra_serf__list_t *done_list;
svn_ra_serf__list_t *done_reports = NULL;
replay_context_t *replay_ctx;
@@ -801,8 +805,12 @@ svn_ra_serf__replay_range(svn_ra_session
status = serf_context_run(session->context, session->timeout,
pool);
+ err = session->pending_error;
+ session->pending_error = NULL;
+
if (APR_STATUS_IS_TIMEUP(status))
{
+ svn_error_clear(err);
return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT,
NULL,
_("Connection timed out"));
@@ -821,10 +829,9 @@ svn_ra_serf__replay_range(svn_ra_session
active_reports--;
}
+ SVN_ERR(err);
if (status)
{
- SVN_ERR(session->pending_error);
-
return svn_error_wrap_apr(status,
_("Error retrieving replay REPORT (%d)"),
status);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c Wed Aug 11 16:43:22 2010
@@ -331,6 +331,7 @@ svn_ra_serf__progress(void *progress_bat
static svn_error_t *
svn_ra_serf__open(svn_ra_session_t *session,
+ const char **corrected_url,
const char *repos_URL,
const svn_ra_callbacks2_t *callbacks,
void *callback_baton,
@@ -342,6 +343,9 @@ svn_ra_serf__open(svn_ra_session_t *sess
apr_uri_t url;
const char *client_string = NULL;
+ if (corrected_url)
+ *corrected_url = NULL;
+
serf_sess = apr_pcalloc(pool, sizeof(*serf_sess));
serf_sess->pool = svn_pool_create(pool);
serf_sess->bkt_alloc = serf_bucket_allocator_create(serf_sess->pool, NULL,
@@ -452,7 +456,7 @@ svn_ra_serf__open(svn_ra_session_t *sess
session->priv = serf_sess;
- return svn_ra_serf__exchange_capabilities(serf_sess, pool);
+ return svn_ra_serf__exchange_capabilities(serf_sess, corrected_url, pool);
}
static svn_error_t *
@@ -541,8 +545,9 @@ svn_ra_serf__rev_proplist(svn_ra_session
propfind_path, rev, "0", all_props,
pool));
- svn_ra_serf__walk_all_props(props, propfind_path, rev,
- svn_ra_serf__set_bare_props, *ret_props, pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(props, propfind_path, rev,
+ svn_ra_serf__set_bare_props, *ret_props,
+ pool));
return SVN_NO_ERROR;
}
@@ -801,13 +806,13 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
return SVN_NO_ERROR;
}
else
- return err;
+ return svn_error_return(err);
}
entry = apr_pcalloc(pool, sizeof(*entry));
- svn_ra_serf__walk_all_props(props, path, fetched_rev, dirent_walker, entry,
- pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev, dirent_walker,
+ entry, pool));
*dirent = entry;
@@ -920,9 +925,9 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
/* Check if the path is really a directory. */
SVN_ERR(resource_is_directory (props, path, revision));
- svn_ra_serf__walk_all_props(props, path, revision,
- svn_ra_serf__set_flat_props,
- *ret_props, pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(props, path, revision,
+ svn_ra_serf__set_flat_props,
+ *ret_props, pool));
}
return SVN_NO_ERROR;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/update.c Wed Aug 11 16:43:22 2010
@@ -218,6 +218,9 @@ typedef struct report_info_t
svn_txdelta_window_handler_t textdelta;
void *textdelta_baton;
+ /* Checksum for close_file */
+ const char *final_checksum;
+
/* temporary property for this file which is currently being parsed
* It will eventually be stored in our parent directory's property hash.
*/
@@ -236,9 +239,6 @@ typedef struct report_fetch_t {
/* Our pool. */
apr_pool_t *pool;
- /* Non-NULL if we received an error during processing. */
- svn_error_t *err;
-
/* The session we should use to fetch the file. */
svn_ra_serf__session_t *sess;
@@ -445,6 +445,12 @@ set_file_props(void *baton,
report_info_t *info = baton;
const svn_delta_editor_t *editor = info->dir->update_editor;
+ if (name_len == 12
+ && ns_len == 39
+ && strcmp(name, "md5-checksum") == 0
+ && strcmp(ns, SVN_DAV_PROP_NS_DAV) == 0)
+ info->final_checksum = apr_pstrdup(info->pool, val->data);
+
return svn_ra_serf__set_baton_props(editor->change_file_prop,
info->file_baton,
ns, ns_len, name, name_len, val, pool);
@@ -554,17 +560,21 @@ close_dir(report_dir_t *dir)
SVN_ERR_ASSERT(! dir->ref_count);
- svn_ra_serf__walk_all_props(dir->props, dir->base_name, dir->base_rev,
- set_dir_props, dir, dir->dir_baton_pool);
-
- svn_ra_serf__walk_all_props(dir->removed_props, dir->base_name,
- dir->base_rev, remove_dir_props, dir,
- dir->dir_baton_pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(dir->props, dir->base_name,
+ dir->base_rev,
+ set_dir_props, dir,
+ dir->dir_baton_pool));
+
+ SVN_ERR(svn_ra_serf__walk_all_props(dir->removed_props, dir->base_name,
+ dir->base_rev, remove_dir_props, dir,
+ dir->dir_baton_pool));
if (dir->fetch_props)
{
- svn_ra_serf__walk_all_props(dir->props, dir->url, dir->target_rev,
- set_dir_props, dir, dir->dir_baton_pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(dir->props, dir->url,
+ dir->target_rev,
+ set_dir_props, dir,
+ dir->dir_baton_pool));
}
SVN_ERR(dir->update_editor->close_directory(dir->dir_baton,
@@ -655,7 +665,7 @@ check_lock(report_info_t *info)
}
}
-static apr_status_t
+static svn_error_t *
headers_fetch(serf_bucket_t *headers,
void *baton,
apr_pool_t *pool)
@@ -676,10 +686,10 @@ headers_fetch(serf_bucket_t *headers,
serf_bucket_headers_setn(headers, "Accept-Encoding", "gzip");
}
- return APR_SUCCESS;
+ return SVN_NO_ERROR;
}
-static apr_status_t
+static svn_error_t *
cancel_fetch(serf_request_t *request,
serf_bucket_t *response,
int status_code,
@@ -708,11 +718,11 @@ cancel_fetch(serf_request_t *request,
fetch_ctx->read_size = 0;
}
- return APR_SUCCESS;
+ return SVN_NO_ERROR;
}
/* We have no idea what went wrong. */
- SVN_ERR_MALFUNCTION_NO_RETURN();
+ SVN_ERR_MALFUNCTION();
}
static svn_error_t *
@@ -720,8 +730,6 @@ error_fetch(serf_request_t *request,
report_fetch_t *fetch_ctx,
svn_error_t *err)
{
- fetch_ctx->err = err;
-
fetch_ctx->done = TRUE;
fetch_ctx->done_item.data = fetch_ctx;
@@ -733,7 +741,12 @@ error_fetch(serf_request_t *request,
serf_request_set_handler(request,
svn_ra_serf__response_discard_handler, NULL);
- return SVN_NO_ERROR;
+ /* Some errors would be handled by serf; make sure they really make
+ the update fail by wrapping it in a different error. */
+ if (!SERF_BUCKET_READ_ERROR(err->apr_err))
+ return svn_error_create(SVN_ERR_RA_SERF_WRAPPED_ERROR, err, NULL);
+
+ return err;
}
/* Implements svn_ra_serf__response_handler_t */
@@ -928,27 +941,31 @@ handle_fetch(serf_request_t *request,
check_lock(info);
/* set all of the properties we received */
- svn_ra_serf__walk_all_props(info->props,
- info->base_name,
- info->base_rev,
- set_file_props,
- info, info->editor_pool);
- svn_ra_serf__walk_all_props(info->dir->removed_props,
- info->base_name,
- info->base_rev,
- remove_file_props,
- info, info->editor_pool);
- if (info->fetch_props)
+ err = svn_ra_serf__walk_all_props(info->props,
+ info->base_name,
+ info->base_rev,
+ set_file_props,
+ info, info->editor_pool);
+
+ if (!err)
+ err = svn_ra_serf__walk_all_props(info->dir->removed_props,
+ info->base_name,
+ info->base_rev,
+ remove_file_props,
+ info, info->editor_pool);
+ if (!err && info->fetch_props)
{
- svn_ra_serf__walk_all_props(info->props,
- info->url,
- info->target_rev,
- set_file_props,
- info, info->editor_pool);
+ err = svn_ra_serf__walk_all_props(info->props,
+ info->url,
+ info->target_rev,
+ set_file_props,
+ info, info->editor_pool);
}
- err = info->dir->update_editor->close_file(info->file_baton, NULL,
- info->editor_pool);
+ if (!err)
+ err = info->dir->update_editor->close_file(info->file_baton,
+ info->final_checksum,
+ info->editor_pool);
if (err)
{
@@ -985,16 +1002,26 @@ handle_stream(serf_request_t *request,
{
report_fetch_t *fetch_ctx = handler_baton;
serf_status_line sl;
+ const char *location;
+ svn_error_t *err;
serf_bucket_response_status(response, &sl);
/* Woo-hoo. Nothing here to see. */
- fetch_ctx->err = svn_ra_serf__error_on_status(sl.code, fetch_ctx->info->name);
- if (fetch_ctx->err)
+ location = svn_ra_serf__response_get_location(response, pool);
+
+ err = svn_ra_serf__error_on_status(sl.code,
+ fetch_ctx->info->name,
+ location);
+ if (err)
{
fetch_ctx->done = TRUE;
- return svn_ra_serf__handle_discard_body(request, response, NULL, pool);
+ err = svn_error_compose_create(
+ err,
+ svn_ra_serf__handle_discard_body(request, response, NULL, pool));
+
+ return svn_error_return(err);
}
while (1)
@@ -1044,7 +1071,8 @@ handle_stream(serf_request_t *request,
written_len = len;
- svn_stream_write(fetch_ctx->target_stream, data, &written_len);
+ SVN_ERR(svn_stream_write(fetch_ctx->target_stream, data,
+ &written_len));
}
if (APR_STATUS_IS_EOF(status))
@@ -1108,19 +1136,23 @@ handle_propchange_only(report_info_t *in
check_lock(info);
/* set all of the properties we received */
- svn_ra_serf__walk_all_props(info->props,
- info->base_name, info->base_rev,
- set_file_props, info, info->editor_pool);
- svn_ra_serf__walk_all_props(info->dir->removed_props,
- info->base_name, info->base_rev,
- remove_file_props, info, info->editor_pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(info->props,
+ info->base_name, info->base_rev,
+ set_file_props, info,
+ info->editor_pool));
+ SVN_ERR(svn_ra_serf__walk_all_props(info->dir->removed_props,
+ info->base_name, info->base_rev,
+ remove_file_props, info,
+ info->editor_pool));
if (info->fetch_props)
{
- svn_ra_serf__walk_all_props(info->props, info->url, info->target_rev,
- set_file_props, info, info->editor_pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(info->props, info->url,
+ info->target_rev, set_file_props,
+ info, info->editor_pool));
}
- SVN_ERR(info->dir->update_editor->close_file(info->file_baton, NULL,
+ SVN_ERR(info->dir->update_editor->close_file(info->file_baton,
+ info->final_checksum,
info->editor_pool));
/* We're done with our pools. */
@@ -1247,9 +1279,9 @@ start_report(svn_ra_serf__xml_parser_t *
_("Missing revision attr in target-revision element"));
}
- ctx->update_editor->set_target_revision(ctx->update_baton,
- SVN_STR_TO_REV(rev),
- ctx->sess->pool);
+ SVN_ERR(ctx->update_editor->set_target_revision(ctx->update_baton,
+ SVN_STR_TO_REV(rev),
+ ctx->sess->pool));
}
else if (state == NONE && strcmp(name.name, "open-directory") == 0)
{
@@ -1485,9 +1517,9 @@ start_report(svn_ra_serf__xml_parser_t *
SVN_ERR(open_dir(info->dir));
- ctx->update_editor->absent_directory(file_name,
- info->dir->dir_baton,
- info->dir->pool);
+ SVN_ERR(ctx->update_editor->absent_directory(file_name,
+ info->dir->dir_baton,
+ info->dir->pool));
}
else if ((state == OPEN_DIR || state == ADD_DIR) &&
strcmp(name.name, "absent-file") == 0)
@@ -1508,9 +1540,9 @@ start_report(svn_ra_serf__xml_parser_t *
SVN_ERR(open_dir(info->dir));
- ctx->update_editor->absent_file(file_name,
- info->dir->dir_baton,
- info->dir->pool);
+ SVN_ERR(ctx->update_editor->absent_file(file_name,
+ info->dir->dir_baton,
+ info->dir->pool));
}
else if (state == OPEN_DIR || state == ADD_DIR)
{
@@ -2178,18 +2210,21 @@ open_connection_if_needed(svn_ra_serf__s
/* Authentication protocol specific initalization. */
if (sess->auth_protocol)
- sess->auth_protocol->init_conn_func(sess, sess->conns[cur], sess->pool);
+ SVN_ERR(sess->auth_protocol->init_conn_func(sess, sess->conns[cur],
+ sess->pool));
if (sess->proxy_auth_protocol)
- sess->proxy_auth_protocol->init_conn_func(sess, sess->conns[cur],
- sess->pool);
+ SVN_ERR(sess->proxy_auth_protocol->init_conn_func(sess,
+ sess->conns[cur],
+ sess->pool));
}
return SVN_NO_ERROR;
}
/* Serf callback to create update request body bucket. */
-static serf_bucket_t *
-create_update_report_body(void *baton,
+static svn_error_t *
+create_update_report_body(serf_bucket_t **body_bkt,
+ void *baton,
serf_bucket_alloc_t *alloc,
apr_pool_t *pool)
{
@@ -2199,7 +2234,9 @@ create_update_report_body(void *baton,
offset = 0;
apr_file_seek(report->body_file, APR_SET, &offset);
- return serf_bucket_file_create(report->body_file, alloc);
+ *body_bkt = serf_bucket_file_create(report->body_file, alloc);
+
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -2275,17 +2312,23 @@ finish_report(void *report_baton,
while (!report->done || report->active_fetches || report->active_propfinds)
{
+ svn_error_t *err;
status = serf_context_run(sess->context, sess->timeout, pool);
+
+ err = sess->pending_error;
+ sess->pending_error = SVN_NO_ERROR;
+
if (APR_STATUS_IS_TIMEUP(status))
{
+ svn_error_clear(err);
return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT,
NULL,
_("Connection timed out"));
}
+
+ SVN_ERR(err);
if (status)
{
- SVN_ERR(sess->pending_error);
-
return svn_error_wrap_apr(status, _("Error retrieving REPORT (%d)"),
status);
}
@@ -2358,21 +2401,6 @@ finish_report(void *report_baton,
report_fetch_t *done_fetch = done_list->data;
report_dir_t *cur_dir;
- if (done_fetch->err)
- {
- svn_error_t *err = done_fetch->err;
- /* Error found. There might be more, clear those first. */
- done_list = done_list->next;
- while (done_list)
- {
- done_fetch = done_list->data;
- if (done_fetch->err)
- svn_error_clear(done_fetch->err);
- done_list = done_list->next;
- }
- return err;
- }
-
/* decrease our parent's directory refcount. */
cur_dir = done_fetch->info->dir;
cur_dir->ref_count--;
@@ -2438,7 +2466,10 @@ abort_report(void *report_baton,
#if 0
report_context_t *report = report_baton;
#endif
- SVN_ERR_MALFUNCTION();
+
+ /* Should we perform some cleanup here? */
+
+ return SVN_NO_ERROR;
}
static const svn_ra_reporter3_t ra_serf_reporter = {
@@ -2700,8 +2731,8 @@ svn_ra_serf__get_file(svn_ra_session_t *
SVN_ERR(svn_ra_serf__retrieve_props(fetch_props, session, conn, fetch_url,
revision, "0", all_props, pool));
- svn_ra_serf__walk_all_props(fetch_props, fetch_url, revision,
- svn_ra_serf__set_flat_props, *props, pool);
+ SVN_ERR(svn_ra_serf__walk_all_props(fetch_props, fetch_url, revision,
+ svn_ra_serf__set_flat_props, *props, pool));
}
if (stream)
@@ -2732,7 +2763,6 @@ svn_ra_serf__get_file(svn_ra_session_t *
svn_ra_serf__request_create(handler);
SVN_ERR(svn_ra_serf__context_run_wait(&stream_ctx->done, session, pool));
- SVN_ERR(stream_ctx->err);
}
return SVN_NO_ERROR;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c Wed Aug 11 16:43:22 2010
@@ -126,25 +126,23 @@ convert_organisation_to_str(apr_hash_t *
(char*)apr_hash_get(org, "E", APR_HASH_KEY_STRING));
}
-/* Callback that implements serf_ssl_need_server_cert_t. This function is
- called on receiving a ssl certificate of a server when opening a https
- connection. It allows Subversion to override the initial validation done
- by serf.
+/* This function is called on receiving a ssl certificate of a server when
+ opening a https connection. It allows Subversion to override the initial
+ validation done by serf.
Serf provides us the @a baton as provided in the call to
serf_ssl_server_cert_callback_set. The result of serf's initial validation
of the certificate @a CERT is returned as a bitmask in FAILURES. */
-static apr_status_t
+static svn_error_t *
ssl_server_cert(void *baton, int failures,
- const serf_ssl_certificate_t *cert)
+ const serf_ssl_certificate_t *cert,
+ apr_pool_t *scratch_pool)
{
svn_ra_serf__connection_t *conn = baton;
- apr_pool_t *subpool;
svn_auth_ssl_server_cert_info_t cert_info;
svn_auth_cred_ssl_server_trust_t *server_creds = NULL;
svn_auth_iterstate_t *state;
const char *realmstring;
apr_uint32_t svn_failures;
- svn_error_t *err;
apr_hash_t *issuer, *subject, *serf_cert;
void *creds;
@@ -154,27 +152,25 @@ ssl_server_cert(void *baton, int failure
return APR_SUCCESS;
}
- subpool = svn_pool_create(conn->session->pool);
-
/* Extract the info from the certificate */
- subject = serf_ssl_cert_subject(cert, subpool);
- issuer = serf_ssl_cert_issuer(cert, subpool);
- serf_cert = serf_ssl_cert_certificate(cert, subpool);
+ subject = serf_ssl_cert_subject(cert, scratch_pool);
+ issuer = serf_ssl_cert_issuer(cert, scratch_pool);
+ serf_cert = serf_ssl_cert_certificate(cert, scratch_pool);
cert_info.hostname = apr_hash_get(subject, "CN", APR_HASH_KEY_STRING);
cert_info.fingerprint = apr_hash_get(serf_cert, "sha1", APR_HASH_KEY_STRING);
if (! cert_info.fingerprint)
- cert_info.fingerprint = apr_pstrdup(subpool, "<unknown>");
+ cert_info.fingerprint = apr_pstrdup(scratch_pool, "<unknown>");
cert_info.valid_from = apr_hash_get(serf_cert, "notBefore",
APR_HASH_KEY_STRING);
if (! cert_info.valid_from)
- cert_info.valid_from = apr_pstrdup(subpool, "[invalid date]");
+ cert_info.valid_from = apr_pstrdup(scratch_pool, "[invalid date]");
cert_info.valid_until = apr_hash_get(serf_cert, "notAfter",
APR_HASH_KEY_STRING);
if (! cert_info.valid_until)
- cert_info.valid_until = apr_pstrdup(subpool, "[invalid date]");
- cert_info.issuer_dname = convert_organisation_to_str(issuer, subpool);
- cert_info.ascii_cert = serf_ssl_cert_export(cert, subpool);
+ cert_info.valid_until = apr_pstrdup(scratch_pool, "[invalid date]");
+ cert_info.issuer_dname = convert_organisation_to_str(issuer, scratch_pool);
+ cert_info.ascii_cert = serf_ssl_cert_export(cert, scratch_pool);
svn_failures = ssl_convert_serf_failures(failures);
@@ -198,32 +194,52 @@ ssl_server_cert(void *baton, int failure
realmstring = construct_realm(conn->session, conn->session->pool);
- err = svn_auth_first_credentials(&creds, &state,
- SVN_AUTH_CRED_SSL_SERVER_TRUST,
- realmstring,
- conn->session->wc_callbacks->auth_baton,
- subpool);
- if (err || ! creds)
- {
- svn_error_clear(err);
- }
- else
+ SVN_ERR(svn_auth_first_credentials(&creds, &state,
+ SVN_AUTH_CRED_SSL_SERVER_TRUST,
+ realmstring,
+ conn->session->wc_callbacks->auth_baton,
+ scratch_pool));
+ if (creds)
{
server_creds = creds;
- err = svn_auth_save_credentials(state, subpool);
- if (err)
- {
- /* It would be nice to show the error to the user somehow... */
- svn_error_clear(err);
- }
+ SVN_ERR(svn_auth_save_credentials(state, scratch_pool));
}
svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO, NULL);
+ if (!server_creds)
+ return svn_error_create(SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED, NULL, NULL);
+
+ return SVN_NO_ERROR;
+}
+
+/* Implements serf_ssl_need_server_cert_t for ssl_server_cert */
+static apr_status_t
+ssl_server_cert_cb(void *baton, int failures,
+ const serf_ssl_certificate_t *cert)
+{
+ svn_ra_serf__connection_t *conn = baton;
+ svn_ra_serf__session_t *session = conn->session;
+ apr_pool_t *subpool;
+ svn_error_t *err;
+
+ subpool = svn_pool_create(session->pool);
+ err = ssl_server_cert(baton, failures, cert, subpool);
+
svn_pool_destroy(subpool);
- return server_creds ? APR_SUCCESS : SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED;
+ if (err || session->pending_error)
+ {
+ session->pending_error = svn_error_compose_create(
+ session->pending_error,
+ err);
+
+ return session->pending_error->apr_err;
+ }
+
+ return APR_SUCCESS;
+
}
static svn_error_t *
@@ -253,43 +269,28 @@ load_authorities(svn_ra_serf__connection
return SVN_NO_ERROR;
}
-#if SERF_VERSION_AT_LEAST(0, 4, 0)
-/* This ugly ifdef construction can be cleaned up as soon as serf >= 0.4
- gets the minimum supported serf version! */
-
-/* svn_ra_serf__conn_setup is a callback for serf. This function
- creates a read bucket and will wrap the write bucket if SSL
- is needed. */
-apr_status_t
-svn_ra_serf__conn_setup(apr_socket_t *sock,
- serf_bucket_t **read_bkt,
- serf_bucket_t **write_bkt,
- void *baton,
- apr_pool_t *pool)
-{
-#else
-/* This is the old API, for compatibility with serf
- versions <= 0.3. */
-serf_bucket_t *
-svn_ra_serf__conn_setup(apr_socket_t *sock,
- void *baton,
- apr_pool_t *pool)
+static svn_error_t *
+conn_setup(apr_socket_t *sock,
+ serf_bucket_t **read_bkt,
+ serf_bucket_t **write_bkt,
+ void *baton,
+ apr_pool_t *pool)
{
-#endif
- serf_bucket_t *rb = NULL;
svn_ra_serf__connection_t *conn = baton;
- rb = serf_context_bucket_socket_create(conn->session->context,
- sock, conn->bkt_alloc);
+ /* While serf < 0.4.0 is supported we should set read_bkt even when
+ we have an error. See svn_ra_serf__conn_setup() */
+ *read_bkt = serf_context_bucket_socket_create(conn->session->context,
+ sock, conn->bkt_alloc);
if (conn->using_ssl)
{
/* input stream */
- rb = serf_bucket_ssl_decrypt_create(rb, conn->ssl_context,
- conn->bkt_alloc);
+ *read_bkt = serf_bucket_ssl_decrypt_create(*read_bkt, conn->ssl_context,
+ conn->bkt_alloc);
if (!conn->ssl_context)
{
- conn->ssl_context = serf_bucket_ssl_encrypt_context_get(rb);
+ conn->ssl_context = serf_bucket_ssl_encrypt_context_get(*read_bkt);
serf_ssl_client_cert_provider_set(conn->ssl_context,
svn_ra_serf__handle_client_cert,
@@ -298,7 +299,7 @@ svn_ra_serf__conn_setup(apr_socket_t *so
svn_ra_serf__handle_client_cert_pw,
conn, conn->session->pool);
serf_ssl_server_cert_callback_set(conn->ssl_context,
- ssl_server_cert,
+ ssl_server_cert_cb,
conn);
/* See if the user wants us to trust "default" openssl CAs. */
@@ -309,34 +310,72 @@ svn_ra_serf__conn_setup(apr_socket_t *so
/* Are there custom CAs to load? */
if (conn->session->ssl_authorities)
{
- svn_error_t *err;
- err = load_authorities(conn, conn->session->ssl_authorities,
- conn->session->pool);
- if (err)
- {
- /* TODO: we need a way to pass this error back to the
- caller */
- svn_error_clear(err);
- }
+ SVN_ERR(load_authorities(conn, conn->session->ssl_authorities,
+ conn->session->pool));
}
}
-#if SERF_VERSION_AT_LEAST(0, 4, 0)
+
+ if (write_bkt) /* = Serf >= 0.4.0, see svn_ra_serf__conn_setup() */
/* output stream */
*write_bkt = serf_bucket_ssl_encrypt_create(*write_bkt, conn->ssl_context,
conn->bkt_alloc);
-#endif
-
}
+ return SVN_NO_ERROR;
+}
+
#if SERF_VERSION_AT_LEAST(0, 4, 0)
- *read_bkt = rb;
+/* This ugly ifdef construction can be cleaned up as soon as serf >= 0.4
+ gets the minimum supported serf version! */
- return APR_SUCCESS;
-}
+/* svn_ra_serf__conn_setup is a callback for serf. This function
+ creates a read bucket and will wrap the write bucket if SSL
+ is needed. */
+apr_status_t
+svn_ra_serf__conn_setup(apr_socket_t *sock,
+ serf_bucket_t **read_bkt,
+ serf_bucket_t **write_bkt,
+ void *baton,
+ apr_pool_t *pool)
+{
#else
+/* This is the old API, for compatibility with serf
+ versions <= 0.3. */
+serf_bucket_t *
+svn_ra_serf__conn_setup(apr_socket_t *sock,
+ void *baton,
+ apr_pool_t *pool)
+{
+ serf_bucket_t **write_bkt = NULL;
+ serf_bucket_t *rb = NULL;
+ serf_bucket_t **read_bkt = &rb;
+#endif
+ svn_ra_serf__connection_t *conn = baton;
+ svn_ra_serf__session_t *session = conn->session;
+ apr_status_t status = SVN_NO_ERROR;
+
+ svn_error_t *err = conn_setup(sock,
+ read_bkt,
+ write_bkt,
+ baton,
+ pool);
+
+ if (err || session->pending_error)
+ {
+ session->pending_error = svn_error_compose_create(
+ session->pending_error,
+ err);
+
+ status = session->pending_error->apr_err;
+ }
+
+#if ! SERF_VERSION_AT_LEAST(0, 4, 0)
+ SVN_ERR_ASSERT_NO_RETURN(rb != NULL);
return rb;
-}
+#else
+ return status;
#endif
+}
serf_bucket_t*
svn_ra_serf__accept_response(serf_request_t *request,
@@ -370,30 +409,44 @@ accept_head(serf_request_t *request,
return response;
}
+static svn_error_t *
+connection_closed(serf_connection_t *conn,
+ svn_ra_serf__connection_t *sc,
+ apr_status_t why,
+ apr_pool_t *pool)
+{
+ if (why)
+ {
+ SVN_ERR_MALFUNCTION();
+ }
+
+ if (sc->using_ssl)
+ sc->ssl_context = NULL;
+
+ /* Restart the authentication phase on this new connection. */
+ if (sc->session->auth_protocol)
+ SVN_ERR(sc->session->auth_protocol->init_conn_func(sc->session,
+ sc,
+ sc->session->pool));
+
+ return SVN_NO_ERROR;
+}
+
void
svn_ra_serf__conn_closed(serf_connection_t *conn,
void *closed_baton,
apr_status_t why,
apr_pool_t *pool)
{
- svn_ra_serf__connection_t *our_conn = closed_baton;
+ svn_ra_serf__connection_t *sc = closed_baton;
+ svn_error_t *err;
- if (why)
- {
- SVN_ERR_MALFUNCTION_NO_RETURN();
- }
+ err = connection_closed(conn, sc, why, pool);
- if (our_conn->using_ssl)
- {
- our_conn->ssl_context = NULL;
- }
- /* Restart the authentication phase on this new connection. */
- if (our_conn->session->auth_protocol)
- {
- our_conn->session->auth_protocol->init_conn_func(our_conn->session,
- our_conn,
- our_conn->session->pool);
- }
+ if (err)
+ sc->session->pending_error = svn_error_compose_create(
+ sc->session->pending_error,
+ err);
}
apr_status_t
@@ -406,13 +459,15 @@ svn_ra_serf__cleanup_serf_session(void *
return APR_SUCCESS;
}
-apr_status_t svn_ra_serf__handle_client_cert(void *data,
- const char **cert_path)
+/* Implementation of svn_ra_serf__handle_client_cert */
+static svn_error_t *
+handle_client_cert(void *data,
+ const char **cert_path,
+ apr_pool_t *pool)
{
svn_ra_serf__connection_t *conn = data;
svn_ra_serf__session_t *session = conn->session;
const char *realm;
- svn_error_t *err;
void *creds;
*cert_path = NULL;
@@ -421,24 +476,18 @@ apr_status_t svn_ra_serf__handle_client_
if (!conn->ssl_client_auth_state)
{
- err = svn_auth_first_credentials(&creds,
- &conn->ssl_client_auth_state,
- SVN_AUTH_CRED_SSL_CLIENT_CERT,
- realm,
- session->wc_callbacks->auth_baton,
- session->pool);
+ SVN_ERR(svn_auth_first_credentials(&creds,
+ &conn->ssl_client_auth_state,
+ SVN_AUTH_CRED_SSL_CLIENT_CERT,
+ realm,
+ session->wc_callbacks->auth_baton,
+ pool));
}
else
{
- err = svn_auth_next_credentials(&creds,
- conn->ssl_client_auth_state,
- session->pool);
- }
-
- if (err)
- {
- session->pending_error = err;
- return err->apr_err;
+ SVN_ERR(svn_auth_next_credentials(&creds,
+ conn->ssl_client_auth_state,
+ session->pool));
}
if (creds)
@@ -448,40 +497,58 @@ apr_status_t svn_ra_serf__handle_client_
*cert_path = client_creds->cert_file;
}
- return APR_SUCCESS;
+ return SVN_NO_ERROR;
}
-apr_status_t svn_ra_serf__handle_client_cert_pw(void *data,
- const char *cert_path,
- const char **password)
+/* Implements serf_ssl_need_client_cert_t for handle_client_cert */
+apr_status_t svn_ra_serf__handle_client_cert(void *data,
+ const char **cert_path)
+{
+ svn_ra_serf__connection_t *conn = data;
+ svn_ra_serf__session_t *session = conn->session;
+ svn_error_t *err = handle_client_cert(data,
+ cert_path,
+ session->pool);
+
+ if (err || session->pending_error)
+ {
+ session->pending_error = svn_error_compose_create(
+ session->pending_error,
+ err);
+
+ return session->pending_error->apr_err;
+ }
+
+ return APR_SUCCESS;
+}
+
+/* Implementation for svn_ra_serf__handle_client_cert_pw */
+static svn_error_t *
+handle_client_cert_pw(void *data,
+ const char *cert_path,
+ const char **password,
+ apr_pool_t *pool)
{
svn_ra_serf__connection_t *conn = data;
svn_ra_serf__session_t *session = conn->session;
- svn_error_t *err;
void *creds;
*password = NULL;
if (!conn->ssl_client_pw_auth_state)
{
- err = svn_auth_first_credentials(&creds,
- &conn->ssl_client_pw_auth_state,
- SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
- cert_path,
- session->wc_callbacks->auth_baton,
- session->pool);
+ SVN_ERR(svn_auth_first_credentials(&creds,
+ &conn->ssl_client_pw_auth_state,
+ SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
+ cert_path,
+ session->wc_callbacks->auth_baton,
+ pool));
}
else
{
- err = svn_auth_next_credentials(&creds,
- conn->ssl_client_pw_auth_state,
- session->pool);
- }
-
- if (err)
- {
- session->pending_error = err;
- return err->apr_err;
+ SVN_ERR(svn_auth_next_credentials(&creds,
+ conn->ssl_client_pw_auth_state,
+ pool));
}
if (creds)
@@ -494,7 +561,32 @@ apr_status_t svn_ra_serf__handle_client_
return APR_SUCCESS;
}
-void
+/* Implements serf_ssl_need_client_cert_pw_t for handle_client_cert_pw */
+apr_status_t svn_ra_serf__handle_client_cert_pw(void *data,
+ const char *cert_path,
+ const char **password)
+{
+ svn_ra_serf__connection_t *conn = data;
+ svn_ra_serf__session_t *session = conn->session;
+ svn_error_t *err = handle_client_cert_pw(data,
+ cert_path,
+ password,
+ session->pool);
+
+ if (err || session->pending_error)
+ {
+ session->pending_error = svn_error_compose_create(
+ session->pending_error,
+ err);
+
+ return session->pending_error->apr_err;
+ }
+
+ return APR_SUCCESS;
+}
+
+
+svn_error_t *
svn_ra_serf__setup_serf_req(serf_request_t *request,
serf_bucket_t **req_bkt,
serf_bucket_t **ret_hdrs_bkt,
@@ -527,13 +619,15 @@ svn_ra_serf__setup_serf_req(serf_request
/* Setup server authorization headers */
if (conn->session->auth_protocol)
- conn->session->auth_protocol->setup_request_func(conn, method, url,
- hdrs_bkt);
+ SVN_ERR(conn->session->auth_protocol->setup_request_func(conn, method, url,
+ hdrs_bkt));
/* Setup proxy authorization headers */
if (conn->session->proxy_auth_protocol)
- conn->session->proxy_auth_protocol->setup_request_func(conn, method,
- url, hdrs_bkt);
+ SVN_ERR(conn->session->proxy_auth_protocol->setup_request_func(conn,
+ method,
+ url,
+ hdrs_bkt));
#if ! SERF_VERSION_AT_LEAST(0, 4, 0)
/* Set up SSL if we need to */
@@ -559,6 +653,8 @@ svn_ra_serf__setup_serf_req(serf_request
{
*ret_hdrs_bkt = hdrs_bkt;
}
+
+ return SVN_NO_ERROR;
}
svn_error_t *
@@ -804,6 +900,18 @@ svn_ra_serf__response_discard_handler(se
}
}
+const char *
+svn_ra_serf__response_get_location(serf_bucket_t *response,
+ apr_pool_t *pool)
+{
+ serf_bucket_t *headers;
+ const char *val;
+
+ headers = serf_bucket_response_get_headers(response);
+ val = serf_bucket_headers_get(headers, "Location");
+ return val ? svn_uri_canonicalize(val, pool) : NULL;
+}
+
/* Implements svn_ra_serf__response_handler_t */
svn_error_t *
svn_ra_serf__handle_status_only(serf_request_t *request,
@@ -826,7 +934,7 @@ svn_ra_serf__handle_status_only(serf_req
ctx->status = sl.code;
ctx->reason = sl.reason;
-
+ ctx->location = svn_ra_serf__response_get_location(response, pool);
ctx->done = TRUE;
}
@@ -986,6 +1094,7 @@ svn_ra_serf__handle_multistatus_only(ser
ctx->status = sl.code;
ctx->reason = sl.reason;
+ ctx->location = svn_ra_serf__response_get_location(response, pool);
}
return svn_error_return(err);
@@ -1060,6 +1169,11 @@ svn_ra_serf__handle_xml_parser(serf_requ
*ctx->status_code = sl.code;
}
+ if (sl.code == 301 || sl.code == 302 || sl.code == 307)
+ {
+ ctx->location = svn_ra_serf__response_get_location(response, pool);
+ }
+
/* Woo-hoo. Nothing here to see. */
if (sl.code == 404 && ctx->ignore_errors == FALSE)
{
@@ -1209,7 +1323,8 @@ svn_ra_serf__credentials_callback(char *
if (err)
{
- ctx->session->pending_error = err;
+ session->pending_error
+ = svn_error_compose_create(session->pending_error, err);
return err->apr_err;
}
@@ -1218,10 +1333,13 @@ svn_ra_serf__credentials_callback(char *
if (!creds || session->auth_attempts > 4)
{
/* No more credentials. */
- ctx->session->pending_error =
- svn_error_create(SVN_ERR_AUTHN_FAILED, NULL,
- "No more credentials or we tried too many times.\n"
- "Authentication failed");
+ session->pending_error
+ = svn_error_compose_create(
+ session->pending_error,
+ svn_error_create(
+ SVN_ERR_AUTHN_FAILED, NULL,
+ _("No more credentials or we tried too many times.\n"
+ "Authentication failed")));
return SVN_ERR_AUTHN_FAILED;
}
@@ -1239,9 +1357,11 @@ svn_ra_serf__credentials_callback(char *
if (!session->proxy_username || session->proxy_auth_attempts > 4)
{
/* No more credentials. */
- ctx->session->pending_error =
- svn_error_create(SVN_ERR_AUTHN_FAILED, NULL,
- "Proxy authentication failed");
+ session->pending_error
+ = svn_error_compose_create(
+ ctx->session->pending_error,
+ svn_error_create(SVN_ERR_AUTHN_FAILED, NULL,
+ _("Proxy authentication failed")));
return SVN_ERR_AUTHN_FAILED;
}
}
@@ -1251,18 +1371,20 @@ svn_ra_serf__credentials_callback(char *
return APR_SUCCESS;
}
-/* Implements the serf_response_handler_t interface. Wait for HTTP
- response status and headers, and invoke CTX->response_handler() to
- carry out operation-specific processing. Afterwards, check for
- connection close.
+/* Wait for HTTP response status and headers, and invoke CTX->
+ response_handler() to carry out operation-specific processing.
+ Afterwards, check for connection close.
+
+ SERF_STATUS allows returning errors to serf without creating a
+ subversion error object.
*/
-static apr_status_t
+static svn_error_t *
handle_response(serf_request_t *request,
serf_bucket_t *response,
- void *baton,
+ svn_ra_serf__handler_t *ctx,
+ apr_status_t *serf_status,
apr_pool_t *pool)
{
- svn_ra_serf__handler_t *ctx = baton;
serf_status_line sl;
apr_status_t status;
@@ -1270,14 +1392,8 @@ handle_response(serf_request_t *request,
{
/* Uh-oh. Our connection died. Requeue. */
if (ctx->response_error)
- {
- status = ctx->response_error(request, response, 0,
- ctx->response_error_baton);
- if (status)
- {
- goto cleanup;
- }
- }
+ SVN_ERR(ctx->response_error(request, response, 0,
+ ctx->response_error_baton));
svn_ra_serf__request_create(ctx);
@@ -1287,12 +1403,14 @@ handle_response(serf_request_t *request,
status = serf_bucket_response_status(response, &sl);
if (SERF_BUCKET_READ_ERROR(status))
{
- return status;
+ *serf_status = status;
+ return SVN_NO_ERROR; /* Handled by serf */
}
if (!sl.version && (APR_STATUS_IS_EOF(status) ||
APR_STATUS_IS_EAGAIN(status)))
{
- goto cleanup;
+ *serf_status = status;
+ return SVN_NO_ERROR; /* Handled by serf */
}
status = serf_bucket_response_wait_for_headers(response);
@@ -1300,7 +1418,8 @@ handle_response(serf_request_t *request,
{
if (!APR_STATUS_IS_EOF(status))
{
- goto cleanup;
+ *serf_status = status;
+ return SVN_NO_ERROR;
}
/* Cases where a lack of a response body (via EOF) is okay:
@@ -1313,26 +1432,22 @@ handle_response(serf_request_t *request,
*/
if (strcmp(ctx->method, "HEAD") != 0 && sl.code != 204 && sl.code != 304)
{
- ctx->session->pending_error =
+ svn_error_t *err =
svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
- svn_error_compose_create(
- ctx->session->pending_error,
- svn_error_wrap_apr(status, NULL)),
+ svn_error_wrap_apr(status, NULL),
_("Premature EOF seen from server "
"(http status=%d)"), sl.code);
/* This discard may be no-op, but let's preserve the algorithm
used elsewhere in this function for clarity's sake. */
svn_ra_serf__response_discard_handler(request, response, NULL, pool);
- status = ctx->session->pending_error->apr_err;
- goto cleanup;
+ return err;
}
}
if (ctx->conn->last_status_code == 401 && sl.code < 400)
{
- svn_error_clear(
- svn_auth_save_credentials(ctx->session->auth_state,
- ctx->session->pool));
+ SVN_ERR(svn_auth_save_credentials(ctx->session->auth_state,
+ ctx->session->pool));
ctx->session->auth_attempts = 0;
ctx->session->auth_state = NULL;
ctx->session->realm = NULL;
@@ -1343,49 +1458,39 @@ handle_response(serf_request_t *request,
if (sl.code == 401 || sl.code == 407)
{
/* 401 Authorization or 407 Proxy-Authentication required */
- svn_error_t *err;
status = svn_ra_serf__response_discard_handler(request, response, NULL, pool);
/* Don't bother handling the authentication request if the response
wasn't received completely yet. Serf will call handle_response
again when more data is received. */
- if (! APR_STATUS_IS_EAGAIN(status))
+ if (APR_STATUS_IS_EAGAIN(status))
{
- err = svn_ra_serf__handle_auth(sl.code, ctx,
- request, response, pool);
- if (err)
- {
- ctx->session->pending_error = svn_error_compose_create(
- err,
- ctx->session->pending_error);
- status = ctx->session->pending_error->apr_err;
- goto cleanup;
- }
-
- svn_ra_serf__priority_request_create(ctx);
- return status;
- }
- else
- {
- return status;
+ *serf_status = status;
+ return SVN_NO_ERROR;
}
+
+ SVN_ERR(svn_ra_serf__handle_auth(sl.code, ctx,
+ request, response, pool));
+
+ svn_ra_serf__priority_request_create(ctx);
+
+ *serf_status = status;
+ return SVN_NO_ERROR;
}
else if (sl.code == 409 || sl.code >= 500)
{
/* 409 Conflict: can indicate a hook error.
5xx (Internal) Server error. */
- ctx->session->pending_error = svn_error_compose_create(
- svn_ra_serf__handle_server_error(request, response, pool),
- ctx->session->pending_error);
+ SVN_ERR(svn_ra_serf__handle_server_error(request, response, pool));
if (!ctx->session->pending_error)
{
- ctx->session->pending_error =
+ return
svn_error_createf(APR_EGENERAL, NULL,
_("Unspecified error message: %d %s"), sl.code, sl.reason);
}
- status = ctx->session->pending_error->apr_err;
- goto cleanup;
+
+ return SVN_NO_ERROR; /* Error is set in caller */
}
else
{
@@ -1407,56 +1512,72 @@ handle_response(serf_request_t *request,
{
svn_ra_serf__response_discard_handler(request, response, NULL,
pool);
- ctx->session->pending_error = err;
- status = ctx->session->pending_error->apr_err;
- goto cleanup;
+ /* Ignore serf status code, just return the real error */
+
+ return svn_error_return(err);
}
}
err = ctx->response_handler(request,response, ctx->response_baton, pool);
- if (err)
- {
- status = err->apr_err;
- if (!SERF_BUCKET_READ_ERROR(err->apr_err))
- {
- /* These errors are special cased in serf
- ### We hope no handler returns these by accident. */
- svn_error_clear(err);
- }
- else
- {
- ctx->session->pending_error =
- svn_error_return(svn_error_compose_create(
- err,
- ctx->session->pending_error));
- }
+ if (err
+ && (!SERF_BUCKET_READ_ERROR(err->apr_err)
+ || APR_STATUS_IS_ECONNRESET(err->apr_err)))
+ {
+ /* These errors are special cased in serf
+ ### We hope no handler returns these by accident. */
+ *serf_status = err->apr_err;
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
}
+
+ return svn_error_return(err);
}
+}
-cleanup:
- return status;
+/* Implements serf_response_handler_t for handle_response. Storing
+ errors in ctx->session->pending_error if appropriate. */
+static apr_status_t
+handle_response_cb(serf_request_t *request,
+ serf_bucket_t *response,
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_ra_serf__handler_t *ctx = baton;
+ svn_ra_serf__session_t *session = ctx->session;
+ svn_error_t *err;
+ apr_status_t serf_status = APR_SUCCESS;
+
+ err = svn_error_return(
+ handle_response(request, response, ctx, &serf_status, pool));
+
+ if (err || session->pending_error)
+ {
+ session->pending_error = svn_error_compose_create(session->pending_error,
+ err);
+
+ serf_status = session->pending_error->apr_err;
+ }
+
+ return serf_status;
}
-/* Implements the serf_request_setup_t interface (which sets up both a
- request and its response handler callback). If the CTX->setup()
- callback is non-NULL, invoke it to carry out the majority of the
- serf_request_setup_t implementation. Otherwise, perform default
- setup, with special handling for HEAD requests, and finer-grained
+/* If the CTX->setup() callback is non-NULL, invoke it to carry out the
+ majority of the serf_request_setup_t implementation. Otherwise, perform
+ default setup, with special handling for HEAD requests, and finer-grained
callbacks invoked (if non-NULL) to produce the request headers and
body. */
-static apr_status_t
+static svn_error_t *
setup_request(serf_request_t *request,
- void *setup_baton,
- serf_bucket_t **req_bkt,
- serf_response_acceptor_t *acceptor,
- void **acceptor_baton,
- serf_response_handler_t *handler,
- void **handler_baton,
- apr_pool_t *pool)
+ svn_ra_serf__handler_t *ctx,
+ serf_bucket_t **req_bkt,
+ serf_response_acceptor_t *acceptor,
+ void **acceptor_baton,
+ serf_response_handler_t *handler,
+ void **handler_baton,
+ apr_pool_t *pool)
{
- svn_ra_serf__handler_t *ctx = setup_baton;
serf_bucket_t *headers_bkt;
*acceptor = svn_ra_serf__accept_response;
@@ -1466,17 +1587,11 @@ setup_request(serf_request_t *request,
{
svn_ra_serf__response_handler_t response_handler;
void *response_baton;
- svn_error_t *error;
- error = ctx->setup(request, ctx->setup_baton, req_bkt,
- acceptor, acceptor_baton,
- &response_handler, &response_baton,
- pool);
- if (error)
- {
- ctx->session->pending_error = error;
- return error->apr_err;
- }
+ SVN_ERR(ctx->setup(request, ctx->setup_baton, req_bkt,
+ acceptor, acceptor_baton,
+ &response_handler, &response_baton,
+ pool));
ctx->response_handler = response_handler;
ctx->response_baton = response_baton;
@@ -1493,42 +1608,77 @@ setup_request(serf_request_t *request,
if (ctx->body_delegate)
{
- body_bkt =
- ctx->body_delegate(ctx->body_delegate_baton, bkt_alloc, pool);
+ SVN_ERR(ctx->body_delegate(&body_bkt, ctx->body_delegate_baton,
+ bkt_alloc, pool));
}
else
{
body_bkt = NULL;
}
- svn_ra_serf__setup_serf_req(request, req_bkt, &headers_bkt, ctx->conn,
- ctx->method, ctx->path,
- body_bkt, ctx->body_type);
+ SVN_ERR(svn_ra_serf__setup_serf_req(request, req_bkt, &headers_bkt,
+ ctx->conn, ctx->method, ctx->path,
+ body_bkt, ctx->body_type));
if (ctx->header_delegate)
{
- ctx->header_delegate(headers_bkt, ctx->header_delegate_baton, pool);
+ SVN_ERR(ctx->header_delegate(headers_bkt, ctx->header_delegate_baton,
+ pool));
}
}
- *handler = handle_response;
+ *handler = handle_response_cb;
*handler_baton = ctx;
return APR_SUCCESS;
}
+/* Implements the serf_request_setup_t interface (which sets up both a
+ request and its response handler callback). Handles errors for
+ setup_request_cb */
+static apr_status_t
+setup_request_cb(serf_request_t *request,
+ void *setup_baton,
+ serf_bucket_t **req_bkt,
+ serf_response_acceptor_t *acceptor,
+ void **acceptor_baton,
+ serf_response_handler_t *handler,
+ void **handler_baton,
+ apr_pool_t *pool)
+{
+ svn_ra_serf__handler_t *ctx = setup_baton;
+ svn_error_t *err;
+
+ err = setup_request(request, ctx,
+ req_bkt,
+ acceptor, acceptor_baton,
+ handler, handler_baton,
+ pool);
+
+ if (err)
+ {
+ ctx->session->pending_error
+ = svn_error_compose_create(ctx->session->pending_error,
+ err);
+
+ return err->apr_err;
+ }
+
+ return APR_SUCCESS;
+}
+
serf_request_t *
svn_ra_serf__request_create(svn_ra_serf__handler_t *handler)
{
return serf_connection_request_create(handler->conn->conn,
- setup_request, handler);
+ setup_request_cb, handler);
}
serf_request_t *
svn_ra_serf__priority_request_create(svn_ra_serf__handler_t *handler)
{
return serf_connection_priority_request_create(handler->conn->conn,
- setup_request, handler);
+ setup_request_cb, handler);
}
svn_error_t *
@@ -1702,18 +1852,21 @@ svn_ra_serf__report_resource(const char
}
svn_error_t *
-svn_ra_serf__error_on_status(int status_code, const char *path)
+svn_ra_serf__error_on_status(int status_code,
+ const char *path,
+ const char *location)
{
switch(status_code)
{
case 301:
case 302:
+ case 307:
return svn_error_createf(SVN_ERR_RA_DAV_RELOCATED, NULL,
- (status_code == 301)
- ? _("Repository moved permanently to '%s';"
- " please relocate")
- : _("Repository moved temporarily to '%s';"
- " please relocate"), path);
+ (status_code == 301)
+ ? _("Repository moved permanently to '%s';"
+ " please relocate")
+ : _("Repository moved temporarily to '%s';"
+ " please relocate"), location);
case 404:
return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
_("'%s' path not found"), path);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/win32_auth_sspi.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/win32_auth_sspi.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/win32_auth_sspi.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/win32_auth_sspi.c Wed Aug 11 16:43:22 2010
@@ -171,14 +171,18 @@ do_auth(serf_sspi_context_t *sspi_contex
apr_size_t tmp_len, token_len = 0;
const char *space;
- space = strchr(auth_attr, ' ');
- if (space)
+ if (auth_attr != NULL)
{
- const char *base64_token = apr_pstrmemdup(pool,
- auth_attr, space - auth_attr);
- token_len = apr_base64_decode_len(base64_token);
- token = apr_palloc(pool, token_len);
- apr_base64_decode(token, base64_token);
+ space = strchr(auth_attr, ' ');
+ if (space)
+ {
+ const char *base64_token = apr_pstrmemdup(pool,
+ auth_attr,
+ space - auth_attr);
+ token_len = apr_base64_decode_len(base64_token);
+ token = apr_palloc(pool, token_len);
+ apr_base64_decode(token, base64_token);
+ }
}
/* We can get a whole batch of 401 responses from the server, but we should
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/client.c Wed Aug 11 16:43:22 2010
@@ -685,7 +685,9 @@ ra_svn_get_schemes(apr_pool_t *pool)
-static svn_error_t *ra_svn_open(svn_ra_session_t *session, const char *url,
+static svn_error_t *ra_svn_open(svn_ra_session_t *session,
+ const char **corrected_url,
+ const char *url,
const svn_ra_callbacks2_t *callbacks,
void *callback_baton,
apr_hash_t *config,
@@ -697,6 +699,10 @@ static svn_error_t *ra_svn_open(svn_ra_s
apr_uri_t uri;
svn_config_t *cfg, *cfg_client;
+ /* We don't support server-prescribed redirections in ra-svn. */
+ if (corrected_url)
+ *corrected_url = NULL;
+
SVN_ERR(parse_url(url, &uri, sess_pool));
parse_tunnel(url, &tunnel, pool);
@@ -885,8 +891,10 @@ static svn_error_t *ra_svn_end_commit(vo
&(commit_info->author),
&(commit_info->post_commit_err)));
- return ccb->callback(commit_info, ccb->callback_baton, ccb->pool);
+ if (ccb->callback)
+ SVN_ERR(ccb->callback(commit_info, ccb->callback_baton, ccb->pool));
+ return SVN_NO_ERROR;
}
static svn_error_t *ra_svn_commit(svn_ra_session_t *session,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c Wed Aug 11 16:43:22 2010
@@ -25,6 +25,7 @@
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_fs.h"
+#include "svn_hash.h"
#include "svn_iter.h"
#include "svn_repos.h"
#include "svn_string.h"
@@ -40,92 +41,6 @@
/*----------------------------------------------------------------------*/
-/** A variant of our hash-writing routine in libsvn_subr; this one
- writes to a stringbuf instead of a file, and outputs PROPS-END
- instead of END. If OLDHASH is not NULL, then only properties
- which vary from OLDHASH will be written, and properties which
- exist only in OLDHASH will be written out with "D" entries
- (like "K" entries but with no corresponding value). **/
-
-static void
-write_hash_to_stringbuf(apr_hash_t *hash,
- apr_hash_t *oldhash,
- svn_stringbuf_t **strbuf,
- apr_pool_t *pool)
-{
- apr_hash_index_t *this; /* current hash entry */
-
- *strbuf = svn_stringbuf_create("", pool);
-
- for (this = apr_hash_first(pool, hash); this; this = apr_hash_next(this))
- {
- const void *key;
- void *val;
- apr_ssize_t keylen;
- svn_string_t *value;
-
- /* Get this key and val. */
- apr_hash_this(this, &key, &keylen, &val);
- value = val;
-
- /* Don't output properties equal to the ones in oldhash, if present. */
- if (oldhash)
- {
- svn_string_t *oldvalue = apr_hash_get(oldhash, key, keylen);
-
- if (oldvalue && svn_string_compare(value, oldvalue))
- continue;
- }
-
- /* Output name length, then name. */
-
- svn_stringbuf_appendcstr(*strbuf,
- apr_psprintf(pool, "K %" APR_SSIZE_T_FMT "\n",
- keylen));
-
- svn_stringbuf_appendbytes(*strbuf, (const char *) key, keylen);
- svn_stringbuf_appendbytes(*strbuf, "\n", 1);
-
- /* Output value length, then value. */
-
- svn_stringbuf_appendcstr(*strbuf,
- apr_psprintf(pool, "V %" APR_SIZE_T_FMT "\n",
- value->len));
-
- svn_stringbuf_appendbytes(*strbuf, value->data, value->len);
- svn_stringbuf_appendbytes(*strbuf, "\n", 1);
- }
-
- if (oldhash)
- {
- /* Output a "D " entry for each property in oldhash but not hash. */
- for (this = apr_hash_first(pool, oldhash); this;
- this = apr_hash_next(this))
- {
- const void *key;
- apr_ssize_t keylen;
-
- /* Get this key. */
- apr_hash_this(this, &key, &keylen, NULL);
-
- /* Only output values deleted in hash. */
- if (apr_hash_get(hash, key, keylen))
- continue;
-
- /* Output name length, then name. */
-
- svn_stringbuf_appendcstr(*strbuf,
- apr_psprintf(pool,
- "D %" APR_SSIZE_T_FMT "\n",
- keylen));
-
- svn_stringbuf_appendbytes(*strbuf, (const char *) key, keylen);
- svn_stringbuf_appendbytes(*strbuf, "\n", 1);
- }
- }
- svn_stringbuf_appendbytes(*strbuf, "PROPS-END\n", 10);
-}
-
/* Compute the delta between OLDROOT/OLDPATH and NEWROOT/NEWPATH and
store it into a new temporary file *TEMPFILE. OLDROOT may be NULL,
@@ -509,6 +424,7 @@ dump_node(struct edit_baton *eb,
{
apr_hash_t *prophash, *oldhash = NULL;
apr_size_t proplen;
+ svn_stream_t *propstream;
SVN_ERR(svn_fs_node_proplist(&prophash, eb->fs_root, path, pool));
@@ -559,7 +475,13 @@ dump_node(struct edit_baton *eb,
SVN_REPOS_DUMPFILE_PROP_DELTA
": true\n"));
}
- write_hash_to_stringbuf(prophash, oldhash, &propstring, pool);
+ else
+ oldhash = apr_hash_make(pool);
+ propstring = svn_stringbuf_create_ensure(0, pool);
+ propstream = svn_stream_from_stringbuf(propstring, pool);
+ svn_hash_write_incremental(prophash, oldhash, propstream, "PROPS-END",
+ pool);
+ SVN_ERR(svn_stream_close(propstream));
proplen = propstring->len;
content_length += proplen;
SVN_ERR(svn_stream_printf(eb->stream, pool,
@@ -962,6 +884,7 @@ write_revision_record(svn_stream_t *stre
svn_stringbuf_t *encoded_prophash;
apr_time_t timetemp;
svn_string_t *datevalue;
+ svn_stream_t *propstream;
/* Read the revision props even if we're aren't going to dump
them for verification purposes */
@@ -981,7 +904,10 @@ write_revision_record(svn_stream_t *stre
datevalue);
}
- write_hash_to_stringbuf(props, NULL, &encoded_prophash, pool);
+ encoded_prophash = svn_stringbuf_create_ensure(0, pool);
+ propstream = svn_stream_from_stringbuf(encoded_prophash, pool);
+ svn_hash_write2(props, propstream, "PROPS-END", pool);
+ SVN_ERR(svn_stream_close(propstream));
/* ### someday write a revision-content-checksum */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c Wed Aug 11 16:43:22 2010
@@ -280,11 +280,36 @@ renumber_mergeinfo_revs(svn_string_t **f
apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create(pool);
- apr_hash_t *mergeinfo;
- apr_hash_t *final_mergeinfo = apr_hash_make(subpool);
+ svn_mergeinfo_t mergeinfo, predates_stream_mergeinfo;
+ svn_mergeinfo_t final_mergeinfo = apr_hash_make(subpool);
apr_hash_index_t *hi;
SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool));
+
+ /* Issue #3020
+ http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16
+ Remove mergeinfo older than the oldest revision in the dump stream
+ and adjust its revisions by the difference between the head rev of
+ the target repository and the current dump stream rev. */
+ if (rb->pb->oldest_old_rev > 1)
+ {
+ SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
+ &predates_stream_mergeinfo, mergeinfo,
+ rb->pb->oldest_old_rev - 1, 0,
+ TRUE, subpool, subpool));
+ SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
+ &mergeinfo, mergeinfo,
+ rb->pb->oldest_old_rev - 1, 0,
+ FALSE, subpool, subpool));
+ SVN_ERR(svn_mergeinfo__adjust_mergeinfo_rangelists(
+ &predates_stream_mergeinfo, predates_stream_mergeinfo,
+ -rb->rev_offset, subpool, subpool));
+ }
+ else
+ {
+ predates_stream_mergeinfo = NULL;
+ }
+
for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi))
{
const char *merge_source;
@@ -350,6 +375,11 @@ renumber_mergeinfo_revs(svn_string_t **f
apr_hash_set(final_mergeinfo, merge_source,
APR_HASH_KEY_STRING, rangelist);
}
+
+ if (predates_stream_mergeinfo)
+ SVN_ERR(svn_mergeinfo_merge(final_mergeinfo, predates_stream_mergeinfo,
+ subpool));
+
SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));
/* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0
@@ -1059,6 +1089,10 @@ new_revision_record(void **revision_bato
pb->notify->old_revision = rb->rev;
pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
}
+
+ /* Stash the oldest "old" revision committed from the load stream. */
+ if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
+ pb->oldest_old_rev = rb->rev;
}
/* If we're parsing revision 0, only the revision are (possibly)
@@ -1416,10 +1450,6 @@ close_revision(void *baton)
return svn_error_return(err);
}
- /* Stash the oldest "old" revision committed from the load stream. */
- if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
- pb->oldest_old_rev = *old_rev;
-
/* Run post-commit hook, if so commanded. */
if (pb->use_post_commit_hook)
{
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/replay.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/replay.c Wed Aug 11 16:43:22 2010
@@ -199,6 +199,8 @@ add_subdir(svn_fs_root_t *source_root,
svn_fs_path_change2_t *change;
svn_boolean_t readable = TRUE;
svn_fs_dirent_t *dent;
+ const char *copyfrom_path = NULL;
+ svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
const char *new_path;
void *val;
@@ -221,6 +223,13 @@ add_subdir(svn_fs_root_t *source_root,
/* If it's a delete, skip this entry. */
if (change->change_kind == svn_fs_path_change_delete)
continue;
+ else if (change->change_kind == svn_fs_path_change_replace)
+ {
+ /* ### Can this assert fail? */
+ SVN_ERR_ASSERT(change->copyfrom_known);
+ copyfrom_path = change->copyfrom_path;
+ copyfrom_rev = change->copyfrom_rev;
+ }
}
if (authz_read_func)
@@ -232,12 +241,31 @@ add_subdir(svn_fs_root_t *source_root,
if (dent->kind == svn_node_dir)
{
+ svn_fs_root_t *new_source_root;
+ const char *new_source_path;
void *new_dir_baton;
- SVN_ERR(add_subdir(source_root, target_root, editor, edit_baton,
+ if (copyfrom_path)
+ {
+ svn_fs_t *fs = svn_fs_root_fs(source_root);
+ SVN_ERR(svn_fs_revision_root(&new_source_root, fs, copyfrom_rev, pool));
+ new_source_path = copyfrom_path;
+ }
+ else
+ {
+ new_source_root = source_root;
+ new_source_path = svn_path_join(source_path, dent->name,
+ subpool);
+ }
+
+ /* ### authz considerations?
+ *
+ * I think not; when path_driver_cb_func() calls add_subdir(), it
+ * passes SOURCE_ROOT and SOURCE_PATH that are unreadable.
+ */
+ SVN_ERR(add_subdir(new_source_root, target_root, editor, edit_baton,
new_path, *dir_baton,
- svn_path_join(source_path, dent->name,
- subpool),
+ new_source_path,
authz_read_func, authz_read_baton,
changed_paths, subpool, &new_dir_baton));
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/repos.c Wed Aug 11 16:43:22 2010
@@ -1806,14 +1806,14 @@ struct hotcopy_ctx_t {
size_t src_len; /* len of the source path*/
};
-/** Called by (svn_io_dir_walk).
+/** Called by (svn_io_dir_walk2).
* Copies the repository structure with exception of @c SVN_REPOS__DB_DIR,
* @c SVN_REPOS__LOCK_DIR and @c SVN_REPOS__FORMAT.
* Those directories and files are handled separetly.
* @a baton is a pointer to (struct hotcopy_ctx_t) specifying
* destination path to copy to and the length of the source path.
*
- * @copydoc svn_io_dir_walk()
+ * @copydoc svn_io_dir_walk2()
*/
static svn_error_t *hotcopy_structure(void *baton,
const char *path,
@@ -1910,11 +1910,11 @@ svn_repos_hotcopy(const char *src_path,
hotcopy_context.dest = dst_path;
hotcopy_context.src_len = strlen(src_path);
- SVN_ERR(svn_io_dir_walk(src_path,
- 0,
- hotcopy_structure,
- &hotcopy_context,
- pool));
+ SVN_ERR(svn_io_dir_walk2(src_path,
+ 0,
+ hotcopy_structure,
+ &hotcopy_context,
+ pool));
/* Prepare dst_repos object so that we may create locks,
so that we may open repository */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config.c Wed Aug 11 16:43:22 2010
@@ -78,18 +78,29 @@ struct cfg_option_t
svn_error_t *
+svn_config_create(svn_config_t **cfgp, apr_pool_t *result_pool)
+{
+ svn_config_t *cfg = apr_palloc(result_pool, sizeof(*cfg));
+
+ cfg->sections = apr_hash_make(result_pool);
+ cfg->pool = result_pool;
+ cfg->x_pool = svn_pool_create(result_pool);
+ cfg->x_values = FALSE;
+ cfg->tmp_key = svn_stringbuf_create("", result_pool);
+ cfg->tmp_value = svn_stringbuf_create("", result_pool);
+
+ *cfgp = cfg;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_config_read(svn_config_t **cfgp, const char *file,
svn_boolean_t must_exist, apr_pool_t *pool)
{
- svn_config_t *cfg = apr_palloc(pool, sizeof(*cfg));
+ svn_config_t *cfg;
svn_error_t *err;
- cfg->sections = apr_hash_make(pool);
- cfg->pool = pool;
- cfg->x_pool = svn_pool_create(pool);
- cfg->x_values = FALSE;
- cfg->tmp_key = svn_stringbuf_create("", pool);
- cfg->tmp_value = svn_stringbuf_create("", pool);
+ SVN_ERR(svn_config_create(&cfg, pool));
/* Yes, this is platform-specific code in Subversion, but there's no
practical way to migrate it into APR, as it's simultaneously
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_win.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_win.c?rev=984468&r1=984467&r2=984468&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_win.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_win.c Wed Aug 11 16:43:22 2010
@@ -177,7 +177,7 @@ svn_config__parse_registry(svn_config_t
{
return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
"Unrecognised registry path '%s'",
- svn_path_local_style(file, pool));
+ svn_dirent_local_style(file, pool));
}
err = RegOpenKeyEx(base_hkey, file, 0,
@@ -189,11 +189,11 @@ svn_config__parse_registry(svn_config_t
if (!is_enoent)
return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
"Can't open registry key '%s'",
- svn_path_local_style(file, pool));
+ svn_dirent_local_style(file, pool));
else if (must_exist && is_enoent)
return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
"Can't find registry key '%s'",
- svn_path_local_style(file, pool));
+ svn_dirent_local_style(file, pool));
else
return SVN_NO_ERROR;
}