Beispiel #1
0
static svn_error_t *
svn_ra_local__get_file_revs(svn_ra_session_t *session,
                            const char *path,
                            svn_revnum_t start,
                            svn_revnum_t end,
                            svn_boolean_t include_merged_revisions,
                            svn_file_rev_handler_t handler,
                            void *handler_baton,
                            apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);
  return svn_repos_get_file_revs2(sess->repos, abs_path, start, end,
                                  include_merged_revisions, NULL, NULL,
                                  handler, handler_baton, pool);
}
Beispiel #2
0
svn_error_t *
svn_repos_get_file_revs(svn_repos_t *repos,
                        const char *path,
                        svn_revnum_t start,
                        svn_revnum_t end,
                        svn_repos_authz_func_t authz_read_func,
                        void *authz_read_baton,
                        svn_repos_file_rev_handler_t handler,
                        void *handler_baton,
                        apr_pool_t *pool)
{
  svn_file_rev_handler_t handler2;
  void *handler2_baton;

  svn_compat_wrap_file_rev_handler(&handler2, &handler2_baton, handler,
                                   handler_baton, pool);

  return svn_repos_get_file_revs2(repos, path, start, end, FALSE,
                                  authz_read_func, authz_read_baton,
                                  handler2, handler2_baton, pool);
}
Beispiel #3
0
/* Respond to a client request for a REPORT of type file-revs-report for the
   RESOURCE.  Get request body from DOC and send result to OUTPUT. */
dav_error *
dav_svn__file_revs_report(const dav_resource *resource,
                          const apr_xml_doc *doc,
                          ap_filter_t *output)
{
  svn_error_t *serr;
  dav_error *derr = NULL;
  apr_xml_elem *child;
  int ns;
  struct file_rev_baton frb;
  dav_svn__authz_read_baton arb;
  const char *abs_path = NULL;

  /* These get determined from the request document. */
  svn_revnum_t start = SVN_INVALID_REVNUM;
  svn_revnum_t end = SVN_INVALID_REVNUM;
  svn_boolean_t include_merged_revisions = FALSE;    /* off by default */

  /* Construct the authz read check baton. */
  arb.r = resource->info->r;
  arb.repos = resource->info->repos;

  /* Sanity check. */
  if (!resource->info->repos_path)
    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
                              "The request does not specify a repository path");
  ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
  /* ### This is done on other places, but the document element is
     in this namespace, so is this necessary at all? */
  if (ns == -1)
    {
      return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,
                                    "The request does not contain the 'svn:' "
                                    "namespace, so it is not going to have "
                                    "certain required elements.",
                                    SVN_DAV_ERROR_NAMESPACE,
                                    SVN_DAV_ERROR_TAG);
    }

  /* Get request information. */
  for (child = doc->root->first_child; child != NULL; child = child->next)
    {
      /* if this element isn't one of ours, then skip it */
      if (child->ns != ns)
        continue;

      if (strcmp(child->name, "start-revision") == 0)
        start = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
      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, "include-merged-revisions") == 0)
        include_merged_revisions = TRUE; /* presence indicates positivity */
      else if (strcmp(child->name, "path") == 0)
        {
          const char *rel_path = dav_xml_get_cdata(child, resource->pool, 0);
          if ((derr = dav_svn__test_canonical(rel_path, resource->pool)))
            return derr;

          /* Force REL_PATH to be a relative path, not an fspath. */
          rel_path = svn_relpath_canonicalize(rel_path, resource->pool);

          /* Append the REL_PATH to the base FS path to get an
             absolute repository path. */
          abs_path = svn_fspath__join(resource->info->repos_path, rel_path,
                                      resource->pool);
        }
      /* else unknown element; skip it */
    }

  /* Check that all parameters are present and valid. */
  if (! abs_path)
    return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,
                                  "Not all parameters passed.",
                                  SVN_DAV_ERROR_NAMESPACE,
                                  SVN_DAV_ERROR_TAG);

  frb.bb = apr_brigade_create(resource->pool,
                              output->c->bucket_alloc);
  frb.output = output;
  frb.needs_header = TRUE;
  frb.svndiff_version = resource->info->svndiff_version;
  frb.compression_level = dav_svn__get_compression_level(resource->info->r);

  /* file_rev_handler will send header first time it is called. */

  /* Get the revisions and send them. */
  serr = svn_repos_get_file_revs2(resource->info->repos->repos,
                                  abs_path, start, end, include_merged_revisions,
                                  dav_svn__authz_read_func(&arb), &arb,
                                  file_rev_handler, &frb, resource->pool);

  if (serr)
    {
      /* We don't 'goto cleanup' because ap_fflush() tells httpd
         to write the HTTP headers out, and that includes whatever
         r->status is at that particular time.  When we call
         dav_svn__convert_err(), we don't immediately set r->status
         right then, so r->status remains 0, hence HTTP status 200
         would be misleadingly returned. */
      return (dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                   serr->message, resource->pool));
    }

  if ((serr = maybe_send_header(&frb)))
    {
      derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "Error beginning REPORT reponse",
                                  resource->pool);
      goto cleanup;
    }

  if ((serr = dav_svn__brigade_puts(frb.bb, frb.output,
                                    "</S:file-revs-report>" DEBUG_CR)))
    {
      derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "Error ending REPORT reponse",
                                  resource->pool);
      goto cleanup;
    }

 cleanup:

  /* We've detected a 'high level' svn action to log. */
  dav_svn__operational_log(resource->info,
                           svn_log__get_file_revs(abs_path, start, end,
                                                  include_merged_revisions,
                                                  resource->pool));

  return dav_svn__final_flush_or_error(resource->info->r, frb.bb, output,
                                       derr, resource->pool);
}