?? serf.c
字號(hào):
/* * serf.c : entry point for ra_serf * * ==================================================================== * Copyright (c) 2006 CollabNet. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals. For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#define APR_WANT_STRFUNC#include <apr_want.h>#include <apr_uri.h>#include <expat.h>#include <serf.h>#include "svn_pools.h"#include "svn_ra.h"#include "svn_dav.h"#include "svn_xml.h"#include "../libsvn_ra/ra_loader.h"#include "svn_config.h"#include "svn_delta.h"#include "svn_version.h"#include "svn_path.h"#include "svn_time.h"#include "svn_private_config.h"#include "ra_serf.h"static const svn_version_t *ra_serf_version(void){ SVN_VERSION_BODY;}#define RA_SERF_DESCRIPTION \ N_("Access repository via WebDAV protocol through serf.")static const char *ra_serf_get_description(void){ return _(RA_SERF_DESCRIPTION);}static const char * const *ra_serf_get_schemes(apr_pool_t *pool){ static const char *serf_ssl[] = { "http", "https", NULL };#if 0 /* ### Temporary: to shut up a warning. */ static const char *serf_no_ssl[] = { "http", NULL };#endif /* TODO: Runtime detection. */ return serf_ssl;}static svn_error_t *load_config(svn_ra_serf__session_t *session, apr_hash_t *config_hash, apr_pool_t *pool){ svn_config_t *config; const char *server_group; config = apr_hash_get(config_hash, SVN_CONFIG_CATEGORY_SERVERS, APR_HASH_KEY_STRING); SVN_ERR(svn_config_get_bool(config, &session->using_compression, SVN_CONFIG_SECTION_GLOBAL, SVN_CONFIG_OPTION_HTTP_COMPRESSION, TRUE)); server_group = svn_config_find_group(config, session->repos_url.hostname, SVN_CONFIG_SECTION_GROUPS, pool); if (server_group) { SVN_ERR(svn_config_get_bool(config, &session->using_compression, server_group, SVN_CONFIG_OPTION_HTTP_COMPRESSION, session->using_compression)); } return SVN_NO_ERROR;}static svn_error_t *svn_ra_serf__open(svn_ra_session_t *session, const char *repos_URL, const svn_ra_callbacks2_t *callbacks, void *callback_baton, apr_hash_t *config, apr_pool_t *pool){ apr_status_t status; svn_ra_serf__session_t *serf_sess; apr_uri_t url; serf_sess = apr_pcalloc(pool, sizeof(*serf_sess)); apr_pool_create(&serf_sess->pool, pool); serf_sess->bkt_alloc = serf_bucket_allocator_create(serf_sess->pool, NULL, NULL); serf_sess->cached_props = apr_hash_make(pool); serf_sess->wc_callbacks = callbacks; serf_sess->wc_callback_baton = callback_baton; /* todo: reuse serf context across sessions */ serf_sess->context = serf_context_create(pool); apr_uri_parse(serf_sess->pool, repos_URL, &url); serf_sess->repos_url = url; serf_sess->repos_url_str = apr_pstrdup(serf_sess->pool, repos_URL); if (!url.port) { url.port = apr_uri_port_of_scheme(url.scheme); } serf_sess->using_ssl = (strcasecmp(url.scheme, "https") == 0); SVN_ERR(load_config(serf_sess, config, pool)); /* register cleanups */ apr_pool_cleanup_register(serf_sess->pool, serf_sess, svn_ra_serf__cleanup_serf_session, apr_pool_cleanup_null); serf_sess->conns = apr_palloc(pool, sizeof(*serf_sess->conns) * 4); serf_sess->conns[0] = apr_pcalloc(pool, sizeof(*serf_sess->conns[0])); serf_sess->conns[0]->bkt_alloc = serf_bucket_allocator_create(serf_sess->pool, NULL, NULL); /* fetch the DNS record for this host */ status = apr_sockaddr_info_get(&serf_sess->conns[0]->address, url.hostname, APR_UNSPEC, url.port, 0, pool); if (status) { return svn_error_createf(status, NULL, _("Could not lookup hostname: %s://%s"), url.scheme, url.hostname); } serf_sess->conns[0]->using_ssl = serf_sess->using_ssl; serf_sess->conns[0]->using_compression = serf_sess->using_compression; serf_sess->conns[0]->hostinfo = url.hostinfo; /* go ahead and tell serf about the connection. */ serf_sess->conns[0]->conn = serf_connection_create(serf_sess->context, serf_sess->conns[0]->address, svn_ra_serf__conn_setup, serf_sess->conns[0], svn_ra_serf__conn_closed, serf_sess->conns[0], serf_sess->pool); serf_sess->num_conns = 1; session->priv = serf_sess; return SVN_NO_ERROR;}static svn_error_t *svn_ra_serf__reparent(svn_ra_session_t *ra_session, const char *url, apr_pool_t *pool){ svn_ra_serf__session_t *session = ra_session->priv; apr_uri_t new_url; /* If it's the URL we already have, wave our hands and do nothing. */ if (strcmp(session->repos_url_str, url) == 0) { return SVN_NO_ERROR; } /* Do we need to check that it's the same host and port? */ apr_uri_parse(session->pool, url, &new_url); session->repos_url.path = new_url.path; session->repos_url_str = apr_pstrdup(pool, url); return SVN_NO_ERROR;}static svn_error_t *svn_ra_serf__get_latest_revnum(svn_ra_session_t *ra_session, svn_revnum_t *latest_revnum, apr_pool_t *pool){ apr_hash_t *props; svn_ra_serf__session_t *session = ra_session->priv; const char *vcc_url, *baseline_url, *version_name; props = apr_hash_make(pool); SVN_ERR(svn_ra_serf__discover_root(&vcc_url, NULL, session, session->conns[0], session->repos_url.path, pool)); if (!vcc_url) { abort(); } /* Using the version-controlled-configuration, fetch the checked-in prop. */ SVN_ERR(svn_ra_serf__retrieve_props(props, session, session->conns[0], vcc_url, SVN_INVALID_REVNUM, "0", checked_in_props, pool)); baseline_url = svn_ra_serf__get_prop(props, vcc_url, "DAV:", "checked-in"); if (!baseline_url) { abort(); } /* Using the checked-in property, fetch: * baseline-connection *and* version-name */ SVN_ERR(svn_ra_serf__retrieve_props(props, session, session->conns[0], baseline_url, SVN_INVALID_REVNUM, "0", baseline_props, pool)); version_name = svn_ra_serf__get_prop(props, baseline_url, "DAV:", "version-name"); if (!version_name) { abort(); } *latest_revnum = SVN_STR_TO_REV(version_name); return SVN_NO_ERROR;}static svn_error_t *svn_ra_serf__rev_proplist(svn_ra_session_t *ra_session, svn_revnum_t rev, apr_hash_t **ret_props, apr_pool_t *pool){ svn_ra_serf__session_t *session = ra_session->priv; apr_hash_t *props; const char *vcc_url; props = apr_hash_make(pool); *ret_props = apr_hash_make(pool); SVN_ERR(svn_ra_serf__discover_root(&vcc_url, NULL, session, session->conns[0], session->repos_url.path, pool)); SVN_ERR(svn_ra_serf__retrieve_props(props, session, session->conns[0], vcc_url, rev, "0", all_props, pool)); svn_ra_serf__walk_all_props(props, vcc_url, rev, svn_ra_serf__set_bare_props, *ret_props, pool); return SVN_NO_ERROR;}static svn_error_t *svn_ra_serf__rev_prop(svn_ra_session_t *session, svn_revnum_t rev, const char *name, svn_string_t **value, apr_pool_t *pool){ apr_hash_t *props; SVN_ERR(svn_ra_serf__rev_proplist(session, rev, &props, pool)); *value = apr_hash_get(props, name, APR_HASH_KEY_STRING); return SVN_NO_ERROR;}static svn_error_t *fetch_path_props(svn_ra_serf__propfind_context_t **ret_prop_ctx, apr_hash_t **ret_props, const char **ret_path, svn_revnum_t *ret_revision, svn_ra_serf__session_t *session, const char *rel_path, svn_revnum_t revision, const svn_ra_serf__dav_props_t *desired_props, apr_pool_t *pool){ svn_ra_serf__propfind_context_t *prop_ctx; apr_hash_t *props; const char *path; path = session->repos_url.path; /* If we have a relative path, append it. */ if (rel_path) { path = svn_path_url_add_component(path, rel_path, pool); } props = apr_hash_make(pool); prop_ctx = NULL; /* If we were given a specific revision, we have to fetch the VCC and * do a PROPFIND off of that. */ if (!SVN_IS_VALID_REVNUM(revision)) { svn_ra_serf__deliver_props(&prop_ctx, props, session, session->conns[0], path, revision, "0", desired_props, TRUE, NULL, session->pool); } else { const char *vcc_url, *relative_url, *basecoll_url; SVN_ERR(svn_ra_serf__discover_root(&vcc_url, &relative_url, session, session->conns[0], path, pool)); SVN_ERR(svn_ra_serf__retrieve_props(props, session, session->conns[0], vcc_url, revision, "0", baseline_props, pool)); basecoll_url = svn_ra_serf__get_ver_prop(props, vcc_url, revision, "DAV:", "baseline-collection"); if (!basecoll_url) { abort(); } /* We will try again with our new path; however, we're now * technically an unversioned resource because we are accessing * the revision's baseline-collection. */ prop_ctx = NULL; path = svn_path_url_add_component(basecoll_url, relative_url, pool); revision = SVN_INVALID_REVNUM; svn_ra_serf__deliver_props(&prop_ctx, props, session, session->conns[0], path, revision, "0", desired_props, TRUE, NULL, session->pool); } SVN_ERR(svn_ra_serf__wait_for_props(prop_ctx, session, pool)); *ret_path = path; *ret_prop_ctx = prop_ctx; *ret_props = props; *ret_revision = revision; return SVN_NO_ERROR;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -