You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2018/11/07 12:30:11 UTC
svn commit: r1846002 [22/44] - in /subversion/branches/ra-git: ./ build/
build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/generator/util/ build/win32/
contrib/client-side/ contrib/client-side/svn_load_dirs/ contr...
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/dav_svn.h Wed Nov 7 12:30:06 2018
@@ -359,10 +359,6 @@ svn_boolean_t dav_svn__get_list_parentpa
master server version (if provided via SVNMasterVersion). */
svn_boolean_t dav_svn__check_httpv2_support(request_rec *r);
-/* For the repository referred to by this request, should ephemeral
- txnprop support be advertised? */
-svn_boolean_t dav_svn__check_ephemeral_txnprops_support(request_rec *r);
-
/* SPECIAL URI
@@ -705,6 +701,7 @@ static const dav_report_elem dav_svn__re
{ SVN_XML_NAMESPACE, "get-deleted-rev-report" },
{ SVN_XML_NAMESPACE, SVN_DAV__MERGEINFO_REPORT },
{ SVN_XML_NAMESPACE, SVN_DAV__INHERITED_PROPS_REPORT },
+ { SVN_XML_NAMESPACE, "list-report" },
{ NULL, NULL },
};
@@ -757,6 +754,11 @@ dav_svn__get_inherited_props_report(cons
const apr_xml_doc *doc,
dav_svn__output *output);
+dav_error *
+dav_svn__list_report(const dav_resource *resource,
+ const apr_xml_doc *doc,
+ dav_svn__output *output);
+
/*** posts/ ***/
/* The various POST handlers, defined in posts/, and used by repos.c. */
@@ -1114,6 +1116,19 @@ dav_svn__get_youngest_rev(svn_revnum_t *
dav_svn_repos *repos,
apr_pool_t *scratch_pool);
+/* Return the liveprop-encoded form of AUTHOR, allocated in RESULT_POOL.
+ * If IS_SVN_CLIENT is set, assume that the data will be sent to a SVN
+ * client. This mainly sanitizes AUTHOR strings with control chars in
+ * them without converting them to escape sequences etc.
+ *
+ * Use SCRATCH_POOL for temporary allocations.
+ */
+const char *
+dav_svn__fuzzy_escape_author(const char *author,
+ svn_boolean_t is_svn_client,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/*** mirror.c ***/
/* Perform the fixup hook for the R request. */
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/liveprops.c Wed Nov 7 12:30:06 2018
@@ -423,43 +423,10 @@ insert_prop_internal(const dav_resource
if (last_author == NULL)
return DAV_PROP_INSERT_NOTDEF;
- if (svn_xml_is_xml_safe(last_author->data, last_author->len)
- || !resource->info->repos->is_svn_client)
- value = apr_xml_quote_string(scratch_pool, last_author->data, 1);
- else
- {
- /* We are talking to a Subversion client, which will (like any proper
- xml parser) error out if we produce control characters in XML.
-
- However Subversion clients process both the generic
- <creator-displayname /> as the custom element for svn:author.
-
- Let's skip outputting the invalid characters here to make the XML
- valid, so clients can see the custom element.
-
- Subversion Clients will then either use a slightly invalid
- author (unlikely) or more likely use the second result, which
- will be transferred with full escaping capabilities.
-
- We have tests in place to assert proper behavior over the RA layer.
- */
- apr_size_t i;
- svn_stringbuf_t *buf;
-
- buf = svn_stringbuf_create_from_string(last_author, scratch_pool);
-
- for (i = 0; i < buf->len; i++)
- {
- char c = buf->data[i];
-
- if (svn_ctype_iscntrl(c))
- {
- svn_stringbuf_remove(buf, i--, 1);
- }
- }
-
- value = apr_xml_quote_string(scratch_pool, buf->data, 1);
- }
+ /* We need to sanitize the LAST_AUTHOR. */
+ value = dav_svn__fuzzy_escape_author(last_author->data,
+ resource->info->repos->is_svn_client,
+ scratch_pool, scratch_pool);
break;
}
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/merge.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/merge.c Wed Nov 7 12:30:06 2018
@@ -171,7 +171,12 @@ do_resources(const dav_svn_repos *repos,
if (! apr_hash_get(sent, path, change->path.len))
{
svn_node_kind_t kind;
- SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool));
+
+ if (change->node_kind == svn_node_unknown)
+ SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool));
+ else
+ kind = change->node_kind;
+
SVN_ERR(send_response(repos, root, change->path.data,
kind == svn_node_dir,
output, bb, iterpool));
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/mod_dav_svn.c Wed Nov 7 12:30:06 2018
@@ -137,6 +137,15 @@ init(apr_pool_t *p, apr_pool_t *plog, ap
return HTTP_INTERNAL_SERVER_ERROR;
}
+ serr = svn_repos_authz_initialize(p);
+ if (serr)
+ {
+ ap_log_perror(APLOG_MARK, APLOG_ERR, serr->apr_err, p,
+ "mod_dav_svn: error calling svn_repos_authz_initialize: '%s'",
+ serr->message ? serr->message : "(no more info)");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
/* This returns void, so we can't check for error. */
conf = ap_get_module_config(s->module_config, &dav_svn_module);
svn_utf_initialize2(conf->use_utf8, p);
@@ -222,6 +231,9 @@ merge_server_config(apr_pool_t *p, void
newconf->compression_level = child->compression_level;
}
+ newconf->use_utf8 = INHERIT_VALUE(parent, child, use_utf8);
+ svn_utf_initialize2(newconf->use_utf8, p);
+
return newconf;
}
@@ -279,8 +291,8 @@ merge_dir_config(apr_pool_t *p, void *ba
if (parent->fs_path)
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
- "mod_dav_svn: nested Location '%s' hinders access to '%s' "
- "in SVNPath Location '%s'",
+ "mod_dav_svn: Location '%s' hinders access to '%s' "
+ "in parent SVNPath Location '%s'",
child->root_dir,
svn_urlpath__skip_ancestor(parent->root_dir, child->root_dir),
parent->root_dir);
@@ -914,21 +926,6 @@ dav_svn__check_httpv2_support(request_re
}
-svn_boolean_t
-dav_svn__check_ephemeral_txnprops_support(request_rec *r)
-{
- svn_version_t *version = dav_svn__get_master_version(r);
-
- /* We know this server supports ephemeral txnprops. But if we're
- proxying requests to a master server, we need to see if it
- supports them, too. */
- if (version && (! svn_version__at_least(version, 1, 8, 0)))
- return FALSE;
-
- return TRUE;
-}
-
-
/* FALSE if path authorization should be skipped.
* TRUE if either the bypass or the apache subrequest methods should be used.
*/
@@ -994,7 +991,9 @@ dav_svn__get_fulltext_cache_flag(request
dir_conf_t *conf;
conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
- return conf->fulltext_cache == CONF_FLAG_ON;
+
+ /* fulltext caching is enabled by default. */
+ return get_conf_flag(conf->fulltext_cache, TRUE);
}
@@ -1004,7 +1003,9 @@ dav_svn__get_revprop_cache_flag(request_
dir_conf_t *conf;
conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
- return conf->revprop_cache == CONF_FLAG_ON;
+
+ /* revprop caching is enabled by default. */
+ return get_conf_flag(conf->revprop_cache, TRUE);
}
svn_boolean_t
@@ -1013,8 +1014,9 @@ dav_svn__get_nodeprop_cache_flag(request
dir_conf_t *conf;
conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+
/* node properties caching is enabled by default. */
- return get_conf_flag(conf->nodeprop_cache, FALSE);
+ return get_conf_flag(conf->nodeprop_cache, TRUE);
}
svn_boolean_t
@@ -1023,7 +1025,9 @@ dav_svn__get_block_read_flag(request_rec
dir_conf_t *conf;
conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
- return conf->block_read == CONF_FLAG_ON;
+
+ /* the block-read feature is disabled by default. */
+ return get_conf_flag(conf->block_read, FALSE);
}
int
@@ -1254,7 +1258,7 @@ static int dav_svn__translate_name(reque
/* Leave a note to ourselves so that we know not to decline in the
* map_to_storage hook. */
- apr_table_setn(r->notes, NO_MAP_TO_STORAGE_NOTE, (const char*)1);
+ apr_table_setn(r->notes, NO_MAP_TO_STORAGE_NOTE, "1");
return OK;
}
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/file-revs.c Wed Nov 7 12:30:06 2018
@@ -214,7 +214,7 @@ file_rev_handler(void *baton,
frb->compression_level, pool);
*window_handler = delta_window_handler;
*window_baton = frb;
- /* Start the txdelta element wich will be terminated by the window
+ /* Start the txdelta element which will be terminated by the window
handler together with the file-rev element. */
SVN_ERR(dav_svn__brigade_puts(frb->bb, frb->output, "<S:txdelta>"));
}
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/mergeinfo.c Wed Nov 7 12:30:06 2018
@@ -42,6 +42,85 @@
#include "../dav_svn.h"
+/* Baton type to be used with mergeinfo_receiver. */
+typedef struct mergeinfo_receiver_baton_t
+{
+ /* Start path of the query; report paths relative to this one. */
+ const char *fs_path;
+
+ /* Allocate the BRIGADE contents here. */
+ apr_pool_t *resource_pool;
+
+ /* Attach the response to this brigade. */
+ apr_bucket_brigade *brigade;
+
+ /* Send the response out here. */
+ dav_svn__output *output;
+
+ /* Did we already send the opening sequence? */
+ svn_boolean_t starting_tuple_sent;
+} mergeinfo_receiver_baton_t;
+
+/* Utility method sending the start of the "get m/i" response once
+ over BATON. */
+static svn_error_t *
+send_mergeinfo_starting_sequence(mergeinfo_receiver_baton_t *baton,
+ apr_pool_t *scratch_pool)
+{
+ if (baton->starting_tuple_sent)
+ return SVN_NO_ERROR;
+
+ /* Ideally, dav_svn__brigade_printf() would set a flag in bb (or rather,
+ in r->sent_bodyct, see dav_method_report()), and ap_fflush()
+ would not set that flag unless it actually sent something. But
+ we are condemned to live in another universe, so we must keep
+ track ourselves of whether we've sent anything or not. See the
+ long comment after the 'cleanup' label for more details. */
+ SVN_ERR(dav_svn__brigade_puts(baton->brigade, baton->output,
+ DAV_XML_HEADER DEBUG_CR
+ "<S:" SVN_DAV__MERGEINFO_REPORT " "
+ "xmlns:S=\"" SVN_XML_NAMESPACE "\" "
+ "xmlns:D=\"DAV:\">" DEBUG_CR));
+ baton->starting_tuple_sent = TRUE;
+
+ return SVN_NO_ERROR;
+}
+
+/* Implements svn_repos_mergeinfo_receiver_t, sending the MERGEINFO
+ * out over the connection in the mergeinfo_receiver_baton_t * BATON. */
+static svn_error_t *
+mergeinfo_receiver(const char *path,
+ svn_mergeinfo_t mergeinfo,
+ void *baton,
+ apr_pool_t *scratch_pool)
+{
+ mergeinfo_receiver_baton_t *b = baton;
+ svn_string_t *mergeinfo_string;
+
+ /* Delay starting the response until we checked that the initial
+ request went through. We are at that point now b/c we've got
+ the first results in. */
+ SVN_ERR(send_mergeinfo_starting_sequence(b, scratch_pool));
+
+ /* Adjust the path info and send the m/i. */
+ path = svn_fspath__skip_ancestor(b->fs_path, path);
+ SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string, mergeinfo,
+ scratch_pool));
+
+ SVN_ERR(dav_svn__brigade_printf
+ (b->brigade, b->output,
+ "<S:" SVN_DAV__MERGEINFO_ITEM ">"
+ DEBUG_CR
+ "<S:" SVN_DAV__MERGEINFO_PATH ">%s</S:" SVN_DAV__MERGEINFO_PATH ">"
+ DEBUG_CR
+ "<S:" SVN_DAV__MERGEINFO_INFO ">%s</S:" SVN_DAV__MERGEINFO_INFO ">"
+ DEBUG_CR
+ "</S:" SVN_DAV__MERGEINFO_ITEM ">",
+ apr_xml_quote_string(b->resource_pool, path, 0),
+ apr_xml_quote_string(b->resource_pool, mergeinfo_string->data, 0)));
+
+ return SVN_NO_ERROR;
+}
dav_error *
dav_svn__get_mergeinfo_report(const dav_resource *resource,
@@ -51,13 +130,12 @@ dav_svn__get_mergeinfo_report(const dav_
svn_error_t *serr;
dav_error *derr = NULL;
apr_xml_elem *child;
- svn_mergeinfo_catalog_t catalog;
svn_boolean_t include_descendants = FALSE;
dav_svn__authz_read_baton arb;
const dav_svn_repos *repos = resource->info->repos;
int ns;
apr_bucket_brigade *bb;
- apr_hash_index_t *hi;
+ mergeinfo_receiver_baton_t receiver_baton;
/* These get determined from the request document. */
svn_revnum_t rev = SVN_INVALID_REVNUM;
@@ -127,20 +205,17 @@ dav_svn__get_mergeinfo_report(const dav_
bb = apr_brigade_create(resource->pool,
dav_svn__output_get_bucket_alloc(output));
- serr = svn_repos_fs_get_mergeinfo(&catalog, repos->repos, paths, rev,
- inherit, include_descendants,
- dav_svn__authz_read_func(&arb),
- &arb, resource->pool);
- if (serr)
- {
- derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, NULL,
- resource->pool);
- goto cleanup;
- }
-
- serr = svn_mergeinfo__remove_prefix_from_catalog(&catalog, catalog,
- resource->info->repos_path,
- resource->pool);
+ receiver_baton.brigade = bb;
+ receiver_baton.output = output;
+ receiver_baton.fs_path = resource->info->repos_path;
+ receiver_baton.resource_pool = resource->pool;
+ receiver_baton.starting_tuple_sent = FALSE;
+
+ serr = svn_repos_fs_get_mergeinfo2(repos->repos, paths, rev,
+ inherit, include_descendants,
+ dav_svn__authz_read_func(&arb), &arb,
+ mergeinfo_receiver, &receiver_baton,
+ resource->pool);
if (serr)
{
derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, NULL,
@@ -148,17 +223,9 @@ dav_svn__get_mergeinfo_report(const dav_
goto cleanup;
}
- /* Ideally, dav_svn__brigade_printf() would set a flag in bb (or rather,
- in r->sent_bodyct, see dav_method_report()), and ap_fflush()
- would not set that flag unless it actually sent something. But
- we are condemned to live in another universe, so we must keep
- track ourselves of whether we've sent anything or not. See the
- long comment after the 'cleanup' label for more details. */
- serr = dav_svn__brigade_puts(bb, output,
- DAV_XML_HEADER DEBUG_CR
- "<S:" SVN_DAV__MERGEINFO_REPORT " "
- "xmlns:S=\"" SVN_XML_NAMESPACE "\" "
- "xmlns:D=\"DAV:\">" DEBUG_CR);
+ /* We might not have sent anything
+ => ensure to begin the response in any case. */
+ serr = send_mergeinfo_starting_sequence(&receiver_baton, resource->pool);
if (serr)
{
derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, NULL,
@@ -166,46 +233,6 @@ dav_svn__get_mergeinfo_report(const dav_
goto cleanup;
}
- for (hi = apr_hash_first(resource->pool, catalog); hi;
- hi = apr_hash_next(hi))
- {
- const void *key;
- void *value;
- const char *path;
- svn_mergeinfo_t mergeinfo;
- svn_string_t *mergeinfo_string;
-
- apr_hash_this(hi, &key, NULL, &value);
- path = key;
- mergeinfo = value;
- serr = svn_mergeinfo_to_string(&mergeinfo_string, mergeinfo,
- resource->pool);
- if (serr)
- {
- derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
- "Error ending REPORT response.",
- resource->pool);
- goto cleanup;
- }
- serr = dav_svn__brigade_printf
- (bb, output,
- "<S:" SVN_DAV__MERGEINFO_ITEM ">"
- DEBUG_CR
- "<S:" SVN_DAV__MERGEINFO_PATH ">%s</S:" SVN_DAV__MERGEINFO_PATH ">"
- DEBUG_CR
- "<S:" SVN_DAV__MERGEINFO_INFO ">%s</S:" SVN_DAV__MERGEINFO_INFO ">"
- DEBUG_CR
- "</S:" SVN_DAV__MERGEINFO_ITEM ">",
- apr_xml_quote_string(resource->pool, path, 0),
- apr_xml_quote_string(resource->pool, mergeinfo_string->data, 0));
- if (serr)
- {
- derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
- "Error ending REPORT response.",
- resource->pool);
- goto cleanup;
- }
- }
if ((serr = dav_svn__brigade_puts(bb, output,
"</S:" SVN_DAV__MERGEINFO_REPORT ">"
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/reports/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/reports/replay.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/reports/replay.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/reports/replay.c Wed Nov 7 12:30:06 2018
@@ -48,6 +48,7 @@ typedef struct edit_baton_t {
svn_boolean_t started;
svn_boolean_t sending_textdelta;
int compression_level;
+ int svndiff_version;
} edit_baton_t;
@@ -326,7 +327,7 @@ apply_textdelta(void *file_baton,
dav_svn__make_base64_output_stream(eb->bb,
eb->output,
pool),
- 0,
+ eb->svndiff_version,
eb->compression_level,
pool);
@@ -369,6 +370,7 @@ make_editor(const svn_delta_editor_t **e
apr_bucket_brigade *bb,
dav_svn__output *output,
int compression_level,
+ int svndiff_version,
apr_pool_t *pool)
{
edit_baton_t *eb = apr_pcalloc(pool, sizeof(*eb));
@@ -379,6 +381,7 @@ make_editor(const svn_delta_editor_t **e
eb->started = FALSE;
eb->sending_textdelta = FALSE;
eb->compression_level = compression_level;
+ eb->svndiff_version = svndiff_version;
e->set_target_revision = set_target_revision;
e->open_root = open_root;
@@ -434,7 +437,7 @@ dav_svn__replay_report(const dav_resourc
URL, and BASE_DIR is embedded in the request body.
The old-school (and incorrect, see issue #4287 --
- http://subversion.tigris.org/issues/show_bug.cgi?id=4287) way was
+ https://issues.apache.org/jira/browse/SVN-4287) way was
to REPORT on the public URL of the BASE_DIR and embed the REV in
the report body.
*/
@@ -544,6 +547,7 @@ dav_svn__replay_report(const dav_resourc
make_editor(&editor, &edit_baton, bb, output,
dav_svn__get_compression_level(resource->info->r),
+ resource->info->svndiff_version,
resource->pool);
if ((err = svn_repos_replay2(root, base_dir, low_water_mark,
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/repos.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/repos.c Wed Nov 7 12:30:06 2018
@@ -1739,6 +1739,18 @@ static int sort_encoding_pref(const void
return (diff == 0 ? 0 : (diff > 0 ? -1 : 1));
}
+static int get_svndiff_version(const struct accept_rec *rec)
+{
+ if (strcmp(rec->name, "svndiff2") == 0)
+ return 2;
+ else if (strcmp(rec->name, "svndiff1") == 0)
+ return 1;
+ else if (strcmp(rec->name, "svndiff") == 0)
+ return 0;
+ else
+ return -1;
+}
+
/* Parse and handle any possible Accept-Encoding header that has been
sent as part of the request. */
static void
@@ -1752,6 +1764,9 @@ negotiate_encoding_prefs(request_rec *r,
necessary ones in this file. */
int i;
apr_array_header_t *encoding_prefs;
+ apr_array_header_t *svndiff_encodings;
+ svn_boolean_t accepts_svndiff2 = FALSE;
+
encoding_prefs = do_header_line(r->pool,
apr_table_get(r->headers_in,
"Accept-Encoding"));
@@ -1762,22 +1777,47 @@ negotiate_encoding_prefs(request_rec *r,
return;
}
- *svndiff_version = 0;
- svn_sort__array(encoding_prefs, sort_encoding_pref);
+ svndiff_encodings = apr_array_make(r->pool, 3, sizeof(struct accept_rec));
for (i = 0; i < encoding_prefs->nelts; i++)
{
- struct accept_rec rec = APR_ARRAY_IDX(encoding_prefs, i,
- struct accept_rec);
- if (strcmp(rec.name, "svndiff1") == 0)
- {
- *svndiff_version = 1;
- break;
- }
- else if (strcmp(rec.name, "svndiff") == 0)
- {
- *svndiff_version = 0;
- break;
- }
+ const struct accept_rec *rec = &APR_ARRAY_IDX(encoding_prefs, i,
+ struct accept_rec);
+ int version = get_svndiff_version(rec);
+
+ if (version > 0)
+ APR_ARRAY_PUSH(svndiff_encodings, struct accept_rec) = *rec;
+
+ if (version == 2)
+ accepts_svndiff2 = TRUE;
+ }
+
+ if (dav_svn__get_compression_level(r) == 0)
+ {
+ /* If the compression is disabled on the server, use the uncompressed
+ * svndiff0 format, which we assume is always supported. */
+ *svndiff_version = 0;
+ }
+ else if (accepts_svndiff2 && dav_svn__get_compression_level(r) == 1)
+ {
+ /* Enable svndiff2 if the client can read it, and if the server-side
+ * compression level is set to 1. Svndiff2 offers better speed and
+ * compression ratio comparable to svndiff1 with compression level 1,
+ * but not with other compression levels.
+ */
+ *svndiff_version = 2;
+ }
+ else if (svndiff_encodings->nelts > 0)
+ {
+ const struct accept_rec *rec;
+
+ /* Otherwise, use what the client prefers to see. */
+ svn_sort__array(svndiff_encodings, sort_encoding_pref);
+ rec = &APR_ARRAY_IDX(svndiff_encodings, 0, struct accept_rec);
+ *svndiff_version = get_svndiff_version(rec);
+ }
+ else
+ {
+ *svndiff_version = 0;
}
}
@@ -2821,6 +2861,13 @@ open_stream(const dav_resource *resource
"Resource body changes may only be made to "
"working resources (at this time).");
}
+ if (!resource->info->root.root)
+ {
+ return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED,
+ 0, 0,
+ "Resource body changes may only be made to "
+ "checked-out resources (at this time).");
+ }
}
/* ### TODO: Can we support range writes someday? */
@@ -2969,6 +3016,26 @@ close_stream(dav_stream *stream, int com
pool);
}
+ if (stream->wstream != NULL || stream->delta_handler != NULL)
+ {
+ request_rec *r = stream->res->info->r;
+ svn_checksum_t *checksum;
+
+ serr = svn_fs_file_checksum(&checksum, svn_checksum_md5,
+ stream->res->info->root.root,
+ stream->res->info->repos_path,
+ FALSE, pool);
+ if (serr)
+ return dav_svn__convert_err
+ (serr, HTTP_INTERNAL_SERVER_ERROR,
+ "mod_dav_svn close_stream: error getting file checksum",
+ pool);
+
+ if (checksum)
+ apr_table_set(r->headers_out, SVN_DAV_RESULT_FULLTEXT_MD5_HEADER,
+ svn_checksum_to_cstring(checksum, pool));
+ }
+
return NULL;
}
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/util.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/util.c Wed Nov 7 12:30:06 2018
@@ -37,6 +37,7 @@
#include "svn_fs.h"
#include "svn_dav.h"
#include "svn_base64.h"
+#include "svn_ctype.h"
#include "dav_svn.h"
#include "private/svn_fspath.h"
@@ -954,3 +955,48 @@ dav_svn__get_youngest_rev(svn_revnum_t *
*youngest_p = repos->youngest_rev;
return SVN_NO_ERROR;
}
+
+const char *
+dav_svn__fuzzy_escape_author(const char *author,
+ svn_boolean_t is_svn_client,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_size_t len = strlen(author);
+ if (is_svn_client && !svn_xml_is_xml_safe(author, len))
+ {
+ /* We are talking to a Subversion client, which will (like any proper
+ xml parser) error out if we produce control characters in XML.
+
+ However Subversion clients process both the generic
+ <creator-displayname /> as the custom element for svn:author.
+
+ Let's skip outputting the invalid characters here to make the XML
+ valid, so clients can see the custom element.
+
+ Subversion Clients will then either use a slightly invalid
+ author (unlikely) or more likely use the second result, which
+ will be transferred with full escaping capabilities.
+
+ We have tests in place to assert proper behavior over the RA layer.
+ */
+ apr_size_t i;
+ svn_stringbuf_t *buf;
+
+ buf = svn_stringbuf_ncreate(author, len, scratch_pool);
+
+ for (i = 0; i < buf->len; i++)
+ {
+ char c = buf->data[i];
+
+ if (svn_ctype_iscntrl(c))
+ {
+ svn_stringbuf_remove(buf, i--, 1);
+ }
+ }
+
+ author = buf->data;
+ }
+
+ return apr_xml_quote_string(result_pool, author, 1);
+}
Modified: subversion/branches/ra-git/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_dav_svn/version.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/ra-git/subversion/mod_dav_svn/version.c Wed Nov 7 12:30:06 2018
@@ -152,7 +152,7 @@ get_vsn_options(apr_pool_t *p, apr_text_
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INHERITED_PROPS);
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INLINE_PROPS);
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_REVERSE_FILE_REVS);
- apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_SVNDIFF1);
+ apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_LIST);
/* Mergeinfo is a special case: here we merely say that the server
* knows how to handle mergeinfo -- whether the repository does too
* is a separate matter.
@@ -176,11 +176,29 @@ get_option(const dav_resource *resource,
const apr_xml_elem *elem,
apr_text_header *option)
{
+ int i;
request_rec *r = resource->info->r;
const char *repos_root_uri =
dav_svn__build_uri(resource->info->repos, DAV_SVN__BUILD_URI_PUBLIC,
SVN_IGNORED_REVNUM, "", FALSE /* add_href */,
resource->pool);
+ svn_version_t *master_version = dav_svn__get_master_version(r);
+
+ /* These capabilities are used during commit and when configured as
+ a WebDAV slave (SVNMasterURI is set) their availablity should
+ depend on the master version (SVNMasterVersion is set) if it is
+ older than our own version. Also, although SVNDIFF1 is available
+ before 1.10 none of those earlier servers advertised it so for
+ consistency we don't advertise it for masters older than 1.10. */
+ struct capability_versions_t {
+ const char *capability_name;
+ svn_version_t min_version;
+ } capabilities[] = {
+ { SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS, { 1, 8, 0, ""} },
+ { SVN_DAV_NS_DAV_SVN_SVNDIFF1, { 1, 10, 0, ""} },
+ { SVN_DAV_NS_DAV_SVN_SVNDIFF2, { 1, 10, 0, ""} },
+ { SVN_DAV_NS_DAV_SVN_PUT_RESULT_CHECKSUM, { 1, 10, 0, ""} },
+ };
/* ### DAV:version-history-collection-set */
if (elem->ns != APR_XML_NS_DAV_ID
@@ -206,14 +224,6 @@ get_option(const dav_resource *resource,
apr_text_append(resource->pool, option,
"</D:activity-collection-set>");
- /* If we're allowed (by configuration) to do so, advertise support
- for ephemeral transaction properties. */
- if (dav_svn__check_ephemeral_txnprops_support(r))
- {
- apr_table_addn(r->headers_out, "DAV",
- SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS);
- }
-
if (resource->info->repos->fs)
{
svn_error_t *serr;
@@ -274,8 +284,6 @@ get_option(const dav_resource *resource,
DeltaV-free! If we're configured to advise this support, do so. */
if (resource->info->repos->v2_protocol)
{
- int i;
- svn_version_t *master_version = dav_svn__get_master_version(r);
dav_svn__bulk_upd_conf bulk_upd_conf = dav_svn__get_bulk_updates_flag(r);
/* The list of Subversion's custom POSTs and which versions of
@@ -346,6 +354,22 @@ get_option(const dav_resource *resource,
}
}
+ /* Report commit capabilites. */
+ for (i = 0; i < sizeof(capabilities)/sizeof(capabilities[0]); ++i)
+ {
+ /* If a master version is declared filter out unsupported
+ capabilities. */
+ if (master_version
+ && (!svn_version__at_least(master_version,
+ capabilities[i].min_version.major,
+ capabilities[i].min_version.minor,
+ capabilities[i].min_version.patch)))
+ continue;
+
+ apr_table_addn(r->headers_out, "DAV",
+ apr_pstrdup(r->pool, capabilities[i].capability_name));
+ }
+
return NULL;
}
@@ -1152,6 +1176,10 @@ deliver_report(request_rec *r,
{
return dav_svn__get_inherited_props_report(resource, doc, output);
}
+ else if (strcmp(doc->root->name, "list-report") == 0)
+ {
+ return dav_svn__list_report(resource, doc, output);
+ }
/* NOTE: if you add a report, don't forget to add it to the
* dav_svn__reports_list[] array.
*/