You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/09/15 21:32:38 UTC
svn commit: r997472 [31/41] - in /subversion/branches/py-tests-as-modules:
./ build/ build/ac-macros/ build/generator/ build/generator/templates/
contrib/server-side/ notes/ notes/tree-conflicts/ notes/wc-ng/
subversion/bindings/javahl/native/ subversi...
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/dav_svn.h?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/dav_svn.h Wed Sep 15 19:32:26 2010
@@ -37,6 +37,7 @@
#include "svn_path.h"
#include "svn_xml.h"
#include "private/svn_dav_protocol.h"
+#include "private/svn_skel.h"
#include "mod_authz_svn.h"
#ifdef __cplusplus
@@ -419,7 +420,7 @@ dav_svn__store_activity(const dav_svn_re
const char *txn_name);
-/* HTTP protocol v2: client does POST against 'me' resource. */
+/* POST request handler. (Used by HTTP protocol v2 clients only.) */
int dav_svn__method_post(request_rec *r);
@@ -640,6 +641,23 @@ dav_svn__get_deleted_rev_report(const da
const apr_xml_doc *doc,
ap_filter_t *output);
+
+/*** posts/ ***/
+
+/* The list of Subversion's custom POSTs. */
+/* ### should move these report names to a public header to share with
+ ### the client (and third parties). */
+static const char * dav_svn__posts_list[] = {
+ "create-txn",
+ NULL
+};
+
+/* The various POST handlers, defined in posts/, and used by repos.c. */
+dav_error *
+dav_svn__post_create_txn(const dav_resource *resource,
+ svn_skel_t *request_skel,
+ ap_filter_t *output);
+
/*** authz.c ***/
/* A baton needed by dav_svn__authz_read_func(). */
@@ -654,17 +672,32 @@ typedef struct
} dav_svn__authz_read_baton;
-/* Convert incoming RESOURCE and revision REV into a version-resource URI and
- perform a GET subrequest on it. This will invoke any authz modules loaded
- into apache. Return TRUE if the subrequest succeeds, FALSE otherwise.
+/* Return TRUE iff the current user (as determined by Apache's
+ authentication system) has permission to read PATH in REPOS at REV
+ (where an invalid REV means "HEAD"). This will invoke any authz
+ modules loaded into Apache unless this Subversion location has been
+ configured to bypass those in favor of a direct lookup in the
+ Subversion authz subsystem. Use POOL for any temporary allocation.
+*/
+svn_boolean_t
+dav_svn__allow_read(request_rec *r,
+ const dav_svn_repos *repos,
+ const char *path,
+ svn_revnum_t rev,
+ apr_pool_t *pool);
- If REV is SVN_INVALID_REVNUM, then we look at HEAD.
- Use POOL for any temporary allocation.
+/* Return TRUE iff the current user (as determined by Apache's
+ authentication system) has permission to read RESOURCE in REV
+ (where an invalid REV means "HEAD"). This will invoke any authz
+ modules loaded into Apache unless this Subversion location has been
+ configured to bypass those in favor of a direct lookup in the
+ Subversion authz subsystem. Use POOL for any temporary allocation.
*/
svn_boolean_t
-dav_svn__allow_read(const dav_resource *resource,
- svn_revnum_t rev,
- apr_pool_t *pool);
+dav_svn__allow_read_resource(const dav_resource *resource,
+ svn_revnum_t rev,
+ apr_pool_t *pool);
+
/* If authz is enabled in the specified BATON, return a read authorization
function. Otherwise, return NULL. */
@@ -890,6 +923,13 @@ dav_svn__final_flush_or_error(request_re
*/
int dav_svn__error_response_tag(request_rec *r, dav_error *err);
+
+/* Set *SKEL to a parsed skel read from the body of request R, and
+ * allocated in POOL.
+ */
+int dav_svn__parse_request_skel(svn_skel_t **skel, request_rec *r,
+ apr_pool_t *pool);
+
/*** mirror.c ***/
/* Perform the fixup hook for the R request. */
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/deadprops.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/deadprops.c Wed Sep 15 19:32:26 2010
@@ -389,7 +389,7 @@ db_output_value(dav_db *db,
const svn_string_t *enc_propval
= svn_base64_encode_string2(propval, TRUE, pool);
xml_safe = enc_propval->data;
- encoding = apr_pstrcat(pool, " V:encoding=\"base64\"", NULL);
+ encoding = " V:encoding=\"base64\"";
}
else
{
@@ -424,23 +424,15 @@ db_map_namespaces(dav_db *db,
static dav_error *
-db_store(dav_db *db,
- const dav_prop_name *name,
- const apr_xml_elem *elem,
- dav_namespace_map *mapping)
+decode_property_value(const svn_string_t **out_propval_p,
+ const svn_string_t *maybe_encoded_propval,
+ const apr_xml_elem *elem,
+ apr_pool_t *pool)
{
- const svn_string_t *propval;
- apr_pool_t *pool = db->p;
apr_xml_attr *attr = elem->attr;
- /* SVN sends property values as a big blob of bytes. Thus, there should be
- no child elements of the property-name element. That also means that
- the entire contents of the blob is located in elem->first_cdata. The
- dav_xml_get_cdata() will figure it all out for us, but (normally) it
- should be awfully fast and not need to copy any data. */
-
- propval = svn_string_create
- (dav_xml_get_cdata(elem, pool, 0 /* strip_white */), pool);
+ /* Default: no "encoding" attribute. */
+ *out_propval_p = maybe_encoded_propval;
/* Check for special encodings of the property value. */
while (attr)
@@ -451,7 +443,7 @@ db_store(dav_db *db,
/* Handle known encodings here. */
if (enc_type && (strcmp(enc_type, "base64") == 0))
- propval = svn_base64_decode_string(propval, pool);
+ *out_propval_p = svn_base64_decode_string(maybe_encoded_propval, pool);
else
return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR, 0,
"Unknown property encoding");
@@ -461,6 +453,32 @@ db_store(dav_db *db,
attr = attr->next;
}
+ return NULL;
+}
+
+static dav_error *
+db_store(dav_db *db,
+ const dav_prop_name *name,
+ const apr_xml_elem *elem,
+ dav_namespace_map *mapping)
+{
+ const svn_string_t *propval;
+ apr_pool_t *pool = db->p;
+ dav_error *derr;
+
+ /* SVN sends property values as a big blob of bytes. Thus, there should be
+ no child elements of the property-name element. That also means that
+ the entire contents of the blob is located in elem->first_cdata. The
+ dav_xml_get_cdata() will figure it all out for us, but (normally) it
+ should be awfully fast and not need to copy any data. */
+
+ propval = svn_string_create
+ (dav_xml_get_cdata(elem, pool, 0 /* strip_white */), pool);
+
+ derr = decode_property_value(&propval, propval, elem, pool);
+ if (derr)
+ return derr;
+
return save_value(db, name, propval);
}
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/liveprops.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/liveprops.c Wed Sep 15 19:32:26 2010
@@ -144,7 +144,7 @@ get_path_revprop(svn_string_t **propval,
{
*propval = NULL;
- if (! dav_svn__allow_read(resource, committed_rev, pool))
+ if (! dav_svn__allow_read_resource(resource, committed_rev, pool))
return SVN_NO_ERROR;
/* Get the property of the created revision. The authz is already
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/lock.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/lock.c Wed Sep 15 19:32:26 2010
@@ -458,7 +458,8 @@ get_locks(dav_lockdb *lockdb,
/* If the resource's fs path is unreadable, we don't want to say
anything about locks attached to it.*/
- if (! dav_svn__allow_read(resource, SVN_INVALID_REVNUM, resource->pool))
+ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
+ resource->pool))
return dav_new_error(resource->pool, HTTP_FORBIDDEN,
DAV_ERR_LOCK_SAVE_LOCK,
"Path is not accessible.");
@@ -518,7 +519,8 @@ find_lock(dav_lockdb *lockdb,
/* If the resource's fs path is unreadable, we don't want to say
anything about locks attached to it.*/
- if (! dav_svn__allow_read(resource, SVN_INVALID_REVNUM, resource->pool))
+ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
+ resource->pool))
return dav_new_error(resource->pool, HTTP_FORBIDDEN,
DAV_ERR_LOCK_SAVE_LOCK,
"Path is not accessible.");
@@ -596,7 +598,8 @@ has_locks(dav_lockdb *lockdb, const dav_
/* If the resource's fs path is unreadable, we don't want to say
anything about locks attached to it.*/
- if (! dav_svn__allow_read(resource, SVN_INVALID_REVNUM, resource->pool))
+ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
+ resource->pool))
return dav_new_error(resource->pool, HTTP_FORBIDDEN,
DAV_ERR_LOCK_SAVE_LOCK,
"Path is not accessible.");
@@ -639,7 +642,8 @@ append_locks(dav_lockdb *lockdb,
/* If the resource's fs path is unreadable, we don't allow a lock to
be created on it. */
- if (! dav_svn__allow_read(resource, SVN_INVALID_REVNUM, resource->pool))
+ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
+ resource->pool))
return dav_new_error(resource->pool, HTTP_FORBIDDEN,
DAV_ERR_LOCK_SAVE_LOCK,
"Path is not accessible.");
@@ -806,7 +810,8 @@ remove_lock(dav_lockdb *lockdb,
/* If the resource's fs path is unreadable, we don't allow a lock to
be removed from it. */
- if (! dav_svn__allow_read(resource, SVN_INVALID_REVNUM, resource->pool))
+ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
+ resource->pool))
return dav_new_error(resource->pool, HTTP_FORBIDDEN,
DAV_ERR_LOCK_SAVE_LOCK,
"Path is not accessible.");
@@ -891,7 +896,8 @@ refresh_locks(dav_lockdb *lockdb,
/* If the resource's fs path is unreadable, we don't want to say
anything about locks attached to it.*/
- if (! dav_svn__allow_read(resource, SVN_INVALID_REVNUM, resource->pool))
+ if (! dav_svn__allow_read_resource(resource, SVN_INVALID_REVNUM,
+ resource->pool))
return dav_new_error(resource->pool, HTTP_FORBIDDEN,
DAV_ERR_LOCK_SAVE_LOCK,
"Path is not accessible.");
Propchange: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/posts/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Sep 15 19:32:26 2010
@@ -0,0 +1 @@
+.libs
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/get-locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/get-locks.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/get-locks.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/get-locks.c Wed Sep 15 19:32:26 2010
@@ -186,6 +186,8 @@ dav_svn__get_locks_report(const dav_reso
apr_status_t apr_err;
apr_hash_t *locks;
dav_svn__authz_read_baton arb;
+ svn_depth_t depth = svn_depth_unknown;
+ apr_xml_attr *this_attr;
/* The request URI should be a public one representing an fs path. */
if ((! resource->info->repos_path)
@@ -197,12 +199,33 @@ dav_svn__get_locks_report(const dav_reso
arb.r = resource->info->r;
arb.repos = resource->info->repos;
+ /* See if the client provided additional information for this request. */
+ for (this_attr = doc->root->attr; this_attr; this_attr = this_attr->next)
+ {
+ if (strcmp(this_attr->name, "depth") == 0)
+ {
+ depth = svn_depth_from_word(this_attr->value);
+ if ((depth != svn_depth_empty) &&
+ (depth != svn_depth_files) &&
+ (depth != svn_depth_immediates) &&
+ (depth != svn_depth_infinity))
+ return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "Invalid 'depth' specified in "
+ "get-locks-report request.");
+ continue;
+ }
+ }
+
+ /* For compatibility, our default depth is infinity. */
+ if (depth == svn_depth_unknown)
+ depth = svn_depth_infinity;
+
/* Fetch the locks, but allow authz_read checks to happen on each. */
- if ((err = svn_repos_fs_get_locks(&locks,
- resource->info->repos->repos,
- resource->info->repos_path,
- dav_svn__authz_read_func(&arb), &arb,
- resource->pool)) != SVN_NO_ERROR)
+ if ((err = svn_repos_fs_get_locks2(&locks,
+ resource->info->repos->repos,
+ resource->info->repos_path, depth,
+ dav_svn__authz_read_func(&arb), &arb,
+ resource->pool)) != SVN_NO_ERROR)
return dav_svn__convert_err(err, HTTP_INTERNAL_SERVER_ERROR,
err->message, resource->pool);
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/log.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/log.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/log.c Wed Sep 15 19:32:26 2010
@@ -311,7 +311,17 @@ dav_svn__log_report(const dav_resource *
else if (strcmp(child->name, "end-revision") == 0)
end = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
else if (strcmp(child->name, "limit") == 0)
- limit = atoi(dav_xml_get_cdata(child, resource->pool, 1));
+ {
+ serr = svn_cstring_atoi(&limit,
+ dav_xml_get_cdata(child, resource->pool, 1));
+ if (serr)
+ {
+ derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
+ "Malformed CDATA in element "
+ "\"limit\"", resource->pool);
+ goto cleanup;
+ }
+ }
else if (strcmp(child->name, "discover-changed-paths") == 0)
discover_changed_paths = TRUE; /* presence indicates positivity */
else if (strcmp(child->name, "strict-node-history") == 0)
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/replay.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/replay.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/replay.c Wed Sep 15 19:32:26 2010
@@ -466,10 +466,18 @@ dav_svn__replay_report(const dav_resourc
}
else if (strcmp(child->name, "send-deltas") == 0)
{
+ apr_int64_t parsed_val;
+
cdata = dav_xml_get_cdata(child, resource->pool, 1);
if (! cdata)
return malformed_element_error("send-deltas", resource->pool);
- send_deltas = atoi(cdata);
+ err = svn_cstring_strtoi64(&parsed_val, cdata, 0, 1, 10);
+ if (err)
+ {
+ svn_error_clear(err);
+ return malformed_element_error("send-deltas", resource->pool);
+ }
+ send_deltas = parsed_val ? TRUE : FALSE;
}
}
}
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/update.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/reports/update.c Wed Sep 15 19:32:26 2010
@@ -782,6 +782,8 @@ struct window_handler_baton
svn_boolean_t seen_first_window; /* False until first window seen. */
update_ctx_t *uc;
+ const char *base_checksum; /* For transfer as part of the S:txdelta element */
+
/* The _real_ window handler and baton. */
svn_txdelta_window_handler_t handler;
void *handler_baton;
@@ -797,7 +799,14 @@ window_handler(svn_txdelta_window_t *win
if (! wb->seen_first_window)
{
wb->seen_first_window = TRUE;
- SVN_ERR(dav_svn__brigade_puts(wb->uc->bb, wb->uc->output, "<S:txdelta>"));
+
+ if (!wb->base_checksum)
+ SVN_ERR(dav_svn__brigade_puts(wb->uc->bb, wb->uc->output,
+ "<S:txdelta>"));
+ else
+ SVN_ERR(dav_svn__brigade_printf(wb->uc->bb, wb->uc->output,
+ "<S:txdelta base-checksum=\"%s\">",
+ wb->base_checksum));
}
SVN_ERR(wb->handler(window, wb->handler_baton));
@@ -850,6 +859,7 @@ upd_apply_textdelta(void *file_baton,
wb = apr_palloc(file->pool, sizeof(*wb));
wb->seen_first_window = FALSE;
wb->uc = file->uc;
+ wb->base_checksum = file->base_checksum;
base64_stream = dav_svn__make_base64_output_stream(wb->uc->bb,
wb->uc->output,
file->pool);
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/repos.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/repos.c Wed Sep 15 19:32:26 2010
@@ -44,6 +44,7 @@
#include "svn_sorts.h"
#include "svn_version.h"
#include "svn_props.h"
+#include "svn_ctype.h"
#include "mod_dav_svn.h"
#include "svn_ra.h" /* for SVN_RA_CAPABILITY_* */
#include "svn_dirent_uri.h"
@@ -1519,7 +1520,7 @@ static const char *get_entry(apr_pool_t
/* Look for 'var = value' --- and make sure the var is in lcase. */
- for (cp = parm; (*cp && !apr_isspace(*cp) && *cp != '='); ++cp)
+ for (cp = parm; (*cp && !svn_ctype_isspace(*cp) && *cp != '='); ++cp)
{
*cp = apr_tolower(*cp);
}
@@ -1530,7 +1531,7 @@ static const char *get_entry(apr_pool_t
}
*cp++ = '\0'; /* Delimit var */
- while (*cp && (apr_isspace(*cp) || *cp == '='))
+ while (*cp && (svn_ctype_isspace(*cp) || *cp == '='))
{
++cp;
}
@@ -1544,7 +1545,7 @@ static const char *get_entry(apr_pool_t
}
else
{
- for (end = cp; (*end && !apr_isspace(*end)); end++);
+ for (end = cp; (*end && !svn_ctype_isspace(*end)); end++);
}
if (*end)
{
@@ -2293,19 +2294,17 @@ static const char *
get_parent_path(const char *path, apr_pool_t *pool)
{
apr_size_t len;
- const char *parentpath, *base_name;
char *tmp = apr_pstrdup(pool, path);
len = strlen(tmp);
if (len > 0)
{
- /* Remove any trailing slash; else svn_uri_split() asserts. */
+ /* Remove any trailing slash; else svn_uri_dirname() asserts. */
if (tmp[len-1] == '/')
tmp[len-1] = '\0';
- svn_uri_split(tmp, &parentpath, &base_name, pool);
- return parentpath;
+ return svn_uri_dirname(tmp, pool);
}
return path;
@@ -3121,6 +3120,7 @@ deliver(const dav_resource *resource, ap
apr_hash_t *entries;
apr_pool_t *entry_pool;
apr_array_header_t *sorted;
+ svn_revnum_t dir_rev = SVN_INVALID_REVNUM;
int i;
/* XML schema for the directory index if xslt_uri is set:
@@ -3165,7 +3165,8 @@ deliver(const dav_resource *resource, ap
const char *fs_parent_path =
dav_svn__get_fs_parent_path(resource->info->r);
- serr = svn_io_get_dirents2(&dirents, fs_parent_path, resource->pool);
+ serr = svn_io_get_dirents3(&dirents, fs_parent_path, TRUE,
+ resource->pool, resource->pool);
if (serr != NULL)
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"couldn't fetch dirents of SVNParentPath",
@@ -3197,6 +3198,7 @@ deliver(const dav_resource *resource, ap
}
else
{
+ dir_rev = svn_fs_revision_root_revision(resource->info->root.root);
serr = svn_fs_dir_entries(&entries, resource->info->root.root,
resource->info->repos_path, resource->pool);
if (serr != NULL)
@@ -3305,9 +3307,31 @@ deliver(const dav_resource *resource, ap
const char *name = item->key;
const char *href = name;
svn_boolean_t is_dir = (entry->kind == svn_node_dir);
+ const char *repos_relpath = NULL;
svn_pool_clear(entry_pool);
+ /* DIR_REV is set to a valid revision if we're looking at
+ the entries of a versioned directory. Otherwise, we're
+ looking at a parent-path listing. */
+ if (SVN_IS_VALID_REVNUM(dir_rev))
+ {
+ repos_relpath = svn_path_join(resource->info->repos_path,
+ name, entry_pool);
+ if (! dav_svn__allow_read(resource->info->r,
+ resource->info->repos,
+ repos_relpath,
+ dir_rev,
+ entry_pool))
+ continue;
+ }
+ else
+ {
+ /* ### TODO: We could test for readability of the root
+ directory of each repository and hide those that
+ the user can't see. */
+ }
+
/* append a trailing slash onto the name for directories. we NEED
this for the href portion so that the relative reference will
descend properly. for the visible portion, it is just nice. */
@@ -3391,7 +3415,8 @@ deliver(const dav_resource *resource, ap
*/
ap_fputs(output, bb,
" </ul>\n <hr noshade><em>Powered by "
- "<a href=\"http://subversion.apache.org/\">Subversion"
+ "<a href=\"http://subversion.apache.org/\">"
+ "Apache Subversion"
"</a> version " SVN_VERSION "."
"</em>\n</body></html>");
}
@@ -3932,6 +3957,7 @@ do_walk(walker_ctx_t *ctx, int depth)
apr_size_t uri_len;
apr_size_t repos_len;
apr_hash_t *children;
+ apr_pool_t *iterpool;
/* Clear the temporary pool. */
svn_pool_clear(ctx->info.pool);
@@ -4007,6 +4033,7 @@ do_walk(walker_ctx_t *ctx, int depth)
params->pool);
/* iterate over the children in this collection */
+ iterpool = svn_pool_create(params->pool);
for (hi = apr_hash_first(params->pool, children); hi; hi = apr_hash_next(hi))
{
const void *key;
@@ -4014,6 +4041,8 @@ do_walk(walker_ctx_t *ctx, int depth)
void *val;
svn_fs_dirent_t *dirent;
+ svn_pool_clear(iterpool);
+
/* fetch one of the children */
apr_hash_this(hi, &key, &klen, &val);
dirent = val;
@@ -4021,7 +4050,16 @@ do_walk(walker_ctx_t *ctx, int depth)
/* authorize access to this resource, if applicable */
if (params->walk_type & DAV_WALKTYPE_AUTH)
{
- /* ### how/what to do? */
+ const char *repos_relpath =
+ apr_pstrcat(iterpool,
+ apr_pstrmemdup(iterpool,
+ ctx->repos_path->data,
+ ctx->repos_path->len),
+ key, NULL);
+ if (! dav_svn__allow_read(ctx->info.r, ctx->info.repos,
+ repos_relpath, ctx->info.root.rev,
+ iterpool))
+ continue;
}
/* append this child to our buffers */
@@ -4062,6 +4100,9 @@ do_walk(walker_ctx_t *ctx, int depth)
ctx->uri->len = uri_len;
ctx->repos_path->len = repos_len;
}
+
+ svn_pool_destroy(iterpool);
+
return NULL;
}
@@ -4263,58 +4304,73 @@ dav_svn__create_version_resource(dav_res
}
-/* POST handler for HTTP protocol v2.
-
- Currently we allow POSTs only against the "me resource", which may
- in the future act as a dispatcher of sorts for handling potentially
- many different kinds of operations as specified by the body of the
- POST request itself.
-
- ### TODO: Define what the format of those POST bodies might be. If
- ### XML, we have access to Apache's streamy XML parsing code, but
- ### ... it's XML. Meh. If skels, we get skels! But we need to
- ### write our own streamy skel parsing routine around a brigade
- ### read loop. Ewww...
- ###
- ### Today we only support transaction creation requests, but we
- ### could conceivable support the likes of a multi-path lock
- ### and/or unlock request, or some other thing for which stock
- ### WebDAV doesn't work or doesn't work well enough.
- ###
- ### Fortunately, today we don't use the POST body at all, and we'll
- ### be able to get away with not defining the body format in the
- ### future thanks to the following:
-
- As a special consideration, an empty POST body is interpreted as a
- simple request to create a new commit transaction based on the HEAD
- revision. The new transaction name will be returned via a custom
- response header SVN_DAV_TXN_NAME_HEADER.
-*/
+
+static dav_error *
+handle_post_request(request_rec *r,
+ dav_resource *resource,
+ ap_filter_t *output)
+{
+ svn_skel_t *request_skel;
+ int status;
+ apr_pool_t *pool = resource->pool;
+
+ /* Make sure our skel-based request parses okay, has an initial atom
+ that identifies what kind of action is expected, and that that
+ action is something we understand. */
+ status = dav_svn__parse_request_skel(&request_skel, r, pool);
+
+ if (status != OK)
+ return dav_new_error(pool, status, 0,
+ "Error parsing skel POST request body.");
+
+ if (svn_skel__list_length(request_skel) < 1)
+ return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
+ "Unable to identify skel POST request flavor.");
+
+ if (svn_skel__matches_atom(request_skel->children, "create-txn"))
+ {
+ return dav_svn__post_create_txn(resource, request_skel, output);
+ }
+ else
+ {
+ return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
+ "Unsupported skel POST request flavor.");
+ }
+ /* NOTREACHED */
+}
+
int dav_svn__method_post(request_rec *r)
{
dav_resource *resource;
dav_error *derr;
- const char *txn_name;
+ const char *content_type;
+ /* We only allow POSTs against the "me resource" right now. */
derr = get_resource(r, dav_svn__get_root_dir(r),
"ignored", 0, &resource);
if (derr != NULL)
return derr->status;
-
if (resource->info->restype != DAV_SVN_RESTYPE_ME)
return HTTP_BAD_REQUEST;
- /* Create a Subversion repository transaction based on HEAD. */
- derr = dav_svn__create_txn(resource->info->repos, &txn_name, resource->pool);
+ /* Pass skel-type POST request handling off to a dispatcher; any
+ other type of request is considered bogus. */
+ content_type = apr_table_get(r->headers_in, "content-type");
+ if (content_type && (strcmp(content_type, SVN_SKEL_MIME_TYPE) == 0))
+ {
+ derr = handle_post_request(r, resource, r->output_filters);
+ }
+ else
+ {
+ derr = dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+ "Unsupported POST request type.");
+ }
+
+ /* If something went wrong above, we'll generate a response back to
+ the client with (hopefully) some helpful information. */
if (derr)
return dav_svn__error_response_tag(r, derr);
-
- /* Build a "201 Created" response with header that tells the client
- our new transaction's name. */
- apr_table_set(resource->info->r->headers_out, SVN_DAV_TXN_NAME_HEADER,
- txn_name);
- r->status = HTTP_CREATED;
-
+
return OK;
}
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/util.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/util.c Wed Sep 15 19:32:26 2010
@@ -28,6 +28,7 @@
#include <mod_dav.h>
#include <http_protocol.h>
+#include <http_core.h>
#include "svn_error.h"
#include "svn_fs.h"
@@ -611,3 +612,140 @@ dav_svn__error_response_tag(request_rec
*/
return DONE;
}
+
+
+/* Set *REQUEST_STR to a string containing the contents of the body of
+ request R, allocated from POOL.
+
+ NOTE: This was shamelessly stolen and modified from Apache's
+ ap_xml_parse_input(). */
+static int
+request_body_to_string(svn_string_t **request_str,
+ request_rec *r,
+ apr_pool_t *pool)
+{
+ apr_bucket_brigade *brigade;
+ int seen_eos;
+ apr_status_t status;
+ apr_off_t total_read = 0;
+ apr_off_t limit_req_body = ap_get_limit_req_body(r);
+ int result = HTTP_BAD_REQUEST;
+ const char *content_length_str;
+ char *endp;
+ apr_off_t content_length;
+ svn_stringbuf_t *buf;
+
+ *request_str = NULL;
+
+ content_length_str = apr_table_get(r->headers_in, "Content-Length");
+ if (content_length_str)
+ {
+ if (apr_strtoff(&content_length, content_length_str, &endp, 10)
+ || endp == content_length_str || *endp || content_length < 0)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid Content-Length");
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
+ }
+ }
+ else
+ content_length = 0;
+
+ if (limit_req_body && (limit_req_body < content_length))
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Requested content-length of %" APR_OFF_T_FMT " is larger "
+ "than the configured limit of %" APR_OFF_T_FMT,
+ content_length, limit_req_body);
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
+ }
+
+ if (content_length)
+ {
+ buf = svn_stringbuf_create_ensure(content_length, pool);
+ }
+ else
+ {
+ buf = svn_stringbuf_create("", pool);
+ }
+
+ brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ seen_eos = 0;
+ total_read = 0;
+
+ do
+ {
+ apr_bucket *bucket;
+
+ status = ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES,
+ APR_BLOCK_READ, 2048);
+ if (status != APR_SUCCESS)
+ goto cleanup;
+
+ for (bucket = APR_BRIGADE_FIRST(brigade);
+ bucket != APR_BRIGADE_SENTINEL(brigade);
+ bucket = APR_BUCKET_NEXT(bucket))
+ {
+ const char *data;
+ apr_size_t len;
+
+ if (APR_BUCKET_IS_EOS(bucket))
+ {
+ seen_eos = 1;
+ break;
+ }
+
+ if (APR_BUCKET_IS_METADATA(bucket))
+ continue;
+
+ status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+ if (status != APR_SUCCESS)
+ goto cleanup;
+
+ total_read += len;
+ if (limit_req_body && total_read > limit_req_body)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Request body is larger than the configured "
+ "limit of %lu", (unsigned long)limit_req_body);
+ result = HTTP_REQUEST_ENTITY_TOO_LARGE;
+ goto cleanup;
+ }
+
+ svn_stringbuf_appendbytes(buf, data, len);
+ }
+
+ apr_brigade_cleanup(brigade);
+ }
+ while (!seen_eos);
+
+ apr_brigade_destroy(brigade);
+
+ /* Make an svn_string_t from our svn_stringbuf_t. */
+ *request_str = svn_string_create("", pool);
+ (*request_str)->data = buf->data;
+ (*request_str)->len = buf->len;
+ return OK;
+
+ cleanup:
+ apr_brigade_destroy(brigade);
+
+ /* Apache will supply a default error, plus the error log above. */
+ return result;
+}
+
+int
+dav_svn__parse_request_skel(svn_skel_t **skel,
+ request_rec *r,
+ apr_pool_t *pool)
+{
+ svn_string_t *skel_str;
+ int status;
+
+ *skel = NULL;
+ status = request_body_to_string(&skel_str, r, pool);
+ if (status != OK)
+ return OK;
+
+ *skel = svn_skel__parse(skel_str->data, skel_str->len, pool);
+ return OK;
+}
Modified: subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/version.c?rev=997472&r1=997471&r2=997472&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/mod_dav_svn/version.c Wed Sep 15 19:32:26 2010
@@ -41,6 +41,7 @@
#include "private/svn_log.h"
#include "dav_svn.h"
+#include "mod_dav_svn.h"
svn_error_t *
@@ -1014,6 +1015,22 @@ deliver_report(request_rec *r,
if (doc->root->ns == ns)
{
+ const char *cleaned_uri, *relative_path, *repos_path;
+ int trailing_slash;
+ /* During SVNPathAuthz short_circuit
+ * resource->info->repos->repo_name becomes NULL.*/
+ if (resource->info->repos->repo_name == NULL)
+ {
+ dav_error *err;
+ err = dav_svn_split_uri(r, r->uri, dav_svn__get_root_dir(r),
+ &cleaned_uri, &trailing_slash,
+ &(resource->info->repos->repo_name),
+ &relative_path, &repos_path);
+ if (err)
+ {
+ return err;
+ }
+ }
/* ### note that these report names should have symbols... */
if (strcmp(doc->root->name, "update-report") == 0)