Index: subversion/libsvn_ra_neon/ra_neon.h =================================================================== --- subversion/libsvn_ra_neon/ra_neon.h (revision 900319) +++ subversion/libsvn_ra_neon/ra_neon.h (working copy) @@ -447,6 +447,7 @@ const char *url, int depth, const char *label, + svn_boolean_t for_commit, const ne_propname *which_props, apr_pool_t *pool); @@ -455,6 +456,7 @@ svn_ra_neon__session_t *sess, const char *url, const char *label, + svn_boolean_t for_commit, const ne_propname *which_props, apr_pool_t *pool); @@ -491,6 +493,7 @@ svn_ra_neon__session_t *sess, const char *url, const char *label, + svn_boolean_t for_commit, const ne_propname *propname, apr_pool_t *pool); Index: subversion/libsvn_ra_neon/props.c =================================================================== --- subversion/libsvn_ra_neon/props.c (revision 900319) +++ subversion/libsvn_ra_neon/props.c (working copy) @@ -495,6 +495,7 @@ const char *url, int depth, const char *label, + svn_boolean_t for_commit, const ne_propname *which_props, apr_pool_t *pool) { @@ -507,6 +508,10 @@ /* If we have a label, use it. */ if (label != NULL) apr_hash_set(extra_headers, "Label", 5, label); + /* If for_commit is TRUE, set SVN-COMMIT so that PROXY can handle + it accordingly. */ + if (for_commit) + apr_hash_set(extra_headers, "SVN-COMMIT", APR_HASH_KEY_STRING, "1"); /* It's easier to roll our own PROPFIND here than use neon's current interfaces. */ @@ -561,6 +566,7 @@ svn_ra_neon__session_t *sess, const char *url, const char *label, + svn_boolean_t for_commit, const ne_propname *which_props, apr_pool_t *pool) { @@ -572,7 +578,7 @@ url_path[len - 1] = '\0'; SVN_ERR(svn_ra_neon__get_props(&props, sess, url_path, SVN_RA_NEON__DEPTH_ZERO, - label, which_props, pool)); + label, for_commit, which_props, pool)); /* ### HACK. We need to have the client canonicalize paths, get rid of double slashes and such. This check is just a check against @@ -612,6 +618,7 @@ svn_ra_neon__session_t *sess, const char *url, const char *label, + svn_boolean_t for_commit, const ne_propname *propname, apr_pool_t *pool) { @@ -621,8 +628,8 @@ const svn_string_t *value; props[0] = *propname; - SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, sess, url, label, props, - pool)); + SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, sess, url, label, for_commit, + props, pool)); name = apr_pstrcat(pool, propname->nspace, propname->name, NULL); value = apr_hash_get(rsrc->propset, name, APR_HASH_KEY_STRING); @@ -647,7 +654,7 @@ svn_string_t *propval; SVN_ERR(svn_ra_neon__get_props_resource(rsrc, sess, url, label, - starting_props, pool)); + FALSE, starting_props, pool)); /* Cache some of the resource information. */ @@ -917,13 +924,14 @@ DAV:baseline-collection property. */ /* ### should wrap this with info about rsrc==VCC */ SVN_ERR(svn_ra_neon__get_one_prop(&baseline, sess, vcc, NULL, - &svn_ra_neon__checked_in_prop, pool)); + FALSE, &svn_ra_neon__checked_in_prop, + pool)); /* ### do we want to optimize the props we fetch, based on what the ### user asked for? i.e. omit version-name if latest_rev is NULL */ SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, sess, baseline->data, NULL, - which_props, pool)); + FALSE, which_props, pool)); } else { @@ -938,7 +946,7 @@ /* ### do we want to optimize the props we fetch, based on what the ### user asked for? i.e. omit version-name if latest_rev is NULL */ SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, sess, vcc, label, - which_props, pool)); + FALSE, which_props, pool)); } /* Return the baseline rsrc, which now contains whatever set of @@ -1281,7 +1289,7 @@ /* Depth-zero PROPFIND is the One True DAV Way. */ err = svn_ra_neon__get_props(&resources, ras, final_url, SVN_RA_NEON__DEPTH_ZERO, - NULL, NULL /* all props */, pool); + NULL, FALSE, NULL /* all props */, pool); if (err) { if (err->apr_err == SVN_ERR_FS_NOT_FOUND) Index: subversion/libsvn_ra_neon/commit.c =================================================================== --- subversion/libsvn_ra_neon/commit.c (revision 900319) +++ subversion/libsvn_ra_neon/commit.c (working copy) @@ -237,7 +237,7 @@ /* Get the DAV:checked-in property, which contains the URL of the Version Resource */ SVN_ERR(svn_ra_neon__get_props_resource(&propres, cc->ras, url, - NULL, fetch_props, pool)); + NULL, TRUE, fetch_props, pool)); url_str = apr_hash_get(propres->propset, SVN_RA_NEON__PROP_CHECKED_IN, APR_HASH_KEY_STRING); @@ -1387,7 +1387,8 @@ This should give us the HEAD revision of the moment. */ SVN_ERR(svn_ra_neon__get_one_prop(&baseline_url, cc->ras, vcc, NULL, - &svn_ra_neon__checked_in_prop, pool)); + TRUE, &svn_ra_neon__checked_in_prop, + pool)); baseline_rsrc.pool = pool; baseline_rsrc.vsn_url = baseline_url->data; Index: subversion/libsvn_ra_neon/fetch.c =================================================================== --- subversion/libsvn_ra_neon/fetch.c (revision 900319) +++ subversion/libsvn_ra_neon/fetch.c (working copy) @@ -719,6 +719,7 @@ ras, final_url, NULL, + FALSE, &md5_propname, pool); @@ -769,7 +770,8 @@ if (props) { SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, ras, final_url, - NULL, NULL /* all props */, + NULL, FALSE, + NULL /* all props */, pool)); *props = apr_hash_make(pool); SVN_ERR(filter_props(*props, rsrc, TRUE, pool)); @@ -836,7 +838,7 @@ const svn_string_t *deadprop_count; SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, ras, - final_url, NULL, + final_url, NULL, FALSE, deadprop_count_support_props, pool)); @@ -935,7 +937,7 @@ PROPFIND on the directory of depth 1. */ SVN_ERR(svn_ra_neon__get_props(&resources, ras, final_url, SVN_RA_NEON__DEPTH_ONE, - NULL, which_props, pool)); + NULL, FALSE, which_props, pool)); /* Count the number of path components in final_url. */ final_url_n_components = svn_path_component_count(final_url); @@ -1073,7 +1075,8 @@ if (props) { SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, ras, final_url, - NULL, NULL /* all props */, + NULL, FALSE, + NULL /* all props */, pool)); *props = apr_hash_make(pool); @@ -1197,7 +1200,7 @@ { const char *url = apr_psprintf(pool, "%s/%ld", ras->rev_stub, rev); SVN_ERR(svn_ra_neon__get_props_resource(&bln, ras, url, - NULL, NULL, pool)); + NULL, FALSE, NULL, pool)); } else { @@ -1584,7 +1587,7 @@ rb->ras, bc_url, SVN_RA_NEON__DEPTH_ONE, - NULL, NULL /* allprops */, + NULL, FALSE, NULL /* allprops */, TOP_DIR(rb).pool)); /* re-index the results into a more usable hash. @@ -1898,6 +1901,7 @@ rb->ras, rb->href->data, NULL, + FALSE, NULL, pool)); props = rsrc->propset; @@ -1924,8 +1928,8 @@ SVN_ERR(svn_ra_neon__get_props_resource(&rsrc, rb->ras, TOP_DIR(rb).vsn_url, + NULL, FALSE, NULL, - NULL, pool)); props = rsrc->propset; } Index: subversion/mod_dav_svn/mirror.c =================================================================== --- subversion/mod_dav_svn/mirror.c (revision 900319) +++ subversion/mod_dav_svn/mirror.c (working copy) @@ -30,7 +30,54 @@ #include "dav_svn.h" +#define USERDATA_KEY "mod_dav_svn_userdata_key" +typedef struct +{ + int mk_activity_has_happened; +} ctx_data; + +static apr_status_t +initialize_ctx_data(ctx_data **data, + request_rec *r, + apr_pool_t *pool) +{ + ctx_data *ctx = apr_pcalloc(pool, sizeof(*ctx)); + + if (apr_pool_userdata_set(ctx, USERDATA_KEY, NULL, pool) != APR_SUCCESS) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "mod_dav_svn: Error setting connection pool userdata"); + return HTTP_INTERNAL_SERVER_ERROR; + } + ctx->mk_activity_has_happened = 0; + *data = ctx; + return APR_SUCCESS; +} + +static int +get_userdata(ctx_data **ctx, + request_rec *r) +{ + void *data; + apr_pool_t *pool = r->connection->pool; + + if (apr_pool_userdata_get(&data, USERDATA_KEY, pool) != APR_SUCCESS) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "mod_dav_svn: Error fetching connection userdata"); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (data) + *ctx = data; + else + initialize_ctx_data(ctx, r, pool); + + return OK; +} + + /* Tweak the request record R, and add the necessary filters, so that the request is ready to be proxied away. MASTER_URI is the URI specified in the SVNMasterURI Apache configuration value. @@ -64,6 +111,14 @@ if (root_dir && master_uri) { const char *seg; + const char *action; + int is_commit = 0; + if (r->method_number == M_MKACTIVITY) { + ctx_data *ctx; + int ret = get_userdata(&ctx, r); + if (ret == OK) + ctx->mk_activity_has_happened = 1; + } /* We know we can always safely handle these. */ if (r->method_number == M_REPORT || @@ -71,6 +126,17 @@ return OK; } + action = apr_table_get(r->headers_in, "SVN-COMMIT"); + if (action) { + is_commit = 1; + } else { + ctx_data *ctx; + int ret = get_userdata(&ctx, r); + if (ret == OK && ctx->mk_activity_has_happened == 1) + is_commit = 1; + } + + /* These are read-only requests -- the kind we like to handle ourselves -- but we need to make sure they aren't aimed at working resource URIs before trying to field them. Why? @@ -79,12 +145,18 @@ of the repository isn't guaranteed to have on hand. */ if (r->method_number == M_PROPFIND || r->method_number == M_GET) { - seg = ap_strstr(r->unparsed_uri, root_dir); - if (seg && ap_strstr_c(seg, - apr_pstrcat(r->pool, special_uri, - "/wrk/", NULL))) { - seg += strlen(root_dir); - proxy_request_fixup(r, master_uri, seg); + if (is_commit) { + seg = ap_strstr(r->unparsed_uri, root_dir); + if (seg && (ap_strstr_c(seg, + apr_pstrcat(r->pool, special_uri, + "/wrk/", NULL)) || + ap_strstr_c(seg, + apr_pstrcat(r->pool, special_uri, + "/vcc/", NULL)) + )) { + seg += strlen(root_dir); + proxy_request_fixup(r, master_uri, seg); + } } return OK; }