Modified: subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/replay.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/replay.c?rev=1655189&r1=1655188&r2=1655189&view=diff ============================================================================== --- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/replay.c (original) +++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/replay.c Tue Jan 27 23:27:44 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; @@ -169,12 +160,11 @@ typedef struct revision_report_t { svn_revnum_t revprop_rev; /* Revision properties for this revision. */ - apr_hash_t *revs_props; - apr_hash_t *props; + apr_hash_t *rev_props; /* 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; @@ -193,19 +183,13 @@ replay_opened(svn_ra_serf__xml_estate_t /* Before we can continue, we need the revision properties. */ SVN_ERR_ASSERT(!ctx->propfind_handler || ctx->propfind_handler->done); - /* Create a pool for the commit editor. */ - SVN_ERR(svn_ra_serf__select_revprops(&ctx->props, - ctx->revprop_target, - ctx->revprop_rev, - ctx->revs_props, - ctx->pool, - scratch_pool)); + svn_ra_serf__keep_only_regular_props(ctx->rev_props, scratch_pool); if (ctx->revstart_func) { SVN_ERR(ctx->revstart_func(ctx->revision, ctx->replay_baton, &ctx->editor, &ctx->editor_baton, - ctx->props, + ctx->rev_props, ctx->pool)); } } @@ -261,8 +245,7 @@ replay_closed(svn_ra_serf__xml_estate_t { SVN_ERR(ctx->revfinish_func(ctx->revision, ctx->replay_baton, ctx->editor, ctx->editor_baton, - ctx->props, - scratch_pool)); + ctx->rev_props, scratch_pool)); } } else if (leaving_state == REPLAY_TARGET_REVISION) @@ -486,35 +469,13 @@ 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, void *baton, serf_bucket_alloc_t *alloc, - apr_pool_t *pool) + apr_pool_t *pool /* request pool */, + apr_pool_t *scratch_pool) { struct revision_report_t *ctx = baton; serf_bucket_t *body_bkt; @@ -573,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); @@ -583,7 +544,7 @@ svn_ra_serf__replay(svn_ra_session_t *ra ctx.revision = revision; ctx.low_water_mark = low_water_mark; ctx.send_deltas = send_deltas; - ctx.revs_props = apr_hash_make(scratch_pool); + ctx.rev_props = apr_hash_make(scratch_pool); xmlctx = svn_ra_serf__xml_context_create(replay_ttable, replay_opened, replay_closed, @@ -591,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( @@ -644,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, @@ -653,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; @@ -661,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 @@ -686,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 { @@ -703,55 +687,56 @@ svn_ra_serf__replay_range(svn_ra_session requests to MAX_OUTSTANDING_REQUESTS. */ if (rev <= end_revision && active_reports < MAX_OUTSTANDING_REQUESTS) { - struct revision_report_t *replay_ctx; + 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; - replay_ctx = apr_pcalloc(ctx_pool, sizeof(*replay_ctx)); - replay_ctx->pool = ctx_pool; - replay_ctx->revstart_func = revstart_func; - replay_ctx->revfinish_func = revfinish_func; - replay_ctx->replay_baton = replay_baton; - replay_ctx->done = &done; - replay_ctx->done_list = &done_reports; - replay_ctx->include_path = include_path; - replay_ctx->revision = rev; - replay_ctx->low_water_mark = low_water_mark; - replay_ctx->send_deltas = send_deltas; - replay_ctx->done_item.data = replay_ctx; + 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->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; /* Request all properties of a certain revision. */ - replay_ctx->revs_props = apr_hash_make(replay_ctx->pool); + rev_ctx->rev_props = apr_hash_make(rev_ctx->pool); if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session)) { - replay_ctx->revprop_target = apr_psprintf(pool, "%s/%ld", - session->rev_stub, rev); - replay_ctx->revprop_rev = SVN_INVALID_REVNUM; + rev_ctx->revprop_target = apr_psprintf(rev_pool, "%s/%ld", + session->rev_stub, rev); + rev_ctx->revprop_rev = SVN_INVALID_REVNUM; } else { - replay_ctx->revprop_target = report_target; - replay_ctx->revprop_rev = rev; + rev_ctx->revprop_target = report_target; + rev_ctx->revprop_rev = rev; } - SVN_ERR(svn_ra_serf__deliver_props(&replay_ctx->propfind_handler, - replay_ctx->revs_props, session, - session->conns[0], - replay_ctx->revprop_target, - replay_ctx->revprop_rev, - "0", all_props, - replay_ctx->pool)); + 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_pool)); /* Spin up the serf request for the PROPFIND. */ - svn_ra_serf__request_create(replay_ctx->propfind_handler); + svn_ra_serf__request_create(rev_ctx->propfind_handler); /* 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 @@ -761,23 +746,21 @@ svn_ra_serf__replay_range(svn_ra_session xmlctx = svn_ra_serf__xml_context_create(replay_ttable, replay_opened, replay_closed, - replay_cdata, - replay_ctx, - ctx_pool); + replay_cdata, rev_ctx, + 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 = replay_ctx; - handler->conn = session->conns[0]; - handler->session = session; + handler->body_delegate_baton = rev_ctx; handler->done_delegate = replay_done; - handler->done_delegate_baton = replay_ctx; + handler->done_delegate_baton = rev_ctx; - replay_ctx->report_handler = handler; + rev_ctx->report_handler = handler; svn_ra_serf__request_create(handler); rev++; @@ -785,32 +768,12 @@ svn_ra_serf__replay_range(svn_ra_session } /* Run the serf loop. */ - SVN_ERR(svn_ra_serf__context_run_wait(&done, session, pool)); + done = FALSE; + 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 = FALSE; - 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/svn-auth-x509/subversion/libsvn_ra_serf/serf.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/serf.c?rev=1655189&r1=1655188&r2=1655189&view=diff ============================================================================== --- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/serf.c (original) +++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/serf.c Tue Jan 27 23:27:44 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)) @@ -871,6 +871,7 @@ serf__rev_proplist(svn_ra_session_t *ra_ svn_ra_serf__session_t *session = ra_session->priv; apr_hash_t *props; const char *propfind_path; + svn_ra_serf__handler_t *handler; if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session)) { @@ -886,17 +887,23 @@ 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)); } - /* ### fix: fetch hash of *just* the PATH@REV props. no nested hash. */ - SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0], - propfind_path, rev, "0", fetch_props, - result_pool, scratch_pool)); + props = apr_hash_make(result_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__select_revprops(ret_props, propfind_path, rev, props, - result_pool, scratch_pool)); + SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool)); + + svn_ra_serf__keep_only_regular_props(props, scratch_pool); + + *ret_props = props; return SVN_NO_ERROR; } @@ -967,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; @@ -1003,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/svn-auth-x509/subversion/libsvn_ra_serf/stat.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/stat.c?rev=1655189&r1=1655188&r2=1655189&view=diff ============================================================================== --- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/stat.c (original) +++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/stat.c Tue Jan 27 23:27:44 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/svn-auth-x509/subversion/libsvn_ra_serf/update.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/update.c?rev=1655189&r1=1655188&r2=1655189&view=diff ============================================================================== --- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/update.c (original) +++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/update.c Tue Jan 27 23:27:44 2015 @@ -931,7 +931,8 @@ ensure_file_opened(file_baton_t *file, static svn_error_t * headers_fetch(serf_bucket_t *headers, void *baton, - apr_pool_t *pool) + apr_pool_t *pool /* request pool */, + apr_pool_t *scratch_pool) { fetch_ctx_t *fetch_ctx = baton; @@ -1428,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) { @@ -1439,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) @@ -1460,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; @@ -1493,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; @@ -1590,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; @@ -2261,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); @@ -2302,7 +2302,8 @@ static svn_error_t * create_update_report_body(serf_bucket_t **body_bkt, void *baton, serf_bucket_alloc_t *alloc, - apr_pool_t *pool) + apr_pool_t *pool /* request pool */, + apr_pool_t *scratch_pool) { report_context_t *report = baton; body_create_baton_t *body = report->body; @@ -2330,7 +2331,8 @@ create_update_report_body(serf_bucket_t static svn_error_t * setup_update_report_headers(serf_bucket_t *headers, void *baton, - apr_pool_t *pool) + apr_pool_t *pool /* request pool */, + apr_pool_t *scratch_pool) { report_context_t *report = baton; @@ -2654,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; @@ -2672,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/svn-auth-x509/subversion/libsvn_ra_serf/util.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/util.c?rev=1655189&r1=1655188&r2=1655189&view=diff ============================================================================== --- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/util.c (original) +++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/util.c Tue Jan 27 23:27:44 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); @@ -1410,12 +1417,13 @@ static apr_status_t handle_response_cb(serf_request_t *request, serf_bucket_t *response, void *baton, - apr_pool_t *scratch_pool) + apr_pool_t *response_pool) { svn_ra_serf__handler_t *handler = baton; svn_error_t *err; apr_status_t inner_status; apr_status_t outer_status; + apr_pool_t *scratch_pool = response_pool; /* Scratch pool needed? */ err = svn_error_trace(handle_response(request, response, handler, &inner_status, @@ -1470,9 +1478,8 @@ setup_request(serf_request_t *request, { serf_bucket_alloc_t *bkt_alloc = serf_request_get_alloc(request); - /* ### should pass the scratch_pool */ SVN_ERR(handler->body_delegate(&body_bkt, handler->body_delegate_baton, - bkt_alloc, request_pool)); + bkt_alloc, request_pool, scratch_pool)); } else { @@ -1501,10 +1508,9 @@ setup_request(serf_request_t *request, if (handler->header_delegate) { - /* ### should pass the scratch_pool */ SVN_ERR(handler->header_delegate(headers_bkt, handler->header_delegate_baton, - request_pool)); + request_pool, scratch_pool)); } return SVN_NO_ERROR; @@ -1521,27 +1527,29 @@ setup_request_cb(serf_request_t *request void **acceptor_baton, serf_response_handler_t *s_handler, void **s_handler_baton, - apr_pool_t *pool) + apr_pool_t *request_pool) { svn_ra_serf__handler_t *handler = setup_baton; + apr_pool_t *scratch_pool; svn_error_t *err; - /* ### construct a scratch_pool? serf gives us a pool that will live for - ### the duration of the request. */ - apr_pool_t *scratch_pool = pool; + /* Construct a scratch_pool? serf gives us a pool that will live for + the duration of the request. But requests are retried in some cases */ + scratch_pool = svn_pool_create(request_pool); if (strcmp(handler->method, "HEAD") == 0) *acceptor = accept_head; else *acceptor = accept_response; - *acceptor_baton = handler->session; + *acceptor_baton = handler; *s_handler = handle_response_cb; *s_handler_baton = handler; err = svn_error_trace(setup_request(request, handler, req_bkt, - pool /* request_pool */, scratch_pool)); + request_pool, scratch_pool)); + svn_pool_destroy(scratch_pool); return save_error(handler->session, err); } @@ -1579,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; @@ -1593,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; @@ -1608,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; @@ -1638,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); } } } @@ -1664,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)); @@ -1692,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; @@ -1709,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)); } @@ -1723,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' @@ -1733,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; } @@ -1838,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, @@ -1877,7 +1876,7 @@ static apr_status_t handler_cleanup(void *baton) { svn_ra_serf__handler_t *handler = baton; - if (handler->scheduled && handler->conn) + if (handler->scheduled && handler->conn && handler->conn->conn) { serf_connection_reset(handler->conn->conn); } @@ -1886,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; @@ -1896,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/svn-auth-x509/subversion/libsvn_ra_serf/xml.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/xml.c?rev=1655189&r1=1655188&r2=1655189&view=diff ============================================================================== --- subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/xml.c (original) +++ subversion/branches/svn-auth-x509/subversion/libsvn_ra_serf/xml.c Tue Jan 27 23:27:44 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/svn-auth-x509/subversion/libsvn_repos/commit.c URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_repos/commit.c?rev=1655189&r1=1655188&r2=1655189&view=diff ============================================================================== --- subversion/branches/svn-auth-x509/subversion/libsvn_repos/commit.c (original) +++ subversion/branches/svn-auth-x509/subversion/libsvn_repos/commit.c Tue Jan 27 23:27:44 2015 @@ -73,7 +73,7 @@ struct edit_baton svn_repos_t *repos; /* URL to the root of the open repository. */ - const char *repos_url; + const char *repos_url_decoded; /* The name of the repository (here for convenience). */ const char *repos_name; @@ -262,7 +262,9 @@ make_dir_baton(struct edit_baton *edit_b /* This function is the shared guts of add_file() and add_directory(), which see for the meanings of the parameters. The only extra parameter here is IS_DIR, which is TRUE when adding a directory, - and FALSE when adding a file. */ + and FALSE when adding a file. + + COPY_PATH must be a full URL, not a relative path. */ static svn_error_t * add_file_or_directory(const char *path, void *parent_baton, @@ -317,8 +319,8 @@ add_file_or_directory(const char *path, /* For now, require that the url come from the same repository that this commit is operating on. */ copy_path = svn_path_uri_decode(copy_path, subpool); - repos_url_len = strlen(eb->repos_url); - if (strncmp(copy_path, eb->repos_url, repos_url_len) != 0) + repos_url_len = strlen(eb->repos_url_decoded); + if (strncmp(copy_path, eb->repos_url_decoded, repos_url_len) != 0) return svn_error_createf (SVN_ERR_FS_GENERAL, NULL, _("Source url '%s' is from different repository"), copy_path); @@ -932,7 +934,7 @@ svn_repos_get_commit_editor5(const svn_d void **edit_baton, svn_repos_t *repos, svn_fs_txn_t *txn, - const char *repos_url, + const char *repos_url_decoded, const char *base_path, apr_hash_t *revprop_table, svn_commit_callback2_t commit_callback, @@ -946,6 +948,7 @@ svn_repos_get_commit_editor5(const svn_d struct edit_baton *eb; svn_delta_shim_callbacks_t *shim_callbacks = svn_delta_shim_callbacks_default(pool); + const char *repos_url = svn_path_uri_encode(repos_url_decoded, pool); /* Do a global authz access lookup. Users with no write access whatsoever to the repository don't get a commit editor. */ @@ -987,7 +990,7 @@ svn_repos_get_commit_editor5(const svn_d eb->authz_baton = authz_baton; eb->base_path = svn_fspath__canonicalize(base_path, subpool); eb->repos = repos; - eb->repos_url = repos_url; + eb->repos_url_decoded = repos_url_decoded; eb->repos_name = svn_dirent_basename(svn_repos_path(repos, subpool), subpool); eb->fs = svn_repos_fs(repos); @@ -1003,7 +1006,7 @@ svn_repos_get_commit_editor5(const svn_d shim_callbacks->fetch_baton = eb; SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton, - eb->repos_url, eb->base_path, + repos_url, eb->base_path, shim_callbacks, pool, pool)); return SVN_NO_ERROR;
