const char * svn_log__switch(const char *path, const char *dst_path, svn_revnum_t revnum, svn_depth_t depth, apr_pool_t *pool) { return apr_psprintf(pool, "switch %s %s@%ld%s", svn_path_uri_encode(path, pool), svn_path_uri_encode(dst_path, pool), revnum, log_depth(depth, pool)); }
const char * svn_log__log(const apr_array_header_t *paths, svn_revnum_t start, svn_revnum_t end, int limit, svn_boolean_t discover_changed_paths, svn_boolean_t strict_node_history, svn_boolean_t include_merged_revisions, const apr_array_header_t *revprops, apr_pool_t *pool) { int i; apr_pool_t *iterpool = svn_pool_create(pool); svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool); svn_stringbuf_t *options = svn_stringbuf_create_empty(pool); for (i = 0; i < paths->nelts; i++) { const char *path = APR_ARRAY_IDX(paths, i, const char *); svn_pool_clear(iterpool); if (i != 0) svn_stringbuf_appendcstr(space_separated_paths, " "); svn_stringbuf_appendcstr(space_separated_paths, svn_path_uri_encode(path, iterpool)); } if (limit) { const char *tmp = apr_psprintf(pool, " limit=%d", limit); svn_stringbuf_appendcstr(options, tmp); } if (discover_changed_paths) svn_stringbuf_appendcstr(options, " discover-changed-paths"); if (strict_node_history) svn_stringbuf_appendcstr(options, " strict"); if (include_merged_revisions) svn_stringbuf_appendcstr(options, log_include_merged_revisions(include_merged_revisions)); if (revprops == NULL) svn_stringbuf_appendcstr(options, " revprops=all"); else if (revprops->nelts > 0) { svn_stringbuf_appendcstr(options, " revprops=("); for (i = 0; i < revprops->nelts; i++) { const char *name = APR_ARRAY_IDX(revprops, i, const char *); svn_pool_clear(iterpool); if (i != 0) svn_stringbuf_appendcstr(options, " "); svn_stringbuf_appendcstr(options, svn_path_uri_encode(name, iterpool)); } svn_stringbuf_appendcstr(options, ")"); }
const char * svn_log__get_mergeinfo(const apr_array_header_t *paths, svn_mergeinfo_inheritance_t inherit, svn_boolean_t include_descendants, apr_pool_t *pool) { int i; apr_pool_t *iterpool = svn_pool_create(pool); svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool); for (i = 0; i < paths->nelts; i++) { const char *path = APR_ARRAY_IDX(paths, i, const char *); svn_pool_clear(iterpool); if (i != 0) svn_stringbuf_appendcstr(space_separated_paths, " "); svn_stringbuf_appendcstr(space_separated_paths, svn_path_uri_encode(path, iterpool)); } svn_pool_destroy(iterpool); return apr_psprintf(pool, "get-mergeinfo (%s) %s%s", space_separated_paths->data, svn_inheritance_to_word(inherit), include_descendants ? " include-descendants" : ""); }
/* 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. URI_SEGMENT is the URI bits relative to the repository root (but if non-empty, *does* have a leading slash delimiter). MASTER_URI and URI_SEGMENT are not URI-encoded. */ static int proxy_request_fixup(request_rec *r, const char *master_uri, const char *uri_segment) { if (uri_segment[0] != '\0' && uri_segment[0] != '/') { ap_log_rerror(APLOG_MARK, APLOG_ERR, SVN_ERR_BAD_CONFIG_VALUE, r, "Invalid URI segment '%s' in slave fixup", uri_segment); return HTTP_INTERNAL_SERVER_ERROR; } r->proxyreq = PROXYREQ_REVERSE; r->uri = r->unparsed_uri; r->filename = (char *) svn_path_uri_encode(apr_pstrcat(r->pool, "proxy:", master_uri, uri_segment, SVN_VA_NULL), r->pool); r->handler = "proxy-server"; /* ### FIXME: Seems we could avoid adding some or all of these filters altogether when the root_dir (that is, the slave's location, relative to the server root) and path portion of the master_uri (the master's location, relative to the server root) are identical, rather than adding them here and then trying to remove them later. (See the filter removal logic in dav_svn__location_in_filter() and dav_svn__location_body_filter(). -- cmpilato */ ap_add_output_filter("LocationRewrite", NULL, r, r->connection); ap_add_output_filter("ReposRewrite", NULL, r, r->connection); ap_add_input_filter("IncomingRewrite", NULL, r, r->connection); return OK; }
apr_status_t dav_svn__location_header_filter(ap_filter_t *f, apr_bucket_brigade *bb) { request_rec *r = f->r; const char *master_uri; const char *location, *start_foo = NULL; /* Don't filter if we're in a subrequest or we aren't setup to proxy anything. */ master_uri = dav_svn__get_master_uri(r); master_uri = svn_path_uri_encode(master_uri, r->pool); if (r->main || !master_uri) { ap_remove_output_filter(f); return ap_pass_brigade(f->next, bb); } location = apr_table_get(r->headers_out, "Location"); if (location) { start_foo = ap_strstr_c(location, master_uri); } if (start_foo) { const char *new_uri; start_foo += strlen(master_uri); new_uri = ap_construct_url(r->pool, apr_pstrcat(r->pool, dav_svn__get_root_dir(r), "/", start_foo, SVN_VA_NULL), r); apr_table_set(r->headers_out, "Location", new_uri); } return ap_pass_brigade(f->next, bb); }
/* 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. URI_SEGMENT is the URI bits relative to the repository root (but if non-empty, *does* have a leading slash delimiter). MASTER_URI and URI_SEGMENT are not URI-encoded. */ static int proxy_request_fixup(request_rec *r, const char *master_uri, const char *uri_segment) { if (uri_segment[0] != '\0' && uri_segment[0] != '/') { ap_log_rerror(APLOG_MARK, APLOG_ERR, SVN_ERR_BAD_CONFIG_VALUE, r, "Invalid URI segment '%s' in slave fixup", uri_segment); return HTTP_INTERNAL_SERVER_ERROR; } r->proxyreq = PROXYREQ_REVERSE; r->uri = r->unparsed_uri; r->filename = (char *) svn_path_uri_encode(apr_pstrcat(r->pool, "proxy:", master_uri, uri_segment, (char *)NULL), r->pool); r->handler = "proxy-server"; ap_add_output_filter("LocationRewrite", NULL, r, r->connection); ap_add_output_filter("ReposRewrite", NULL, r, r->connection); ap_add_input_filter("IncomingRewrite", NULL, r, r->connection); return OK; }
/* Helper function. Set URL to a "file://" url for the current directory, suffixed by the forward-slash-style relative path SUFFIX, performing all allocation in POOL. */ static svn_error_t * current_directory_url(const char **url, const char *suffix, apr_pool_t *pool) { /* 8KB is a lot, but it almost guarantees that any path will fit. */ char curdir[8192]; const char *utf8_ls_curdir, *utf8_is_curdir, *unencoded_url; if (! getcwd(curdir, sizeof(curdir))) return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed"); SVN_ERR(svn_utf_cstring_to_utf8(&utf8_ls_curdir, curdir, pool)); utf8_is_curdir = svn_path_internal_style(utf8_ls_curdir, pool); unencoded_url = apr_psprintf(pool, "file://%s%s%s%s", (utf8_is_curdir[0] != '/') ? "/" : "", utf8_is_curdir, (suffix[0] && suffix[0] != '/') ? "/" : "", suffix); *url = svn_path_uri_encode(unencoded_url, pool); return SVN_NO_ERROR; }
svn_error_t * svn_cache__create_memcache(svn_cache__t **cache_p, svn_memcache_t *memcache, svn_cache__serialize_func_t serialize_func, svn_cache__deserialize_func_t deserialize_func, apr_ssize_t klen, const char *prefix, apr_pool_t *pool) { svn_cache__t *wrapper = apr_pcalloc(pool, sizeof(*wrapper)); memcache_t *cache = apr_pcalloc(pool, sizeof(*cache)); cache->serialize_func = serialize_func; cache->deserialize_func = deserialize_func; cache->klen = klen; cache->prefix = svn_path_uri_encode(prefix, pool); cache->memcache = memcache->c; wrapper->vtable = &memcache_vtable; wrapper->cache_internal = cache; wrapper->error_handler = 0; wrapper->error_baton = 0; *cache_p = wrapper; return SVN_NO_ERROR; }
const char * svn_log__status(const char *path, svn_revnum_t rev, svn_depth_t depth, apr_pool_t *pool) { return apr_psprintf(pool, "status %s r%ld%s", svn_path_uri_encode(path, pool), rev, log_depth(depth, pool)); }
const char * svn_log__checkout(const char *path, svn_revnum_t rev, svn_depth_t depth, apr_pool_t *pool) { return apr_psprintf(pool, "checkout-or-export %s r%ld%s", svn_path_uri_encode(path, pool), rev, log_depth(depth, pool)); }
const char * svn_log__diff(const char *path, svn_revnum_t from_revnum, const char *dst_path, svn_revnum_t revnum, svn_depth_t depth, svn_boolean_t ignore_ancestry, apr_pool_t *pool) { const char *log_ignore_ancestry = (ignore_ancestry ? " ignore-ancestry" : ""); if (strcmp(path, dst_path) == 0) return apr_psprintf(pool, "diff %s r%ld:%ld%s%s", svn_path_uri_encode(path, pool), from_revnum, revnum, log_depth(depth, pool), log_ignore_ancestry); return apr_psprintf(pool, "diff %s@%ld %s@%ld%s%s", svn_path_uri_encode(path, pool), from_revnum, svn_path_uri_encode(dst_path, pool), revnum, log_depth(depth, pool), log_ignore_ancestry); }
const char * svn_log__get_file(const char *path, svn_revnum_t rev, svn_boolean_t want_contents, svn_boolean_t want_props, apr_pool_t *pool) { return apr_psprintf(pool, "get-file %s r%ld%s%s", svn_path_uri_encode(path, pool), rev, want_contents ? " text" : "", want_props ? " props" : ""); }
static svn_error_t * svn_ra_local__get_session_url(svn_ra_session_t *session, const char **url, apr_pool_t *pool) { svn_ra_local__session_baton_t *sess = session->priv; *url = svn_path_join(sess->repos_url, svn_path_uri_encode(sess->fs_path->data + 1, pool), pool); return SVN_NO_ERROR; }
const char * svn_log__update(const char *path, svn_revnum_t rev, svn_depth_t depth, svn_boolean_t send_copyfrom_args, apr_pool_t *pool) { return apr_psprintf(pool, "update %s r%ld%s%s", svn_path_uri_encode(path, pool), rev, log_depth(depth, pool), (send_copyfrom_args ? " send-copyfrom-args" : "")); }
/* Set *MC_KEY to a memcache key for the given key KEY for CACHE, allocated in POOL. */ static svn_error_t * build_key(const char **mc_key, memcache_t *cache, const void *raw_key, apr_pool_t *pool) { const char *encoded_suffix; const char *long_key; apr_size_t long_key_len; if (cache->klen == APR_HASH_KEY_STRING) encoded_suffix = svn_path_uri_encode(raw_key, pool); else { const svn_string_t *raw = svn_string_ncreate(raw_key, cache->klen, pool); const svn_string_t *encoded = svn_base64_encode_string2(raw, FALSE, pool); encoded_suffix = encoded->data; } long_key = apr_pstrcat(pool, "SVN:", cache->prefix, ":", encoded_suffix, (char *)NULL); long_key_len = strlen(long_key); /* We don't want to have a key that's too big. If it was going to be too big, we MD5 the entire string, then replace the last bit with the checksum. Note that APR_MD5_DIGESTSIZE is for the pure binary digest; we have to double that when we convert to hex. Every key we use will either be at most MEMCACHED_KEY_UNHASHED_LEN bytes long, or be exactly MAX_MEMCACHED_KEY_LEN bytes long. */ if (long_key_len > MEMCACHED_KEY_UNHASHED_LEN) { svn_checksum_t *checksum; SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, long_key, long_key_len, pool)); long_key = apr_pstrcat(pool, apr_pstrmemdup(pool, long_key, MEMCACHED_KEY_UNHASHED_LEN), svn_checksum_to_cstring_display(checksum, pool), (char *)NULL); } *mc_key = long_key; return SVN_NO_ERROR; }
/* 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. URI_SEGMENT is the URI bits relative to the repository root (but if non-empty, *does* have a leading slash delimiter). MASTER_URI and URI_SEGMENT are not URI-encoded. */ static void proxy_request_fixup(request_rec *r, const char *master_uri, const char *uri_segment) { assert((uri_segment[0] == '\0') || (uri_segment[0] == '/')); r->proxyreq = PROXYREQ_REVERSE; r->uri = r->unparsed_uri; r->filename = (char *) svn_path_uri_encode(apr_pstrcat(r->pool, "proxy:", master_uri, uri_segment, (char *)NULL), r->pool); r->handler = "proxy-server"; ap_add_output_filter("LocationRewrite", NULL, r, r->connection); ap_add_output_filter("ReposRewrite", NULL, r, r->connection); ap_add_input_filter("IncomingRewrite", NULL, r, r->connection); }
/* If the components of RELPATH exactly match (after being URI-encoded) the final components of URL, return a copy of URL minus those components allocated in RESULT_POOL; otherwise, return NULL. */ static const char * url_remove_final_relpath(const char *url, const char *relpath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { char *result = apr_pstrdup(result_pool, url); char *result_end; const char *relpath_end; SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(url)); SVN_ERR_ASSERT_NO_RETURN(svn_relpath_is_canonical(relpath)); if (relpath[0] == 0) return result; relpath = svn_path_uri_encode(relpath, scratch_pool); result_end = result + strlen(result) - 1; relpath_end = relpath + strlen(relpath) - 1; while (relpath_end >= relpath) { if (*result_end != *relpath_end) return NULL; relpath_end--; result_end--; } if (*result_end != '/') return NULL; *result_end = 0; return result; }
dav_error * dav_svn__replay_report(const dav_resource *resource, const apr_xml_doc *doc, ap_filter_t *output) { svn_revnum_t low_water_mark = SVN_INVALID_REVNUM; svn_revnum_t rev = SVN_INVALID_REVNUM; const svn_delta_editor_t *editor; svn_boolean_t send_deltas = TRUE; dav_svn__authz_read_baton arb; const char *base_dir = resource->info->repos_path; apr_bucket_brigade *bb; apr_xml_elem *child; svn_fs_root_t *root; svn_error_t *err; void *edit_baton; int ns; /* The request won't have a repos_path if it's for the root. */ if (! base_dir) base_dir = ""; arb.r = resource->info->r; arb.repos = resource->info->repos; ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE); if (ns == -1) return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0, "The request does not contain the 'svn:' " "namespace, so it is not going to have an " "svn:revision element. That element is " "required.", SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG); for (child = doc->root->first_child; child != NULL; child = child->next) { if (child->ns == ns) { const char *cdata; if (strcmp(child->name, "revision") == 0) { cdata = dav_xml_get_cdata(child, resource->pool, 1); if (! cdata) return malformed_element_error("revision", resource->pool); rev = SVN_STR_TO_REV(cdata); } else if (strcmp(child->name, "low-water-mark") == 0) { cdata = dav_xml_get_cdata(child, resource->pool, 1); if (! cdata) return malformed_element_error("low-water-mark", resource->pool); low_water_mark = SVN_STR_TO_REV(cdata); } else if (strcmp(child->name, "send-deltas") == 0) { cdata = dav_xml_get_cdata(child, resource->pool, 1); if (! cdata) return malformed_element_error("send-deltas", resource->pool); send_deltas = atoi(cdata); } } } if (! SVN_IS_VALID_REVNUM(rev)) return dav_svn__new_error_tag (resource->pool, HTTP_BAD_REQUEST, 0, "Request was missing the revision argument.", SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG); if (! SVN_IS_VALID_REVNUM(low_water_mark)) return dav_svn__new_error_tag (resource->pool, HTTP_BAD_REQUEST, 0, "Request was missing the low-water-mark argument.", SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG); bb = apr_brigade_create(resource->pool, output->c->bucket_alloc); if ((err = svn_fs_revision_root(&root, resource->info->repos->fs, rev, resource->pool))) return dav_svn__convert_err(err, HTTP_INTERNAL_SERVER_ERROR, "Couldn't retrieve revision root", resource->pool); make_editor(&editor, &edit_baton, bb, output, resource->pool); if ((err = svn_repos_replay2(root, base_dir, low_water_mark, send_deltas, editor, edit_baton, dav_svn__authz_read_func(&arb), &arb, resource->pool))) return dav_svn__convert_err(err, HTTP_INTERNAL_SERVER_ERROR, "Problem replaying revision", resource->pool); if ((err = end_report(edit_baton))) return dav_svn__convert_err(err, HTTP_INTERNAL_SERVER_ERROR, "Problem closing editor drive", resource->pool); { const char *action, *log_base_dir; if (base_dir && base_dir[0] != '\0') log_base_dir = svn_path_uri_encode(base_dir, resource->info->r->pool); else log_base_dir = "/"; action = apr_psprintf(resource->info->r->pool, "replay %s r%ld", log_base_dir, rev); dav_svn__operational_log(resource->info, action); } ap_fflush(output, bb); return NULL; }
/* This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * svn_cl__export(apr_getopt_t *os, void *baton, apr_pool_t *pool) { svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; const char *from, *to; apr_array_header_t *targets; svn_error_t *err; svn_opt_revision_t peg_revision; const char *truefrom; SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os, opt_state->targets, ctx, pool)); /* We want exactly 1 or 2 targets for this subcommand. */ if (targets->nelts < 1) return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL); if (targets->nelts > 2) return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL); /* The first target is the `from' path. */ from = APR_ARRAY_IDX(targets, 0, const char *); /* Get the peg revision if present. */ SVN_ERR(svn_opt_parse_path(&peg_revision, &truefrom, from, pool)); /* If only one target was given, split off the basename to use as the `to' path. Else, a `to' path was supplied. */ if (targets->nelts == 1) to = svn_path_uri_decode(svn_path_basename(truefrom, pool), pool); else to = APR_ARRAY_IDX(targets, 1, const char *); SVN_ERR(svn_opt__split_arg_at_peg_revision(&to, NULL, to, pool)); if (! opt_state->quiet) svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, FALSE, TRUE, FALSE, pool); if (opt_state->depth == svn_depth_unknown) opt_state->depth = svn_depth_infinity; /* Decode the partially encoded URL and escape all URL unsafe characters. */ if (svn_path_is_url(truefrom)) truefrom = svn_path_uri_encode(svn_path_uri_decode(truefrom, pool), pool); /* Do the export. */ err = svn_client_export4(NULL, truefrom, to, &peg_revision, &(opt_state->start_revision), opt_state->force, opt_state->ignore_externals, opt_state->depth, opt_state->native_eol, ctx, pool); if (err && err->apr_err == SVN_ERR_WC_OBSTRUCTED_UPDATE && !opt_state->force) SVN_ERR_W(err, _("Destination directory exists; please remove " "the directory or use --force to overwrite")); return err; }
/* Opens a session */ char session_open(session_t *session) { svn_error_t *err; svn_client_ctx_t *ctx; svn_config_t *config; svn_auth_baton_t *auth_baton; const char *root; const char *config_dir = NULL; /* Make sure the URL is properly encoded */ session->encoded_url = svn_path_uri_encode(svn_path_canonicalize(session->url, session->pool), session->pool); /* Do neccessary SVN library initialization */ if ((err = svn_fs_initialize(session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } if ((err = svn_ra_initialize(session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } if ((err = svn_config_ensure(NULL, session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } /* Setup the client context */ if ((err = svn_client_create_context(&ctx, session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } if ((err = svn_config_get_config(&(ctx->config), NULL, session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } if (session->config_dir != NULL) { const char *path; if ((err = svn_utf_cstring_to_utf8(&path, session->config_dir, session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } config_dir = svn_path_canonicalize(path, session->pool); } /* Setup auth baton */ config = apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG, APR_HASH_KEY_STRING); if ((err = svn_cmdline_setup_auth_baton(&auth_baton, (session->flags & SF_NON_INTERACTIVE), session->username, session->password, config_dir, (session->flags & SF_NO_AUTH_CACHE), config, NULL, NULL, session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } ctx->auth_baton = auth_baton; /* Setup the RA session */ if ((err = svn_client_open_ra_session(&(session->ra), session->encoded_url, ctx, session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } /* Determine the root (and the prefix) of the URL */ if ((err = svn_ra_get_repos_root(session->ra, &root, session->pool))) { utils_handle_error(err, stderr, FALSE, "ERROR: "); svn_error_clear(err); return 1; } session->root = root; if (!strcmp(session->encoded_url, root)) { session->prefix = apr_pstrdup(session->pool, ""); } else { session->prefix = apr_pstrdup(session->pool, session->encoded_url + strlen(root) + 1); } session->prefix = session_obfuscate(session, session->pool, session->prefix); return 0; }
const char * svn_log__rev_prop(svn_revnum_t rev, const char *name, apr_pool_t *pool) { return apr_psprintf(pool, "rev-prop r%ld %s", rev, svn_path_uri_encode(name, pool)); }
const char * svn_log__reparent(const char *path, apr_pool_t *pool) { return apr_psprintf(pool, "reparent %s", svn_path_uri_encode(path, pool)); }
apr_status_t dav_svn__location_in_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { request_rec *r = f->r; locate_ctx_t *ctx = f->ctx; apr_status_t rv; apr_bucket *bkt; const char *master_uri, *root_dir, *canonicalized_uri; apr_uri_t uri; /* Don't filter if we're in a subrequest or we aren't setup to proxy anything. */ master_uri = dav_svn__get_master_uri(r); if (r->main || !master_uri) { ap_remove_input_filter(f); return ap_get_brigade(f->next, bb, mode, block, readbytes); } /* And don't filter if our search-n-replace would be a noop anyway (that is, if our root path matches that of the master server). */ apr_uri_parse(r->pool, master_uri, &uri); root_dir = dav_svn__get_root_dir(r); canonicalized_uri = svn_urlpath__canonicalize(uri.path, r->pool); if (strcmp(canonicalized_uri, root_dir) == 0) { ap_remove_input_filter(f); return ap_get_brigade(f->next, bb, mode, block, readbytes); } /* ### FIXME: While we want to fix up any locations in proxied XML ### requests, we do *not* want to be futzing with versioned (or ### to-be-versioned) data, such as the file contents present in ### PUT requests and properties in PROPPATCH requests. ### See issue #3445 for details. */ /* We are url encoding the current url and the master url as incoming(from client) request body has it encoded already. */ canonicalized_uri = svn_path_uri_encode(canonicalized_uri, r->pool); root_dir = svn_path_uri_encode(root_dir, r->pool); if (!f->ctx) { ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx)); ctx->remotepath = canonicalized_uri; ctx->remotepath_len = strlen(ctx->remotepath); ctx->localpath = root_dir; ctx->localpath_len = strlen(ctx->localpath); ctx->pattern = apr_strmatch_precompile(r->pool, ctx->localpath, 1); ctx->pattern_len = ctx->localpath_len; } rv = ap_get_brigade(f->next, bb, mode, block, readbytes); if (rv) { return rv; } bkt = APR_BRIGADE_FIRST(bb); while (bkt != APR_BRIGADE_SENTINEL(bb)) { const char *data, *match; apr_size_t len; if (APR_BUCKET_IS_METADATA(bkt)) { bkt = APR_BUCKET_NEXT(bkt); continue; } /* read */ apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ); match = apr_strmatch(ctx->pattern, data, len); if (match) { apr_bucket *next_bucket; apr_bucket_split(bkt, match - data); next_bucket = APR_BUCKET_NEXT(bkt); apr_bucket_split(next_bucket, ctx->pattern_len); bkt = APR_BUCKET_NEXT(next_bucket); apr_bucket_delete(next_bucket); next_bucket = apr_bucket_pool_create(ctx->remotepath, ctx->remotepath_len, r->pool, bb->bucket_alloc); APR_BUCKET_INSERT_BEFORE(bkt, next_bucket); } else { bkt = APR_BUCKET_NEXT(bkt); } } return APR_SUCCESS; }
apr_status_t dav_svn__location_body_filter(ap_filter_t *f, apr_bucket_brigade *bb) { request_rec *r = f->r; locate_ctx_t *ctx = f->ctx; apr_bucket *bkt; const char *master_uri, *root_dir, *canonicalized_uri; apr_uri_t uri; /* Don't filter if we're in a subrequest or we aren't setup to proxy anything. */ master_uri = dav_svn__get_master_uri(r); if (r->main || !master_uri) { ap_remove_output_filter(f); return ap_pass_brigade(f->next, bb); } /* And don't filter if our search-n-replace would be a noop anyway (that is, if our root path matches that of the master server). */ apr_uri_parse(r->pool, master_uri, &uri); root_dir = dav_svn__get_root_dir(r); canonicalized_uri = svn_urlpath__canonicalize(uri.path, r->pool); if (strcmp(canonicalized_uri, root_dir) == 0) { ap_remove_output_filter(f); return ap_pass_brigade(f->next, bb); } /* ### FIXME: GET and PROPFIND requests that make it here must be ### referring to data inside commit transactions-in-progress. ### We've got to be careful not to munge the versioned data ### they return in the process of trying to do URI fix-ups. ### See issue #3445 for details. */ /* We are url encoding the current url and the master url as incoming(from master) request body has it encoded already. */ canonicalized_uri = svn_path_uri_encode(canonicalized_uri, r->pool); root_dir = svn_path_uri_encode(root_dir, r->pool); if (!f->ctx) { ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx)); ctx->remotepath = canonicalized_uri; ctx->remotepath_len = strlen(ctx->remotepath); ctx->localpath = root_dir; ctx->localpath_len = strlen(ctx->localpath); ctx->pattern = apr_strmatch_precompile(r->pool, ctx->remotepath, 1); ctx->pattern_len = ctx->remotepath_len; } bkt = APR_BRIGADE_FIRST(bb); while (bkt != APR_BRIGADE_SENTINEL(bb)) { const char *data, *match; apr_size_t len; /* read */ apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ); match = apr_strmatch(ctx->pattern, data, len); if (match) { apr_bucket *next_bucket; apr_bucket_split(bkt, match - data); next_bucket = APR_BUCKET_NEXT(bkt); apr_bucket_split(next_bucket, ctx->pattern_len); bkt = APR_BUCKET_NEXT(next_bucket); apr_bucket_delete(next_bucket); next_bucket = apr_bucket_pool_create(ctx->localpath, ctx->localpath_len, r->pool, bb->bucket_alloc); APR_BUCKET_INSERT_BEFORE(bkt, next_bucket); } else { bkt = APR_BUCKET_NEXT(bkt); } } return ap_pass_brigade(f->next, bb); }
svn_error_t * svn_repos_get_commit_editor5(const svn_delta_editor_t **editor, void **edit_baton, svn_repos_t *repos, svn_fs_txn_t *txn, const char *repos_url_decoded, const char *base_path, apr_hash_t *revprop_table, svn_commit_callback2_t commit_callback, void *commit_baton, svn_repos_authz_callback_t authz_callback, void *authz_baton, apr_pool_t *pool) { svn_delta_editor_t *e; apr_pool_t *subpool = svn_pool_create(pool); 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. */ if (authz_callback) { svn_boolean_t allowed; SVN_ERR(authz_callback(svn_authz_write, &allowed, NULL, NULL, authz_baton, pool)); if (!allowed) return svn_error_create(SVN_ERR_AUTHZ_UNWRITABLE, NULL, "Not authorized to open a commit editor."); } /* Allocate the structures. */ e = svn_delta_default_editor(pool); eb = apr_pcalloc(subpool, sizeof(*eb)); /* Set up the editor. */ e->open_root = open_root; e->delete_entry = delete_entry; e->add_directory = add_directory; e->open_directory = open_directory; e->change_dir_prop = change_dir_prop; e->add_file = add_file; e->open_file = open_file; e->close_file = close_file; e->apply_textdelta = apply_textdelta; e->change_file_prop = change_file_prop; e->close_edit = close_edit; e->abort_edit = abort_edit; /* Set up the edit baton. */ eb->pool = subpool; eb->revprop_table = svn_prop_hash_dup(revprop_table, subpool); eb->commit_callback = commit_callback; eb->commit_callback_baton = commit_baton; eb->authz_callback = authz_callback; eb->authz_baton = authz_baton; eb->base_path = svn_fspath__canonicalize(base_path, subpool); eb->repos = repos; 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); eb->txn = txn; eb->txn_owner = txn == NULL; *edit_baton = eb; *editor = e; shim_callbacks->fetch_props_func = fetch_props_func; shim_callbacks->fetch_kind_func = fetch_kind_func; shim_callbacks->fetch_base_func = fetch_base_func; shim_callbacks->fetch_baton = eb; SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton, repos_url, eb->base_path, shim_callbacks, pool, pool)); return SVN_NO_ERROR; }