Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/mod_dav_svn/repos.c  view on Meta::CPAN

#include <http_request.h>
#include <http_protocol.h>
#include <http_log.h>
#include <http_core.h>  /* for ap_construct_url */
#include <mod_dav.h>

#define CORE_PRIVATE      /* To make ap_show_mpm public in 2.2 */
#include <http_config.h>

#include "svn_hash.h"
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_time.h"
#include "svn_fs.h"
#include "svn_repos.h"
#include "svn_dav.h"
#include "svn_sorts.h"
#include "svn_version.h"
#include "svn_props.h"
#include "svn_ctype.h"
#include "svn_subst.h"
#include "mod_dav_svn.h"
#include "svn_ra.h"  /* for SVN_RA_CAPABILITY_* */
#include "svn_dirent_uri.h"
#include "private/svn_log.h"
#include "private/svn_fspath.h"
#include "private/svn_repos_private.h"

#include "dav_svn.h"


#define DEFAULT_ACTIVITY_DB "dav/activities.d"


struct dav_stream {
  const dav_resource *res;

  /* for reading from the FS */
  svn_stream_t *rstream;

  /* for writing to the FS. we use wstream OR the handler/baton. */
  svn_stream_t *wstream;
  svn_txdelta_window_handler_t delta_handler;
  void *delta_baton;
};


/* Convenience structure that facilitates combined memory allocation of
   a dav_resource and dav_resource_private pair. */
typedef struct dav_resource_combined {
  dav_resource res;
  dav_resource_private priv;
} dav_resource_combined;


/* Helper-wrapper around svn_fs_check_path(), which takes the same
   arguments.  But: if we attempt to stat a path like "file1/file2",
   then still return 'svn_node_none' to signal nonexistence, rather
   than a full-blown filesystem error.  This allows mod_dav to throw
   404 instead of 500. */
static dav_error *
fs_check_path(svn_node_kind_t *kind,
              svn_fs_root_t *root,
              const char *path,
              apr_pool_t *pool)
{
  svn_error_t *serr;
  svn_node_kind_t my_kind;

  serr = svn_fs_check_path(&my_kind, root, path, pool);

  /* Possibly trap other fs-errors here someday -- errors which may
     simply indicate the path's nonexistence, rather than a critical
     problem. */
  if (serr && serr->apr_err == SVN_ERR_FS_NOT_DIRECTORY)
    {
      svn_error_clear(serr);
      *kind = svn_node_none;
      return NULL;
    }
  else if (serr)
    {
      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  apr_psprintf(pool, "Error checking kind of "
                                               "path '%s' in repository",
                                               path),
                                  pool);
    }

  *kind = my_kind;
  return NULL;
}


static int
parse_version_uri(dav_resource_combined *comb,
                  const char *path,
                  const char *label,
                  int use_checked_in)
{
  const char *slash;
  const char *created_rev_str;

  /* format: CREATED_REV/REPOS_PATH */

  /* ### what to do with LABEL and USE_CHECKED_IN ?? */

  comb->res.type = DAV_RESOURCE_TYPE_VERSION;
  comb->res.versioned = TRUE;

  slash = ap_strchr_c(path, '/');
  if (slash == NULL)
    {
      /* http://host.name/repos/$svn/ver/0

         This URL form refers to the root path of the repository.
      */
      created_rev_str = apr_pstrndup(comb->res.pool, path, strlen(path));
      comb->priv.root.rev = SVN_STR_TO_REV(created_rev_str);
      comb->priv.repos_path = "/";

src/subversion/subversion/mod_dav_svn/repos.c  view on Meta::CPAN

      comb->res.type = DAV_RESOURCE_TYPE_REGULAR;
      comb->res.versioned = TRUE;

      /* The location of these resources corresponds directly to the URI,
         and we keep the leading "/". */
      comb->priv.repos_path = comb->priv.uri_path->data;
    }

  return FALSE;
}


static dav_error *
prep_regular(dav_resource_combined *comb)
{
  apr_pool_t *pool = comb->res.pool;
  dav_svn_repos *repos = comb->priv.repos;
  svn_error_t *serr;
  dav_error *derr;
  svn_node_kind_t kind;

  /* A REGULAR resource might have a specific revision already (e.g. if it
     is part of a baseline collection). However, if it doesn't, then we
     will assume that we need the youngest revision.
     ### other cases besides a BC? */
  if (comb->priv.root.rev == SVN_INVALID_REVNUM)
    {
      serr = svn_fs_youngest_rev(&comb->priv.root.rev, repos->fs, pool);
      if (serr != NULL)
        {
          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                      "Could not determine the proper "
                                      "revision to access",
                                      pool);
        }
    }

  /* get the root of the tree */
  serr = svn_fs_revision_root(&comb->priv.root.root, repos->fs,
                              comb->priv.root.rev, pool);
  if (serr != NULL)
    {
      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "Could not open the root of the "
                                  "repository",
                                  pool);
    }

  derr = fs_check_path(&kind, comb->priv.root.root,
                       comb->priv.repos_path, pool);
  if (derr != NULL)
    return derr;

  comb->res.exists = (kind != svn_node_none);
  comb->res.collection = (kind == svn_node_dir);

  /* HACK:  dav_get_resource_state() is making shortcut assumptions
     about how to distinguish a null resource from a lock-null
     resource.  This is the only way to get around that problem.
     Without it, it won't ever detect lock-nulls, and thus 'svn unlock
     nonexistentURL' will always return 404's. */
  if (! comb->res.exists)
    comb->priv.r->path_info = (char *) "";

  return NULL;
}


static dav_error *
prep_version(dav_resource_combined *comb)
{
  svn_error_t *serr;
  apr_pool_t *pool = comb->res.pool;

  /* we are accessing the Version Resource by REV/PATH */

  /* ### assert: .baselined = TRUE */

  /* if we don't have a revision, then assume the youngest */
  if (!SVN_IS_VALID_REVNUM(comb->priv.root.rev))
    {
      serr = svn_fs_youngest_rev(&comb->priv.root.rev,
                                 comb->priv.repos->fs,
                                 pool);
      if (serr != NULL)
        {
          /* ### might not be a baseline */

          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                      "Could not fetch 'youngest' revision "
                                      "to enable accessing the latest "
                                      "baseline resource.",
                                      pool);
        }
    }

  /* ### baselines have no repos_path, and we don't need to open
     ### a root (yet). we just needed to ensure that we have the proper
     ### revision number. */

  if (!comb->priv.root.root)
    {
      serr = svn_fs_revision_root(&comb->priv.root.root,
                                  comb->priv.repos->fs,
                                  comb->priv.root.rev,
                                  pool);
      if (serr != NULL)
        {
          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                      "Could not open a revision root.",
                                      pool);
        }
    }

  /* ### we should probably check that the revision is valid */
  comb->res.exists = TRUE;

  /* Set up the proper URI. Most likely, we arrived here via a VCC,
     so the URI will be incorrect. Set the canonical form. */
  /* ### assuming a baseline */
  comb->res.uri = dav_svn__build_uri(comb->priv.repos,



( run in 0.996 second using v1.01-cache-2.11-cpan-39bf76dae61 )