Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/libsvn_ra_serf/commit.c  view on Meta::CPAN

  err = svn_error_compose_create(
            handler->server_error != NULL
              ? handler->server_error->error
              : SVN_NO_ERROR,
            svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                              _("%s of '%s': %d %s"),
                              handler->method, handler->path,
                              handler->sline.code, handler->sline.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(
                                    handler->sline,
                                    handler->path,
                                    handler->location),
                                  err);
}

/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_checkout_body(serf_bucket_t **bkt,
                     void *baton,
                     serf_bucket_alloc_t *alloc,
                     apr_pool_t *pool)
{
  const char *activity_url = baton;
  serf_bucket_t *body_bkt;

  body_bkt = serf_bucket_aggregate_create(alloc);

  svn_ra_serf__add_xml_header_buckets(body_bkt, alloc);
  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:checkout",
                                    "xmlns:D", "DAV:",
                                    NULL);
  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(activity_url != NULL);
  svn_ra_serf__add_cdata_len_buckets(body_bkt, alloc,
                                     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");
  svn_ra_serf__add_tag_buckets(body_bkt, "D:apply-to-version", NULL, alloc);
  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:checkout");

  *bkt = body_bkt;
  return SVN_NO_ERROR;
}


/* Using the HTTPv1 protocol, perform a CHECKOUT of NODE_URL within the
   given COMMIT_CTX. The resulting working resource will be returned in
   *WORKING_URL, allocated from RESULT_POOL. All temporary allocations
   are performed in SCRATCH_POOL.

   ### are these URLs actually repos relpath values? or fspath? or maybe
   ### the abspath portion of the full URL.

   This function operates synchronously.

   Strictly speaking, we could perform "all" of the CHECKOUT requests
   when the commit starts, and only block when we need a specific
   answer. Or, at a minimum, send off these individual requests async
   and block when we need the answer (eg PUT or PROPPATCH).

   However: the investment to speed this up is not worthwhile, given
   that CHECKOUT (and the related round trip) is completely obviated
   in HTTPv2.
*/
static svn_error_t *
checkout_node(const char **working_url,
              const commit_context_t *commit_ctx,
              const char *node_url,
              apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
{
  svn_ra_serf__handler_t handler = { 0 };
  apr_status_t status;
  apr_uri_t uri;

  /* HANDLER_POOL is the scratch pool since we don't need to remember
     anything from the handler. We just want the working resource.  */
  handler.handler_pool = scratch_pool;
  handler.session = commit_ctx->session;
  handler.conn = commit_ctx->conn;

  handler.body_delegate = create_checkout_body;
  handler.body_delegate_baton = (/* const */ void *)commit_ctx->activity_url;
  handler.body_type = "text/xml";

  handler.response_handler = svn_ra_serf__expect_empty_body;
  handler.response_baton = &handler;

  handler.method = "CHECKOUT";
  handler.path = node_url;

  SVN_ERR(svn_ra_serf__context_run_one(&handler, scratch_pool));

  if (handler.sline.code != 201)
    return svn_error_trace(return_response_err(&handler));

  if (handler.location == NULL)
    return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                            _("No Location header received"));

  /* We only want the path portion of the Location header.
     (code.google.com sometimes returns an 'http:' scheme for an
     'https:' transaction ... we'll work around that by stripping the
     scheme, host, and port here and re-adding the correct ones
     later.  */
  status = apr_uri_parse(scratch_pool, handler.location, &uri);
  if (status)
    return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                            _("Error parsing Location header value"));

  *working_url = svn_urlpath__canonicalize(uri.path, result_pool);

  return SVN_NO_ERROR;
}



( run in 1.792 second using v1.01-cache-2.11-cpan-d7f47b0818f )