⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 repos.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  repos->autoversioning = dav_svn_get_autoversioning_flag(r);  /* Remember various bits for later URL construction */  repos->base_url = ap_construct_url(r->pool, "", r);  repos->special_uri = dav_svn_get_special_uri(r);  /* Remember who is making this request */  repos->username = r->user;  /* Remember if the requesting client is a Subversion client */  {    const char *ua = apr_table_get(r->headers_in, "User-Agent");    if (ua && (ap_strstr_c(ua, "SVN/") == ua))      repos->is_svn_client = TRUE;  }    /* Retrieve/cache open repository */  repos_key = apr_pstrcat(r->pool, "mod_dav_svn:", fs_path, NULL);  apr_pool_userdata_get(&userdata, repos_key, r->connection->pool);  repos->repos = userdata;  if (repos->repos == NULL)    {      serr = svn_repos_open(&(repos->repos), fs_path, r->connection->pool);      if (serr != NULL)        {          /* The error returned by svn_repos_open might contain the             actual path to the failed repository.  We don't want to             leak that path back to the client, because that would be             a security risk, but we do want to log the real error on             the server side. */          return dav_svn__sanitize_error(serr, "Could not open the requested "                                         "SVN filesystem",                                         HTTP_INTERNAL_SERVER_ERROR, r);        }      /* Cache the open repos for the next request on this connection */      apr_pool_userdata_set(repos->repos, repos_key,                            NULL, r->connection->pool);    }  /* cache the filesystem object */  repos->fs = svn_repos_fs(repos->repos);  /* capture warnings during cleanup of the FS */  svn_fs_set_warning_func(repos->fs, log_warning, r);  /* if an authenticated username is present, attach it to the FS */  if (r->user)    {      svn_fs_access_t *access_ctx;      /* The fs is cached in connection->pool, but the fs access         context lives in r->pool.  Because the username or token         could change on each request, we need to make sure that the         fs points to a NULL access context after the request is gone. */      cleanup_baton = apr_pcalloc(r->pool, sizeof(*cleanup_baton));      cleanup_baton->pool = r->pool;      cleanup_baton->fs = repos->fs;            apr_pool_cleanup_register(r->pool, cleanup_baton, cleanup_fs_access,                                apr_pool_cleanup_null);                  /* Create an access context based on the authenticated username. */      serr = svn_fs_create_access(&access_ctx, r->user, r->pool);      if (serr)        {          return dav_svn__sanitize_error(serr,                                         "Could not create fs access context",                                         HTTP_INTERNAL_SERVER_ERROR, r);        }      /* Attach the access context to the fs. */      serr = svn_fs_set_access(repos->fs, access_ctx);      if (serr)        {          return dav_svn__sanitize_error(serr, "Could not attach access "                                         "context to fs",                                         HTTP_INTERNAL_SERVER_ERROR, r);        }    }  /* Look for locktokens in the "If:" request header. */  err = dav_get_locktoken_list(r, &ltl);    /* dav_get_locktoken_list claims to return a NULL list when no     locktokens are present.  But it actually throws this error     instead!  So we're deliberately trapping/ignoring it.      This is a workaround for a bug in mod_dav.  Remove this when the     bug is fixed in mod_dav.  See Subversion Issue #2248 */  if (err && (err->error_id != DAV_ERR_IF_ABSENT))    return err;  /* If one or more locktokens are present in the header, push them     into the filesystem access context. */  if (ltl)    {      svn_fs_access_t *access_ctx;      dav_locktoken_list *list = ltl;      serr = svn_fs_get_access(&access_ctx, repos->fs);      if (serr)        {          return dav_svn__sanitize_error(serr, "Lock token is in request, "                                         "but no user name",                                         HTTP_BAD_REQUEST, r);        }      do {        serr = svn_fs_access_add_lock_token(access_ctx,                                            list->locktoken->uuid_str);        if (serr)          return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,                                     "Error pushing token into filesystem.",                                     r->pool);        list = list->next;      } while (list);    }  /* Figure out the type of the resource. Note that we have a PARSE step     which is separate from a PREP step. This is because the PARSE can     map multiple URLs to the same resource type. The PREP operates on     the type of the resource. */  /* skip over the leading "/" in the relative URI */  if (dav_svn_parse_uri(comb, relative + 1, label, use_checked_in))    goto malformed_URI;#ifdef SVN_DEBUG  if (comb->res.type == DAV_RESOURCE_TYPE_UNKNOWN)    {      /* Unknown URI. Return NULL to indicate "no resource" */      DBG0("DESIGN FAILURE: should not be UNKNOWN at this point");      *resource = NULL;      return NULL;    }#endif  /* prepare the resource for operation */  if ((err = dav_svn_prep_resource(comb)) != NULL)    return err;  /* a GET request for a REGULAR collection resource MUST have a trailing     slash. Redirect to include one if it does not. */  if (comb->res.collection && comb->res.type == DAV_RESOURCE_TYPE_REGULAR      && !had_slash && r->method_number == M_GET)    {      /* note that we drop r->args. we don't deal with them anyways */      const char *new_path = apr_pstrcat(r->pool,                                         ap_escape_uri(r->pool, r->uri),                                         "/",                                         NULL);      apr_table_setn(r->headers_out, "Location",                     ap_construct_url(r->pool, new_path, r));      return dav_new_error(r->pool, HTTP_MOVED_PERMANENTLY, 0,                           "Requests for a collection must have a "                           "trailing slash on the URI.");    }  *resource = &comb->res;  return NULL; malformed_URI:  /* A malformed URI error occurs when a URI indicates the "special" area,     yet it has an improper construction. Generally, this is because some     doofus typed it in manually or has a buggy client. */  /* ### pick something other than HTTP_INTERNAL_SERVER_ERROR */  /* ### are SVN_ERR_APMOD codes within the right numeric space? */  return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR,                       SVN_ERR_APMOD_MALFORMED_URI,                       "The URI indicated a resource within Subversion's "                       "special resource area, but does not exist. This is "                       "generally caused by a problem in the client "                       "software.");}/* Helper func:  return the parent of PATH, allocated in POOL. */static const char *get_parent_path(const char *path,                                   apr_pool_t *pool){  apr_size_t len;  const char *parentpath, *base_name;  char *tmp = apr_pstrdup(pool, path);  len = strlen(tmp);  if (len > 0)    {      /* Remove any trailing slash; else svn_path_split() asserts. */      if (tmp[len-1] == '/')        tmp[len-1] = '\0';            svn_path_split(tmp, &parentpath, &base_name, pool);      return parentpath;    }    return path;}static dav_error * dav_svn_get_parent_resource(const dav_resource *resource,                                               dav_resource **parent_resource){  dav_resource *parent;  dav_resource_private *parentinfo;  svn_stringbuf_t *path = resource->info->uri_path;  /* the root of the repository has no parent */  if (path->len == 1 && *path->data == '/')    {      *parent_resource = NULL;      return NULL;    }  switch (resource->type)    {    case DAV_RESOURCE_TYPE_REGULAR:      parent = apr_pcalloc(resource->pool, sizeof(*parent));      parentinfo  = apr_pcalloc(resource->pool, sizeof(*parentinfo));      parent->type = DAV_RESOURCE_TYPE_REGULAR;      parent->exists = 1;      parent->collection = 1;      parent->versioned = 1;      parent->hooks = resource->hooks;      parent->pool = resource->pool;      parent->uri = get_parent_path(resource->uri, resource->pool);      parent->info = parentinfo;      parentinfo->pool = resource->info->pool;      parentinfo->uri_path =         svn_stringbuf_create(get_parent_path(resource->info->uri_path->data,                                             resource->pool), resource->pool);      parentinfo->repos = resource->info->repos;      parentinfo->root = resource->info->root;      parentinfo->r = resource->info->r;      parentinfo->svn_client_options = resource->info->svn_client_options;      parentinfo->repos_path = get_parent_path(resource->info->repos_path,                                               resource->pool);      *parent_resource = parent;      break;    case DAV_RESOURCE_TYPE_WORKING:      /* The "/" occurring within the URL of working resources is part of         its identifier; it does not establish parent resource relationships.         All working resources have the same parent, which is:         http://host.name/path2repos/$svn/wrk/      */      *parent_resource =        dav_svn_create_private_resource(resource,                                        DAV_SVN_RESTYPE_WRK_COLLECTION);      break;    case DAV_RESOURCE_TYPE_ACTIVITY:      *parent_resource =        dav_svn_create_private_resource(resource,                                        DAV_SVN_RESTYPE_ACT_COLLECTION);      break;    default:      /* ### needs more work. need parents for other resource types         ###         ### return an error so we can easily identify the cases where         ### we've called this function unexpectedly. */      return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,                           apr_psprintf(resource->pool,                                        "get_parent_resource was called for "                                        "%s (type %d)",                                        resource->uri, resource->type));      break;    }  return NULL;}/* does RES2 live in the same repository as RES1? */static int is_our_resource(const dav_resource *res1,                           const dav_resource *res2){  if (res1->hooks != res2->hooks      || strcmp(res1->info->repos->fs_path, res2->info->repos->fs_path) != 0)    {      /* a different provider, or a different FS repository */      return 0;    }  /* coalesce the repository */  if (res1->info->repos != res2->info->repos)    {            /* ### might be nice to have a pool which we can clear to toss         ### out the old, redundant repos/fs.  */      /* have res2 point to res1's filesystem */      res2->info->repos = res1->info->repos;      /* res2's fs_root object is now invalid.  regenerate it using         the now-shared filesystem. */      if (res2->info->root.txn_name)        {          /* reopen the txn by name */          svn_error_clear(svn_fs_open_txn(&(res2->info->root.txn),                                          res2->info->repos->fs,                                          res2->info->root.txn_name,                                          res2->info->repos->pool));          /* regenerate the txn "root" object */          svn_error_clear(svn_fs_txn_root(&(res2->info->root.root),                                          res2->info->root.txn,                                          res2->info->repos->pool));        }      else if (res2->info->root.rev)        {          /* default:  regenerate the revision "root" object */          svn_error_clear(svn_fs_revision_root(&(res2->info->root.root),                                               res2->info->repos->fs,                                               res2->info->root.rev,                                               res2->info->repos->pool));        }    }  return 1;}static int dav_svn_is_same_resource(const dav_resource *res1,                                    const dav_resource *res2){  if (!is_our_resource(res1, res2))    return 0;  /* ### what if the same resource were reached via two URIs? */  return svn_stringbuf_compare(res1->info->uri_path, res2->info->uri_path);}static int dav_svn_is_parent_resource(const dav_resource *res1,                                      const dav_resource *res2){  apr_size_t len1 = strlen(res1->info->uri_path->data);  apr_size_t len2;  if (!is_our_resource(res1, res2))    return 0;  /* ### what if a resource were reached via two URIs? we ought to define     ### parent/child relations for resources independent of URIs.     ### i.e. define a "canonical" location for each resource, then return     ### the parent based on that location. */  /* res2 is one of our resources, we can use its ->info ptr */  len2 = strlen(res2->info->uri_path->data);  return (len2 > len1          && memcmp(res1->info->uri_path->data, res2->info->uri_path->data,                    len1) == 0          && res2->info->uri_path->data[len1] == '/');}dav_error * dav_svn_resource_kind(request_rec *r,                                  const char *uri,                                  const char *root_path,                                  svn_node_kind_t *kind){  dav_error *derr;  svn_error_t *serr;  dav_resource *resource;  svn_revnum_t base_rev;  svn_fs_root_t *base_rev_root;  char *saved_uri;  /* Temporarily insert the uri that the user actually wants us to     convert into a resource.  Typically, this is already r->uri, so     this is usually a no-op.  But sometimes the caller may pass in     the Destination: header uri.     ### WHAT WE REALLY WANT here is to refactor dav_svn_get_resource,     so that some alternate interface actually allows us to specify     the URI to process, i.e. not always process r->uri.  */  saved_uri = r->uri;  r->uri = apr_pstrdup(r->pool, uri);   /* parse the uri and prep the associated resource. */  derr = dav_svn_get_resource(r, root_path,                              /* ### I can't believe that every single                                 parser ignores the LABEL and USE_CHECKED_IN                                 args below!! */                              "ignored_labe

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -