You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2010/07/30 21:04:17 UTC
svn commit: r980924 - in /subversion/trunk/subversion/libsvn_ra_serf:
blame.c commit.c getlocations.c getlocationsegments.c mergeinfo.c options.c
property.c ra_serf.h update.c util.c
Author: cmpilato
Date: Fri Jul 30 19:04:17 2010
New Revision: 980924
URL: http://svn.apache.org/viewvc?rev=980924&view=rev
Log:
Finish issue #3685: ra_serf fails to alert users of relocated
repositories (301/302 handling).
* subversion/libsvn_ra_serf/ra_serf.h
(svn_ra_serf__simple_request_context_t): Add 'location' member.
(struct svn_ra_serf__xml_parser_t): Add 'location' member.
(svn_ra_serf__error_on_status): Add 'location' parameter.
(svn_ra_serf__response_get_location): New function.
* subversion/libsvn_ra_serf/util.c
(svn_ra_serf__response_get_location): New function.
(svn_ra_serf__handle_status_only, svn_ra_serf__handle_multistatus_only,
svn_ra_serf__handle_xml_parser): Use svn_ra_serf__response_get_location()
to populate the context's
'location' member.
(svn_ra_serf__error_on_status): Add 'location' parameter, and use it
(instead of the 'path' parameter) to report redirect locations.
* subversion/libsvn_ra_serf/blame.c
(svn_ra_serf__get_file_revs): Update call to svn_ra_serf__error_on_status().
* subversion/libsvn_ra_serf/commit.c
(return_response_err): Update call to svn_ra_serf__error_on_status(),
and give the code some room to breathe.
* subversion/libsvn_ra_serf/getlocations.c
(svn_ra_serf__get_locations): Update call to svn_ra_serf__error_on_status().
* subversion/libsvn_ra_serf/getlocationsegments.c
(svn_ra_serf__get_location_segments): Update call to
svn_ra_serf__error_on_status(). While here, fix an error leak, too.
* subversion/libsvn_ra_serf/mergeinfo.c
(svn_ra_serf__get_mergeinfo): Update call to svn_ra_serf__error_on_status().
* subversion/libsvn_ra_serf/options.c
(svn_ra_serf__exchange_capabilities): Use svn_ra_serf__error_on_status() to
notice common errors, including the 301/302 redirect variety.
* subversion/libsvn_ra_serf/property.c
(svn_ra_serf__wait_for_props): Update call to svn_ra_serf__error_on_status().
* subversion/libsvn_ra_serf/update.c
(handle_stream): Use svn_ra_serf__response_get_location(), and
update call to svn_ra_serf__error_on_status().
Modified:
subversion/trunk/subversion/libsvn_ra_serf/blame.c
subversion/trunk/subversion/libsvn_ra_serf/commit.c
subversion/trunk/subversion/libsvn_ra_serf/getlocations.c
subversion/trunk/subversion/libsvn_ra_serf/getlocationsegments.c
subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c
subversion/trunk/subversion/libsvn_ra_serf/options.c
subversion/trunk/subversion/libsvn_ra_serf/property.c
subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
subversion/trunk/subversion/libsvn_ra_serf/update.c
subversion/trunk/subversion/libsvn_ra_serf/util.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/blame.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/blame.c Fri Jul 30 19:04:17 2010
@@ -483,8 +483,10 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
err = svn_ra_serf__context_run_wait(&blame_ctx->done, session, pool);
err = svn_error_compose_create(
- svn_ra_serf__error_on_status(status_code, handler->path),
- err);
+ svn_ra_serf__error_on_status(status_code,
+ handler->path,
+ parser_ctx->location),
+ err);
return svn_error_return(err);
}
Modified: subversion/trunk/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/commit.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/commit.c Fri Jul 30 19:04:17 2010
@@ -220,16 +220,22 @@ static svn_error_t *
return_response_err(svn_ra_serf__handler_t *handler,
svn_ra_serf__simple_request_context_t *ctx)
{
+ svn_error_t *err;
+
+ /* Ye Olde Fallback Error */
+ err = svn_error_compose_create(
+ ctx->server_error.error,
+ svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+ "%s of '%s': %d %s",
+ handler->method, handler->path,
+ ctx->status, ctx->reason));
+
/* Try to return one of the standard errors for 301, 404, etc.,
then look for an error embedded in the response. */
- return svn_error_compose_create(
- svn_ra_serf__error_on_status(ctx->status, handler->path),
- svn_error_compose_create(
- ctx->server_error.error,
- svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
- "%s of '%s': %d %s",
- handler->method, handler->path,
- ctx->status, ctx->reason)));
+ return svn_error_compose_create(svn_ra_serf__error_on_status(ctx->status,
+ handler->path,
+ ctx->location),
+ err);
}
static serf_bucket_t *
Modified: subversion/trunk/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/getlocations.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/getlocations.c Fri Jul 30 19:04:17 2010
@@ -277,7 +277,9 @@ svn_ra_serf__get_locations(svn_ra_sessio
err = svn_ra_serf__context_run_wait(&loc_ctx->done, session, pool);
SVN_ERR(svn_error_compose_create(
- svn_ra_serf__error_on_status(loc_ctx->status_code, req_url),
+ svn_ra_serf__error_on_status(loc_ctx->status_code,
+ req_url,
+ parser_ctx->location),
err));
return SVN_NO_ERROR;
Modified: subversion/trunk/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/getlocationsegments.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/getlocationsegments.c Fri Jul 30 19:04:17 2010
@@ -181,7 +181,7 @@ svn_ra_serf__get_location_segments(svn_r
svn_ra_serf__handler_t *handler;
svn_ra_serf__xml_parser_t *parser_ctx;
const char *relative_url, *basecoll_url, *req_url;
- svn_error_t *err;
+ svn_error_t *err, *err2;
gls_ctx = apr_pcalloc(pool, sizeof(*gls_ctx));
gls_ctx->path = path;
@@ -230,8 +230,15 @@ svn_ra_serf__get_location_segments(svn_r
_("Location segment report failed on '%s'@'%ld'"),
path, peg_revision);
- /* ### Leaks err */
- SVN_ERR(svn_ra_serf__error_on_status(gls_ctx->status_code, handler->path));
+ err2 = svn_ra_serf__error_on_status(gls_ctx->status_code,
+ handler->path,
+ parser_ctx->location);
+ if (err2)
+ {
+ /* Prefer err2 to err. */
+ svn_error_clear(err);
+ return err2;
+ }
svn_pool_destroy(gls_ctx->subpool);
Modified: subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/mergeinfo.c Fri Jul 30 19:04:17 2010
@@ -290,12 +290,12 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
err = svn_ra_serf__context_run_wait(&mergeinfo_ctx->done, session, pool);
- err2 = svn_ra_serf__error_on_status(status_code, handler->path);
-
+ err2 = svn_ra_serf__error_on_status(status_code, handler->path,
+ parser_ctx->location);
if (err2)
{
svn_error_clear(err);
- SVN_ERR(err2);
+ return err2;
}
SVN_ERR(err);
Modified: subversion/trunk/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/options.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/options.c Fri Jul 30 19:04:17 2010
@@ -481,15 +481,20 @@ svn_ra_serf__exchange_capabilities(svn_r
apr_pool_t *pool)
{
svn_ra_serf__options_context_t *opt_ctx;
+ svn_error_t *err;
/* This routine automatically fills in serf_sess->capabilities */
svn_ra_serf__create_options_req(&opt_ctx, serf_sess, serf_sess->conns[0],
serf_sess->repos_url.path, pool);
- SVN_ERR(svn_ra_serf__context_run_wait(
- svn_ra_serf__get_options_done_ptr(opt_ctx), serf_sess, pool));
+ err = svn_ra_serf__context_run_wait(
+ svn_ra_serf__get_options_done_ptr(opt_ctx), serf_sess, pool);
- return SVN_NO_ERROR;
+ return svn_error_compose_create(
+ svn_ra_serf__error_on_status(opt_ctx->status_code,
+ serf_sess->repos_url.path,
+ opt_ctx->parser_ctx->location),
+ err);
}
Modified: subversion/trunk/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/property.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/property.c Fri Jul 30 19:04:17 2010
@@ -700,7 +700,8 @@ svn_ra_serf__wait_for_props(svn_ra_serf_
err = svn_ra_serf__context_run_wait(&prop_ctx->done, sess, pool);
- err2 = svn_ra_serf__error_on_status(prop_ctx->status_code, prop_ctx->path);
+ err2 = svn_ra_serf__error_on_status(prop_ctx->status_code,
+ prop_ctx->path, NULL);
if (err2)
{
svn_error_clear(err);
Modified: subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Fri Jul 30 19:04:17 2010
@@ -623,6 +623,10 @@ struct svn_ra_serf__xml_parser_t {
*/
int *status_code;
+ /* If non-NULL, this is the value of the response's Location header.
+ */
+ const char *location;
+
/* If non-NULL, this value will be set to TRUE when the response is
* completed.
*/
@@ -686,6 +690,10 @@ typedef struct svn_ra_serf__simple_reque
/* The HTTP status line of the response */
const char *reason;
+ /* The Location header value of the response, or NULL if there
+ wasn't one. */
+ const char *location;
+
/* This value is set to TRUE when the response is completed. */
svn_boolean_t done;
@@ -775,6 +783,13 @@ svn_ra_serf__response_discard_handler(se
void *baton,
apr_pool_t *pool);
+/* Return the value of the RESPONSE's Location header if any, or NULL
+ * otherwise. All allocations will be made in POOL.
+ */
+const char *
+svn_ra_serf__response_get_location(serf_bucket_t *response,
+ apr_pool_t *pool);
+
/** XML helper functions. **/
/*
@@ -1498,11 +1513,14 @@ svn_ra_serf__encode_auth_header(const ch
/*** General utility functions ***/
/**
- * Convert an HTTP status code resulting from a WebDAV request to the relevant
- * error code.
+ * Convert an HTTP STATUS_CODE resulting from a WebDAV request against
+ * PATH to the relevant error code. Use the response-supplied LOCATION
+ * where it necessary.
*/
svn_error_t *
-svn_ra_serf__error_on_status(int status_code, const char *path);
+svn_ra_serf__error_on_status(int status_code,
+ const char *path,
+ const char *location);
#ifdef __cplusplus
}
Modified: subversion/trunk/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/update.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/update.c Fri Jul 30 19:04:17 2010
@@ -995,11 +995,15 @@ handle_stream(serf_request_t *request,
{
report_fetch_t *fetch_ctx = handler_baton;
serf_status_line sl;
+ const char *location;
serf_bucket_response_status(response, &sl);
/* Woo-hoo. Nothing here to see. */
- fetch_ctx->err = svn_ra_serf__error_on_status(sl.code, fetch_ctx->info->name);
+ location = svn_ra_serf__response_get_location(response, pool);
+ fetch_ctx->err = svn_ra_serf__error_on_status(sl.code,
+ fetch_ctx->info->name,
+ location);
if (fetch_ctx->err)
{
fetch_ctx->done = TRUE;
Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=980924&r1=980923&r2=980924&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Fri Jul 30 19:04:17 2010
@@ -804,6 +804,18 @@ svn_ra_serf__response_discard_handler(se
}
}
+const char *
+svn_ra_serf__response_get_location(serf_bucket_t *response,
+ apr_pool_t *pool)
+{
+ serf_bucket_t *headers;
+ const char *val;
+
+ headers = serf_bucket_response_get_headers(response);
+ val = serf_bucket_headers_get(headers, "Location");
+ return val ? svn_uri_canonicalize(val, pool) : NULL;
+}
+
/* Implements svn_ra_serf__response_handler_t */
svn_error_t *
svn_ra_serf__handle_status_only(serf_request_t *request,
@@ -826,7 +838,7 @@ svn_ra_serf__handle_status_only(serf_req
ctx->status = sl.code;
ctx->reason = sl.reason;
-
+ ctx->location = svn_ra_serf__response_get_location(response, pool);
ctx->done = TRUE;
}
@@ -986,6 +998,7 @@ svn_ra_serf__handle_multistatus_only(ser
ctx->status = sl.code;
ctx->reason = sl.reason;
+ ctx->location = svn_ra_serf__response_get_location(response, pool);
}
return svn_error_return(err);
@@ -1060,6 +1073,11 @@ svn_ra_serf__handle_xml_parser(serf_requ
*ctx->status_code = sl.code;
}
+ if (sl.code == 301 || sl.code == 302)
+ {
+ ctx->location = svn_ra_serf__response_get_location(response, pool);
+ }
+
/* Woo-hoo. Nothing here to see. */
if (sl.code == 404 && ctx->ignore_errors == FALSE)
{
@@ -1702,18 +1720,20 @@ svn_ra_serf__report_resource(const char
}
svn_error_t *
-svn_ra_serf__error_on_status(int status_code, const char *path)
+svn_ra_serf__error_on_status(int status_code,
+ const char *path,
+ const char *location)
{
switch(status_code)
{
case 301:
case 302:
return svn_error_createf(SVN_ERR_RA_DAV_RELOCATED, NULL,
- (status_code == 301)
- ? _("Repository moved permanently to '%s';"
- " please relocate")
- : _("Repository moved temporarily to '%s';"
- " please relocate"), path);
+ (status_code == 301)
+ ? _("Repository moved permanently to '%s';"
+ " please relocate")
+ : _("Repository moved temporarily to '%s';"
+ " please relocate"), location);
case 404:
return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
_("'%s' path not found"), path);