Example #1
0
svn_error_t *
svn_ra_serf__get_file_revs(svn_ra_session_t *ra_session,
                           const char *path,
                           svn_revnum_t start,
                           svn_revnum_t end,
                           svn_boolean_t include_merged_revisions,
                           svn_file_rev_handler_t rev_handler,
                           void *rev_handler_baton,
                           apr_pool_t *pool)
{
  blame_context_t *blame_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url;
  svn_revnum_t peg_rev;

  blame_ctx = apr_pcalloc(pool, sizeof(*blame_ctx));
  blame_ctx->pool = pool;
  blame_ctx->path = path;
  blame_ctx->file_rev = rev_handler;
  blame_ctx->file_rev_baton = rev_handler_baton;
  blame_ctx->start = start;
  blame_ctx->end = end;
  blame_ctx->include_merged_revisions = include_merged_revisions;

  /* Since Subversion 1.8 we allow retrieving blames backwards. So we can't
     just unconditionally use end_rev as the peg revision as before */
  if (end > start)
    peg_rev = end;
  else
    peg_rev = start;

  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                      session,
                                      NULL /* url */, peg_rev,
                                      pool, pool));

  xmlctx = svn_ra_serf__xml_context_create(blame_ttable,
                                           blame_opened,
                                           blame_closed,
                                           blame_cdata,
                                           blame_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_type = "text/xml";
  handler->body_delegate = create_file_revs_body;
  handler->body_delegate_baton = blame_ctx;

  SVN_ERR(svn_ra_serf__context_run_one(handler, pool));

  if (handler->sline.code != 200)
    return svn_error_trace(svn_ra_serf__unexpected_status(handler));

  return SVN_NO_ERROR;
}
Example #2
0
svn_error_t *
svn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **propfind_handler,
                                     svn_ra_serf__session_t *sess,
                                     const char *path,
                                     svn_revnum_t rev,
                                     const char *depth,
                                     const svn_ra_serf__dav_props_t *find_props,
                                     svn_ra_serf__prop_func_t prop_func,
                                     void *prop_func_baton,
                                     apr_pool_t *pool)
{
  propfind_context_t *new_prop_ctx;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;

  new_prop_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx));

  new_prop_ctx->path = path;
  new_prop_ctx->find_props = find_props;
  new_prop_ctx->prop_func = prop_func;
  new_prop_ctx->prop_func_baton = prop_func_baton;
  new_prop_ctx->depth = depth;

  if (SVN_IS_VALID_REVNUM(rev))
    {
      new_prop_ctx->label = apr_ltoa(pool, rev);
    }
  else
    {
      new_prop_ctx->label = NULL;
    }

  xmlctx = svn_ra_serf__xml_context_create(propfind_ttable,
                                           propfind_opened,
                                           propfind_closed,
                                           NULL,
                                           new_prop_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(sess, xmlctx,
                                              propfind_expected_status,
                                              pool);

  handler->method = "PROPFIND";
  handler->path = path;
  handler->body_delegate = create_propfind_body;
  handler->body_type = "text/xml";
  handler->body_delegate_baton = new_prop_ctx;
  handler->header_delegate = setup_propfind_headers;
  handler->header_delegate_baton = new_prop_ctx;

  handler->no_dav_headers = TRUE;

  new_prop_ctx->handler = handler;

  *propfind_handler = handler;

  return SVN_NO_ERROR;
}
Example #3
0
svn_error_t *
svn_ra_serf__list(svn_ra_session_t *ra_session,
                  const char *path,
                  svn_revnum_t revision,
                  const apr_array_header_t *patterns,
                  svn_depth_t depth,
                  apr_uint32_t dirent_fields,
                  svn_ra_dirent_receiver_t receiver,
                  void *receiver_baton,
                  apr_pool_t *scratch_pool)
{
  list_context_t *list_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url;

  list_ctx = apr_pcalloc(scratch_pool, sizeof(*list_ctx));
  list_ctx->pool = scratch_pool;
  list_ctx->receiver = receiver;
  list_ctx->receiver_baton = receiver_baton;
  list_ctx->path = path;
  list_ctx->revision = revision;
  list_ctx->patterns = patterns;
  list_ctx->depth = depth;
  list_ctx->dirent_fields = dirent_fields;
  list_ctx->props = svn_ra_serf__get_dirent_props(dirent_fields, session,
                                                  scratch_pool);
  list_ctx->author_buf = svn_stringbuf_create_empty(scratch_pool);

  /* At this point, we may have a deleted file.  So, we'll match ra_neon's
   * behavior and use the larger of start or end as our 'peg' rev.
   */
  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                      session,
                                      NULL /* url */, revision,
                                      scratch_pool, scratch_pool));

  xmlctx = svn_ra_serf__xml_context_create(log_ttable,
                                           NULL, item_closed, NULL,
                                           list_ctx,
                                           scratch_pool);
  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
                                              scratch_pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_delegate = create_list_body;
  handler->body_delegate_baton = list_ctx;
  handler->body_type = "text/xml";

  SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));

  if (handler->sline.code != 200)
    SVN_ERR(svn_ra_serf__unexpected_status(handler));

  return SVN_NO_ERROR;
}
Example #4
0
svn_error_t *
svn_ra_serf__get_file_revs(svn_ra_session_t *ra_session,
                           const char *path,
                           svn_revnum_t start,
                           svn_revnum_t end,
                           svn_boolean_t include_merged_revisions,
                           svn_file_rev_handler_t rev_handler,
                           void *rev_handler_baton,
                           apr_pool_t *pool)
{
  blame_context_t *blame_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url;
  svn_error_t *err;

  blame_ctx = apr_pcalloc(pool, sizeof(*blame_ctx));
  blame_ctx->pool = pool;
  blame_ctx->path = path;
  blame_ctx->file_rev = rev_handler;
  blame_ctx->file_rev_baton = rev_handler_baton;
  blame_ctx->start = start;
  blame_ctx->end = end;
  blame_ctx->include_merged_revisions = include_merged_revisions;

  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                      session, NULL /* conn */,
                                      NULL /* url */, end,
                                      pool, pool));

  xmlctx = svn_ra_serf__xml_context_create(blame_ttable,
                                           blame_opened,
                                           blame_closed,
                                           blame_cdata,
                                           blame_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_type = "text/xml";
  handler->body_delegate = create_file_revs_body;
  handler->body_delegate_baton = blame_ctx;
  handler->conn = session->conns[0];
  handler->session = session;

  err = svn_ra_serf__context_run_one(handler, pool);

  err = svn_error_compose_create(
            svn_ra_serf__error_on_status(handler->sline,
                                         handler->path,
                                         handler->location),
            err);

  return svn_error_trace(err);
}
Example #5
0
svn_error_t *
svn_ra_serf__get_locations(svn_ra_session_t *ra_session,
                           apr_hash_t **locations,
                           const char *path,
                           svn_revnum_t peg_revision,
                           const apr_array_header_t *location_revisions,
                           apr_pool_t *pool)
{
  loc_context_t *loc_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url;
  svn_error_t *err;

  loc_ctx = apr_pcalloc(pool, sizeof(*loc_ctx));
  loc_ctx->pool = pool;
  loc_ctx->path = path;
  loc_ctx->peg_revision = peg_revision;
  loc_ctx->location_revisions = location_revisions;
  loc_ctx->paths = apr_hash_make(loc_ctx->pool);

  *locations = loc_ctx->paths;

  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                      session, NULL /* conn */,
                                      NULL /* url */, peg_revision,
                                      pool, pool));

  xmlctx = svn_ra_serf__xml_context_create(getloc_ttable,
                                           NULL, getloc_closed, NULL,
                                           loc_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_delegate = create_get_locations_body;
  handler->body_delegate_baton = loc_ctx;
  handler->body_type = "text/xml";
  handler->conn = session->conns[0];
  handler->session = session;

  err = svn_ra_serf__context_run_one(handler, pool);

  SVN_ERR(svn_error_compose_create(
              svn_ra_serf__error_on_status(handler->sline.code,
                                           req_url,
                                           handler->location),
              err));

  return SVN_NO_ERROR;
}
Example #6
0
svn_error_t *
svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
                       apr_hash_t **locks,
                       const char *path,
                       svn_depth_t depth,
                       apr_pool_t *pool)
{
  lock_context_t *lock_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url, *rel_path;

  req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
  SVN_ERR(svn_ra_serf__get_relative_path(&rel_path, req_url, session,
                                         NULL, pool));

  lock_ctx = apr_pcalloc(pool, sizeof(*lock_ctx));
  lock_ctx->pool = pool;
  lock_ctx->path = apr_pstrcat(pool, "/", rel_path, (char *)NULL);
  lock_ctx->requested_depth = depth;
  lock_ctx->hash = apr_hash_make(pool);

  xmlctx = svn_ra_serf__xml_context_create(getlocks_ttable,
                                           NULL, getlocks_closed, NULL,
                                           lock_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_type = "text/xml";
  handler->conn = session->conns[0];
  handler->session = session;

  handler->body_delegate = create_getlocks_body;
  handler->body_delegate_baton = lock_ctx;

  SVN_ERR(svn_ra_serf__context_run_one(handler, pool));

  /* We get a 404 when a path doesn't exist in HEAD, but it might
     have existed earlier (E.g. 'svn ls http://s/svn/trunk/file@1' */
  if (handler->sline.code != 404)
    {
      SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
                                           handler->path,
                                           handler->location));
    }

  *locks = lock_ctx->hash;

  return SVN_NO_ERROR;
}
Example #7
0
svn_error_t *
svn_ra_serf__get_deleted_rev(svn_ra_session_t *session,
                             const char *path,
                             svn_revnum_t peg_revision,
                             svn_revnum_t end_revision,
                             svn_revnum_t *revision_deleted,
                             apr_pool_t *pool)
{
  drev_context_t *drev_ctx;
  svn_ra_serf__session_t *ras = session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url;
  svn_error_t *err;

  drev_ctx = apr_pcalloc(pool, sizeof(*drev_ctx));
  drev_ctx->path = path;
  drev_ctx->peg_revision = peg_revision;
  drev_ctx->end_revision = end_revision;
  drev_ctx->revision_deleted = revision_deleted;

  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                      ras, NULL /* conn */,
                                      NULL /* url */, peg_revision,
                                      pool, pool));

  xmlctx = svn_ra_serf__xml_context_create(getdrev_ttable,
                                           NULL, getdrev_closed, NULL,
                                           drev_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_type = "text/xml";
  handler->body_delegate = create_getdrev_body;
  handler->body_delegate_baton = drev_ctx;
  handler->conn = ras->conns[0];
  handler->session = ras;

  err = svn_ra_serf__context_run_one(handler, pool);

  /* Map status 501: Method Not Implemented to our not implemented error.
     1.5.x servers and older don't support this report. */
  if (handler->sline.code == 501)
    return svn_error_createf(SVN_ERR_RA_NOT_IMPLEMENTED, err,
                             _("'%s' REPORT not implemented"),
                             "get-deleted-rev");
  SVN_ERR(err);

  return SVN_NO_ERROR;
}
Example #8
0
svn_error_t *
svn_ra_serf__get_dated_revision(svn_ra_session_t *ra_session,
                                svn_revnum_t *revision,
                                apr_time_t tm,
                                apr_pool_t *pool)
{
  date_context_t *date_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *report_target;

  date_ctx = apr_palloc(pool, sizeof(*date_ctx));
  date_ctx->time = tm;
  date_ctx->revision = revision;

  SVN_ERR(svn_ra_serf__report_resource(&report_target, session, pool));

  xmlctx = svn_ra_serf__xml_context_create(date_ttable,
                                           NULL, date_closed, NULL,
                                           date_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool);

  handler->method = "REPORT";
  handler->path = report_target;
  handler->body_type = "text/xml";

  handler->body_delegate = create_getdate_body;
  handler->body_delegate_baton = date_ctx;

  *date_ctx->revision = SVN_INVALID_REVNUM;

  SVN_ERR(svn_ra_serf__context_run_one(handler, pool));

  if (handler->sline.code != 200)
    return svn_error_trace(svn_ra_serf__unexpected_status(handler));

  if (!SVN_IS_VALID_REVNUM(*revision))
    return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
                            _("The REPORT response did not include "
                              "the requested properties"));

  return SVN_NO_ERROR;
}
Example #9
0
svn_error_t *
svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
                       svn_ra_serf__session_t *session,
                       const char *merge_resource_url,
                       apr_hash_t *lock_tokens,
                       svn_boolean_t keep_locks,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  merge_context_t *merge_ctx;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;

  merge_ctx = apr_pcalloc(scratch_pool, sizeof(*merge_ctx));

  merge_ctx->pool = result_pool;
  merge_ctx->session = session;

  merge_ctx->merge_resource_url = merge_resource_url;

  merge_ctx->lock_tokens = lock_tokens;
  merge_ctx->keep_locks = keep_locks;

  /* We don't need the full merge response when working over HTTPv2.
   * Over HTTPv1, this response is only required with a non-null
   * svn_ra_push_wc_prop_func_t callback. */
  merge_ctx->disable_merge_response =
    SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session) ||
    session->wc_callbacks->push_wc_prop == NULL;

  merge_ctx->commit_info = svn_create_commit_info(result_pool);

  merge_ctx->merge_url = session->session_url.path;

  xmlctx = svn_ra_serf__xml_context_create(merge_ttable,
                                           NULL, merge_closed, NULL,
                                           merge_ctx,
                                           scratch_pool);
  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
                                              scratch_pool);

  handler->method = "MERGE";
  handler->path = merge_ctx->merge_url;
  handler->body_delegate = create_merge_body;
  handler->body_delegate_baton = merge_ctx;
  handler->body_type = "text/xml";

  handler->header_delegate = setup_merge_headers;
  handler->header_delegate_baton = merge_ctx;

  merge_ctx->handler = handler;

  SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));

  if (handler->sline.code != 200)
    return svn_error_trace(svn_ra_serf__unexpected_status(handler));

  *commit_info = merge_ctx->commit_info;

  /* Sanity check (Reported to be triggered by CodePlex's svnbridge) */
  if (! SVN_IS_VALID_REVNUM(merge_ctx->commit_info->revision))
    {
      return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
                              _("The MERGE response did not include "
                                "a new revision"));
    }

  merge_ctx->commit_info->repos_root = apr_pstrdup(result_pool,
                                                   session->repos_root_str);

  return SVN_NO_ERROR;
}
Example #10
0
svn_error_t *
svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
                       svn_ra_serf__session_t *session,
                       const char *merge_resource_url,
                       apr_hash_t *lock_tokens,
                       svn_boolean_t keep_locks,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  merge_context_t *merge_ctx;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;

  merge_ctx = apr_pcalloc(scratch_pool, sizeof(*merge_ctx));

  merge_ctx->pool = result_pool;
  merge_ctx->session = session;

  merge_ctx->merge_resource_url = merge_resource_url;

  merge_ctx->lock_tokens = lock_tokens;
  merge_ctx->keep_locks = keep_locks;

  merge_ctx->commit_info = svn_create_commit_info(result_pool);

  merge_ctx->merge_url = session->session_url.path;

  xmlctx = svn_ra_serf__xml_context_create(merge_ttable,
                                           NULL, merge_closed, NULL,
                                           merge_ctx,
                                           scratch_pool);
  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
                                              scratch_pool);

  handler->method = "MERGE";
  handler->path = merge_ctx->merge_url;
  handler->body_delegate = create_merge_body;
  handler->body_delegate_baton = merge_ctx;

  handler->header_delegate = setup_merge_headers;
  handler->header_delegate_baton = merge_ctx;

  merge_ctx->handler = handler;

  SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));

  if (handler->sline.code != 200)
    return svn_error_trace(svn_ra_serf__unexpected_status(handler));

  *commit_info = merge_ctx->commit_info;

  /* Sanity check (Reported to be triggered by CodePlex's svnbridge) */
  if (! SVN_IS_VALID_REVNUM(merge_ctx->commit_info->revision))
    {
      return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
                              _("The MERGE response did not include "
                                "a new revision"));
    }

  merge_ctx->commit_info->repos_root = apr_pstrdup(result_pool,
                                                   session->repos_root_str);

  return SVN_NO_ERROR;
}
Example #11
0
svn_error_t *
svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
                       apr_hash_t **locks,
                       const char *path,
                       svn_depth_t depth,
                       apr_pool_t *pool)
{
  lock_context_t *lock_ctx;
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *req_url, *rel_path;
  svn_error_t *err;

  req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
  SVN_ERR(svn_ra_serf__get_relative_path(&rel_path, req_url, session, pool));

  lock_ctx = apr_pcalloc(pool, sizeof(*lock_ctx));
  lock_ctx->pool = pool;
  lock_ctx->path = apr_pstrcat(pool, "/", rel_path, SVN_VA_NULL);
  lock_ctx->requested_depth = depth;
  lock_ctx->hash = apr_hash_make(pool);

  xmlctx = svn_ra_serf__xml_context_create(getlocks_ttable,
                                           NULL, getlocks_closed, NULL,
                                           lock_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool);

  handler->method = "REPORT";
  handler->path = req_url;
  handler->body_type = "text/xml";

  handler->body_delegate = create_getlocks_body;
  handler->body_delegate_baton = lock_ctx;

  err = svn_ra_serf__context_run_one(handler, pool);

  if (err)
    {
      if (svn_error_find_cause(err, SVN_ERR_UNSUPPORTED_FEATURE))
        {
          /* The server told us that it doesn't support this report type.
             We return the documented error for svn_ra_get_locks(), but
             with the original error report */
          return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL);
        }
      else if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
        {
          /* File doesn't exist in HEAD: Not an error */
          svn_error_clear(err);
        }
      else
        return svn_error_trace(err);
    }

  /* We get a 404 when a path doesn't exist in HEAD, but it might
     have existed earlier (E.g. 'svn ls http://s/svn/trunk/file@1' */
  if (handler->sline.code != 200
      && handler->sline.code != 404)
    {
      return svn_error_trace(svn_ra_serf__unexpected_status(handler));
    }

  *locks = lock_ctx->hash;

  return SVN_NO_ERROR;
}