Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/mod_dav_svn/repos.c view on Meta::CPAN
*cp++ = '\0'; /* Delimit var */
while (*cp && (svn_ctype_isspace(*cp) || *cp == '='))
{
++cp;
}
if (*cp == '"')
{
++cp;
for (end = cp;
(*end && *end != '\n' && *end != '\r' && *end != '\"');
end++);
}
else
{
for (end = cp; (*end && !svn_ctype_isspace(*end)); end++);
}
if (*end)
{
*end = '\0'; /* strip ending quote or return */
}
ap_str_tolower(cp);
if (parm[0] == 'q'
&& (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0')))
{
result->quality = (float) atof(cp);
}
}
if (*accept_line == ',')
{
++accept_line;
}
return accept_line;
}
/* @a accept_line is the Accept-Encoding header, which is of the
format:
Accept-Encoding: name; q=N;
This function will return an array of accept_rec structures that
contain the accepted encodings and the quality each one has
associated with them.
*/
static apr_array_header_t *do_header_line(apr_pool_t *p,
const char *accept_line)
{
apr_array_header_t *accept_recs;
if (!accept_line)
return NULL;
accept_recs = apr_array_make(p, 10, sizeof(accept_rec));
while (*accept_line)
{
accept_rec *prefs = (accept_rec *) apr_array_push(accept_recs);
accept_line = get_entry(p, prefs, accept_line);
}
return accept_recs;
}
/* ---------------------------------------------------------------------- */
/* qsort comparison function for the quality field of the accept_rec
structure */
static int sort_encoding_pref(const void *accept_rec1, const void *accept_rec2)
{
float diff = ((const accept_rec *) accept_rec1)->quality -
((const accept_rec *) accept_rec2)->quality;
return (diff == 0 ? 0 : (diff > 0 ? -1 : 1));
}
/* Parse and handle any possible Accept-Encoding header that has been
sent as part of the request. */
static void
negotiate_encoding_prefs(request_rec *r, int *svndiff_version)
{
/* It would be nice if mod_negotiation
<http://httpd.apache.org/docs-2.1/mod/mod_negotiation.html> could
handle the Accept-Encoding header parsing for us. Sadly, it
looks like its data structures and routines are private (see
httpd/modules/mappers/mod_negotiation.c). Thus, we duplicate the
necessary ones in this file. */
int i;
const apr_array_header_t *encoding_prefs;
encoding_prefs = do_header_line(r->pool,
apr_table_get(r->headers_in,
"Accept-Encoding"));
if (!encoding_prefs || apr_is_empty_array(encoding_prefs))
{
*svndiff_version = 0;
return;
}
*svndiff_version = 0;
qsort(encoding_prefs->elts, (size_t) encoding_prefs->nelts,
sizeof(accept_rec), sort_encoding_pref);
for (i = 0; i < encoding_prefs->nelts; i++)
{
struct accept_rec rec = APR_ARRAY_IDX(encoding_prefs, i,
struct accept_rec);
if (strcmp(rec.name, "svndiff1") == 0)
{
*svndiff_version = 1;
break;
}
else if (strcmp(rec.name, "svndiff") == 0)
{
*svndiff_version = 0;
break;
}
}
}
/* The only two possible values for a capability. */
static const char *capability_yes = "yes";
static const char *capability_no = "no";
/* Convert CAPABILITIES, a hash table mapping 'const char *' keys to
* "yes" or "no" values, to a list of all keys whose value is "yes".
* Return the list, allocated in POOL, and use POOL for all temporary
* allocation.
*/
static apr_array_header_t *
capabilities_as_list(apr_hash_t *capabilities, apr_pool_t *pool)
{
apr_array_header_t *list = apr_array_make(pool, apr_hash_count(capabilities),
sizeof(char *));
apr_hash_index_t *hi;
for (hi = apr_hash_first(pool, capabilities); hi; hi = apr_hash_next(hi))
{
const void *key;
void *val;
apr_hash_this(hi, &key, NULL, &val);
if (strcmp((const char *) val, "yes") == 0)
APR_ARRAY_PUSH(list, const char *) = key;
}
return list;
}
/* Given a non-NULL QUERY string of the form "key1=val1&key2=val2&...",
* parse the keys and values into an apr table. Allocate the table in
* POOL; dup all keys and values into POOL as well.
*
* Note that repeating the same key will cause table overwrites
* (e.g. "r=3&r=5"), and that a lack of value ("p=") is legal, but
* equivalent to not specifying the key at all.
*/
static apr_table_t *
querystring_to_table(const char *query, apr_pool_t *pool)
{
apr_table_t *table = apr_table_make(pool, 2);
apr_array_header_t *array = svn_cstring_split(query, "&", TRUE, pool);
int i;
for (i = 0; i < array->nelts; i++)
{
src/subversion/subversion/mod_dav_svn/repos.c view on Meta::CPAN
/* Marshall the error back to the client by generating by
* way of the dav_svn__error_response_tag trick. */
err = dav_svn__new_error(r->pool, HTTP_METHOD_NOT_ALLOWED,
SVN_ERR_APMOD_MALFORMED_URI,
"The URI does not contain the name "
"of a repository.");
/* can't use r->allowed since the default handler isn't called */
apr_table_setn(r->headers_out, "Allow", "GET,HEAD");
status = dav_svn__error_response_tag(r, err);
return dav_push_error(r->pool, status, err->error_id, NULL, err);
}
err = get_parentpath_resource(r, resource);
if (err)
return err;
return NULL;
}
/* This does all the work of interpreting/splitting the request uri. */
err = dav_svn_split_uri(r, r->uri, root_path,
&cleaned_uri, &had_slash,
&repo_basename, &relative, &repos_path);
if (err)
return err;
/* The path that we will eventually try to open as an svn
repository. Normally defined by the SVNPath directive. */
fs_path = dav_svn__get_fs_path(r);
/* If the SVNParentPath directive was used instead... */
if (fs_parent_path != NULL)
{
/* ...then the URL to the repository is actually one implicit
component longer... */
root_path = svn_urlpath__join(root_path, repo_basename, r->pool);
/* ...and we need to specify exactly what repository to open. */
fs_path = svn_dirent_join(fs_parent_path, repo_basename, r->pool);
}
/* Start building and filling a 'combination' object. */
comb = apr_pcalloc(r->pool, sizeof(*comb));
comb->res.info = &comb->priv;
comb->res.hooks = &dav_svn__hooks_repository;
comb->res.pool = r->pool;
comb->res.uri = cleaned_uri;
/* Original request, off which to generate subrequests later. */
comb->priv.r = r;
/* ### ugly hack to carry over Content-Type data to the open_stream, which
### does not have access to the request headers. */
{
const char *ct = apr_table_get(r->headers_in, "content-type");
comb->priv.is_svndiff =
ct != NULL
&& strcmp(ct, SVN_SVNDIFF_MIME_TYPE) == 0;
}
negotiate_encoding_prefs(r, &comb->priv.svndiff_version);
/* ### and another hack for computing diffs to send to the client */
comb->priv.delta_base = apr_table_get(r->headers_in,
SVN_DAV_DELTA_BASE_HEADER);
/* Gather any options requested by an svn client. */
comb->priv.svn_client_options = apr_table_get(r->headers_in,
SVN_DAV_OPTIONS_HEADER);
/* See if the client sent a custom 'version name' request header. */
version_name = apr_table_get(r->headers_in, SVN_DAV_VERSION_NAME_HEADER);
comb->priv.version_name
= version_name ? SVN_STR_TO_REV(version_name): SVN_INVALID_REVNUM;
/* Remember checksums, if any. */
comb->priv.base_checksum =
apr_table_get(r->headers_in, SVN_DAV_BASE_FULLTEXT_MD5_HEADER);
comb->priv.result_checksum =
apr_table_get(r->headers_in, SVN_DAV_RESULT_FULLTEXT_MD5_HEADER);
/* "relative" is part of the "uri" string, so it has the proper
lifetime to store here. */
/* ### that comment no longer applies. we're creating a string with its
### own lifetime now. so WHY are we using a string? hmm... */
comb->priv.uri_path = svn_stringbuf_create(relative, r->pool);
/* initialize this until we put something real here */
comb->priv.root.rev = SVN_INVALID_REVNUM;
/* create the repository structure and stash it away */
repos = apr_pcalloc(r->pool, sizeof(*repos));
repos->pool = r->pool;
comb->priv.repos = repos;
/* We are assuming the root_path will live at least as long as this
resource. Considering that it typically comes from the per-dir
config in mod_dav, this is valid for now. */
repos->root_path = svn_path_uri_encode(root_path, r->pool);
/* where is the SVN FS for this resource? */
repos->fs_path = fs_path;
/* A name for the repository */
repos->repo_name = repo_name;
/* The repository filesystem basename */
repos->repo_basename = repo_basename;
/* An XSL transformation */
repos->xslt_uri = xslt_uri;
/* Is autoversioning active in this repos? */
repos->autoversioning = dav_svn__get_autoversioning_flag(r);
/* Are bulk updates allowed in this repos? */
repos->bulk_updates = dav_svn__get_bulk_updates_flag(r);
/* Are we advertising HTTP v2 protocol support? */
repos->v2_protocol = dav_svn__check_httpv2_support(r);
( run in 2.131 seconds using v1.01-cache-2.11-cpan-0bb4e1dffa6 )