Author: gstein
Date: Fri Jun 15 08:55:40 2012
New Revision: 1350541
URL: http://svn.apache.org/viewvc?rev=1350541&view=rev
Log:
Fix a problem with trying to fetch the Location: header when checking
out a node. The code was examining HANDLER->DONE before it would
extract the Location: header, but that was simply wrong. The Location:
header is always set before an ra_serf response handler is invoked, so
there is no need to check DONE. Further, when the DONE flag gets set,
the response handler might never get called(!).
However, the handle_checkout() response handler is really just a cover
for expect_empty_body() with an "override" to capture the Location:
header. But the core ra_serf response processing *already* captures
the Location: header whenever it is present.
So... this is run synchronously, we can just examine the handler's
LOCATION field after the request completes. And we can use
expect_empty_body() directly.
* subversion/libsvn_ra_serf/commit.c:
(checkout_context_t): not needed. removed.
(create_checkout_body): the baton is now the activity_url.
(handle_checkout): not needed. removed.
(checkout_node): no longer set up a checkout_context_t, and just
pass the activity_url as the BODY_DELEGATE_BATON. go ahead and use
svn_ra_serf__expect_empty_body for the response handler. examine
HANDLER.LOCATION after the request completes.
Modified:
subversion/trunk/subversion/libsvn_ra_serf/commit.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/commit.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/commit.c?rev=1350541&r1=1350540&r2=1350541&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/commit.c Fri Jun 15 08:55:40 2012
@@ -42,22 +42,6 @@
#include "ra_serf.h"
#include "../libsvn_ra/ra_loader.h"
-
-/* Structure associated with a CHECKOUT request. */
-typedef struct checkout_context_t {
- /* The handler running the CHECKOUT. */
- svn_ra_serf__handler_t *handler;
-
- /* The pool for allocating RESOURCE_URL. */
- apr_pool_t *result_pool;
-
- /* The activity that will hold the checked-out resource. */
- const char *activity_url;
-
- /* The output: */
- const char *resource_url;
-
-} checkout_context_t;
/* Baton passed back with the commit editor. */
typedef struct commit_context_t {
@@ -250,7 +234,7 @@ create_checkout_body(serf_bucket_t **bkt
serf_bucket_alloc_t *alloc,
apr_pool_t *pool)
{
- checkout_context_t *ctx = baton;
+ const char *activity_url = baton;
serf_bucket_t *body_bkt;
body_bkt = serf_bucket_aggregate_create(alloc);
@@ -262,10 +246,10 @@ create_checkout_body(serf_bucket_t **bkt
svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:activity-set", NULL);
svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:href", NULL);
- SVN_ERR_ASSERT(ctx->activity_url != NULL);
+ SVN_ERR_ASSERT(activity_url != NULL);
svn_ra_serf__add_cdata_len_buckets(body_bkt, alloc,
- ctx->activity_url,
- strlen(ctx->activity_url));
+ activity_url,
+ strlen(activity_url));
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href");
svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:activity-set");
@@ -276,53 +260,6 @@ create_checkout_body(serf_bucket_t **bkt
return SVN_NO_ERROR;
}
-/* Implements svn_ra_serf__response_handler_t */
-static svn_error_t *
-handle_checkout(serf_request_t *request,
- serf_bucket_t *response,
- void *baton,
- apr_pool_t *pool)
-{
- checkout_context_t *ctx = baton;
- svn_ra_serf__handler_t *handler = ctx->handler;
-
- svn_error_t *err = svn_ra_serf__expect_empty_body(request, response,
- handler, pool);
-
- /* These handler functions are supposed to return an APR_EOF status
- wrapped in a svn_error_t to indicate to serf that the response was
- completely read. While we have to return this status code to our
- caller, we should treat it as the normal case for now. */
- if (err && ! APR_STATUS_IS_EOF(err->apr_err))
- return err;
-
- /* Get the resulting location. */
- if (handler->done && handler->sline.code == 201)
- {
- serf_bucket_t *hdrs;
- apr_uri_t uri;
- const char *location;
- apr_status_t status;
-
- hdrs = serf_bucket_response_get_headers(response);
- location = serf_bucket_headers_get(hdrs, "Location");
- if (!location)
- return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, err,
- _("No Location header received"));
-
- status = apr_uri_parse(pool, location, &uri);
-
- if (status)
- err = svn_error_compose_create(svn_error_wrap_apr(status, NULL), err);
-
- SVN_ERR_ASSERT(ctx->result_pool != NULL);
- ctx->resource_url = svn_urlpath__canonicalize(uri.path,
- ctx->result_pool);
- }
-
- return err;
-}
-
/* Using the HTTPv1 protocol, perform a CHECKOUT of NODE_URL within the
given COMMIT_CTX. The resulting working resource will be returned in
@@ -351,7 +288,6 @@ checkout_node(const char **working_url,
apr_pool_t *scratch_pool)
{
svn_ra_serf__handler_t handler = { 0 };
- checkout_context_t checkout_ctx = { 0 };
/* HANDLER_POOL is the scratch pool since we don't need to remember
anything from the handler. We just want the working resource. */
@@ -359,16 +295,12 @@ checkout_node(const char **working_url,
handler.session = commit_ctx->session;
handler.conn = commit_ctx->conn;
- checkout_ctx.handler = &handler;
- checkout_ctx.result_pool = result_pool;
- checkout_ctx.activity_url = commit_ctx->activity_url;
-
handler.body_delegate = create_checkout_body;
- handler.body_delegate_baton = &checkout_ctx;
+ handler.body_delegate_baton = (/* const */ void *)commit_ctx->activity_url;
handler.body_type = "text/xml";
- handler.response_handler = handle_checkout;
- handler.response_baton = &checkout_ctx;
+ handler.response_handler = svn_ra_serf__expect_empty_body;
+ handler.response_baton = &handler;
handler.method = "CHECKOUT";
handler.path = node_url;
@@ -378,8 +310,11 @@ checkout_node(const char **working_url,
if (handler.sline.code != 201)
return svn_error_trace(return_response_err(&handler));
- /* Already in the correct pool. */
- *working_url = checkout_ctx.resource_url;
+ if (handler.location == NULL)
+ return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+ _("No Location header received"));
+
+ *working_url = apr_pstrdup(result_pool, handler.location);
return SVN_NO_ERROR;
}