Win32: fix an incorrect error status being propagated to the caller in case
[svn/apache.git] / subversion / mod_dav_svn / dav_svn.h
blob34efccb129b0469df4bc529d59c00668330df9d3
1 /*
2 * dav_svn.h: types, functions, macros for the DAV/SVN Apache module
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
20 * under the License.
21 * ====================================================================
24 #ifndef DAV_SVN_H
25 #define DAV_SVN_H
27 #include <apr_tables.h>
28 #include <apr_xml.h>
30 #include <httpd.h>
31 #include <http_log.h>
32 #include <mod_dav.h>
34 #include "svn_error.h"
35 #include "svn_fs.h"
36 #include "svn_repos.h"
37 #include "svn_path.h"
38 #include "svn_xml.h"
39 #include "private/svn_dav_protocol.h"
40 #include "private/svn_skel.h"
41 #include "mod_authz_svn.h"
43 #ifdef __cplusplus
44 extern "C" {
45 #endif /* __cplusplus */
49 /* what the one VCC is called */
50 #define DAV_SVN__DEFAULT_VCC_NAME "default"
52 /* a pool-key for the shared dav_svn_root used by autoversioning */
53 #define DAV_SVN__AUTOVERSIONING_ACTIVITY "svn-autoversioning-activity"
55 /* Option values for SVNAllowBulkUpdates. Note that
56 it's important that CONF_BULKUPD_DEFAULT is 0 to make
57 merge_dir_config in mod_dav_svn do the right thing. */
58 typedef enum dav_svn__bulk_upd_conf {
59 CONF_BULKUPD_DEFAULT,
60 CONF_BULKUPD_ON,
61 CONF_BULKUPD_OFF,
62 CONF_BULKUPD_PREFER
63 } dav_svn__bulk_upd_conf;
65 /* dav_svn_repos
67 * Record information about the repository that a resource belongs to.
68 * This structure will be shared between multiple resources so that we
69 * can optimized our FS access.
71 * Note that we do not refcount this structure. Presumably, we will need
72 * it throughout the life of the request. Therefore, we can just leave it
73 * for the request pool to cleanup/close.
75 * Also, note that it is possible that two resources may have distinct
76 * dav_svn_repos structures, yet refer to the same repository. This is
77 * allowed by the SVN FS interface.
79 * ### should we attempt to merge them when we detect this situation in
80 * ### places like is_same_resource, is_parent_resource, or copy/move?
81 * ### I say yes: the FS will certainly have an easier time if there is
82 * ### only a single FS open; otherwise, it will have to work a bit harder
83 * ### to keep the things in sync.
85 typedef struct dav_svn_repos {
86 apr_pool_t *pool; /* request_rec -> pool */
88 /* Remember the root URL path of this repository (just a path; no
89 scheme, host, or port).
91 Example: the URI is "http://host/repos/file", this will be "/repos".
93 This always starts with "/", and if there are any components
94 beyond that, then it does not end with "/".
96 const char *root_path;
98 /* Remember an absolute URL for constructing other URLs. In the above
99 example, this would be "http://host" (note: no trailing slash)
101 const char *base_url;
103 /* Remember the special URI component for this repository */
104 const char *special_uri;
106 /* This records the filesystem path to the SVN FS */
107 const char *fs_path;
109 /* The name of this repository */
110 const char *repo_name;
112 /* The repository filesystem basename */
113 const char *repo_basename;
115 /* The URI of the XSL transform for directory indexes */
116 const char *xslt_uri;
118 /* Whether autoversioning is active for this repository. */
119 svn_boolean_t autoversioning;
121 /* Whether bulk updates are allowed for this repository. */
122 dav_svn__bulk_upd_conf bulk_updates;
124 /* Whether HTTP protocol version 2 is allowed to be used. */
125 svn_boolean_t v2_protocol;
127 /* the open repository */
128 svn_repos_t *repos;
130 /* a cached copy of REPOS->fs above. */
131 svn_fs_t *fs;
133 /* the user operating against this repository */
134 const char *username;
136 /* is the client a Subversion client? */
137 svn_boolean_t is_svn_client;
139 /* The client's capabilities. Maps SVN_RA_CAPABILITY_* keys to
140 "yes" or "no" values. If a capability is not yet discovered, it
141 is absent from the table. The table itself is allocated in this
142 structure's 'pool' field, and the keys and values must have at
143 least that lifetime. Most likely the keys and values are
144 constants anyway (and sufficiently well-informed internal code
145 may therefore compare against those constants' addresses). If
146 'is_svn_client' is false, then 'capabilities' should be empty. */
147 apr_hash_t *client_capabilities;
149 /* The path to the activities db */
150 const char *activities_db;
152 /* Cached yongest revision of the repository. SVN_INVALID_REVNUM if
153 youngest revision is not fetched yet. */
154 svn_revnum_t youngest_rev;
155 } dav_svn_repos;
159 ** dav_svn_private_restype: identifiers for our different private resources
161 ** There are some resources within mod_dav_svn that are "privately defined".
162 ** This isn't so much to prevent other people from knowing what they are,
163 ** but merely that mod_dav doesn't have a standard name for them.
165 enum dav_svn_private_restype {
166 DAV_SVN_RESTYPE_UNSET,
168 DAV_SVN_RESTYPE_ROOT_COLLECTION, /* .../!svn/ */
169 DAV_SVN_RESTYPE_VER_COLLECTION, /* .../!svn/ver/ */
170 DAV_SVN_RESTYPE_HIS_COLLECTION, /* .../!svn/his/ */
171 DAV_SVN_RESTYPE_WRK_COLLECTION, /* .../!svn/wrk/ */
172 DAV_SVN_RESTYPE_ACT_COLLECTION, /* .../!svn/act/ */
173 DAV_SVN_RESTYPE_VCC_COLLECTION, /* .../!svn/vcc/ */
174 DAV_SVN_RESTYPE_BC_COLLECTION, /* .../!svn/bc/ */
175 DAV_SVN_RESTYPE_BLN_COLLECTION, /* .../!svn/bln/ */
176 DAV_SVN_RESTYPE_WBL_COLLECTION, /* .../!svn/wbl/ */
177 DAV_SVN_RESTYPE_VCC, /* .../!svn/vcc/NAME */
178 DAV_SVN_RESTYPE_PARENTPATH_COLLECTION,/* see SVNParentPath directive */
180 /* new types in HTTP protocol v2: */
181 DAV_SVN_RESTYPE_ME, /* .../!svn/me */
182 DAV_SVN_RESTYPE_REV_COLLECTION, /* .../!svn/rev/ */
183 DAV_SVN_RESTYPE_REVROOT_COLLECTION, /* .../!svn/rvr/ */
184 DAV_SVN_RESTYPE_TXN_COLLECTION, /* .../!svn/txn/ */
185 DAV_SVN_RESTYPE_TXNROOT_COLLECTION /* .../!svn/txr/ */
189 /* store info about a root in a repository */
190 typedef struct dav_svn_root {
191 /* If a root within the FS has been opened, the value is stored here.
192 Otherwise, this field is NULL. */
193 svn_fs_root_t *root;
195 /* If the root has been opened, and it was opened for a specific revision,
196 then it is contained in REV. If the root is unopened or corresponds to
197 a transaction, then REV will be SVN_INVALID_REVNUM. */
198 svn_revnum_t rev;
200 /* If this resource is an activity or part of an activity, this specifies
201 the ID of that activity. It may not (yet) correspond to a transaction
202 in the FS.
204 WORKING and ACTIVITY resources use this field.
206 const char *activity_id;
208 /* If the root is part of a transaction, this contains the FS's tranaction
209 name. It may be NULL if this root corresponds to a specific revision.
210 It may also be NULL if we have not opened the root yet.
212 WORKING and ACTIVITY resources use this field, as well as PRIVATE
213 resources that directly represent either a txn or txn-root.
215 const char *txn_name;
217 /* The optional vtxn name supplied by an HTTPv2 client and
218 used in subsequent requests. This may be NULL if the client
219 is not using a vtxn name.
221 PRIVATE resources that directly represent either a txn or
222 txn-root use this field.
224 const char *vtxn_name;
226 /* If the root is part of a transaction, this contains the FS's transaction
227 handle. It may be NULL if this root corresponds to a specific revision.
228 It may also be NULL if we have not opened the transaction yet.
230 WORKING resources use this field.
232 svn_fs_txn_t *txn;
234 } dav_svn_root;
237 /* internal structure to hold information about this resource */
238 struct dav_resource_private {
239 /* Path from the SVN repository root to this resource. This value has
240 a leading slash. It will never have a trailing slash, even if the
241 resource represents a collection.
243 For example: URI is http://host/repos/file -- path will be "/file".
245 NOTE: this path is from the URI and does NOT necessarily correspond
246 to a path within the FS repository.
248 svn_stringbuf_t *uri_path;
250 /* The FS repository path to this resource, with a leading "/". Note
251 that this is "/" the root. This value will be NULL for resources
252 that have no corresponding resource within the repository (such as
253 the PRIVATE resources, Baselines, or Working Baselines). */
254 const char *repos_path;
256 /* the FS repository this resource is associated with */
257 dav_svn_repos *repos;
259 /* what FS root this resource occurs within */
260 dav_svn_root root;
262 /* for PRIVATE resources: the private resource type */
263 enum dav_svn_private_restype restype;
265 /* The request which created this resource. We need this to
266 generate subrequests. */
267 request_rec *r;
269 /* ### hack to deal with the Content-Type header on a PUT */
270 int is_svndiff;
272 /* ### record the base for computing a delta during a GET */
273 const char *delta_base;
275 /* SVNDIFF version we can transmit to the client. */
276 int svndiff_version;
278 /* the value of any SVN_DAV_OPTIONS_HEADER that came in the request */
279 const char *svn_client_options;
281 /* the revnum value from a possible SVN_DAV_VERSION_NAME_HEADER */
282 svn_revnum_t version_name;
284 /* Hex MD5 digests for base text and resultant fulltext.
285 Either or both of these may be null, in which case ignored. */
286 const char *base_checksum;
287 const char *result_checksum;
289 /* was this resource auto-checked-out? */
290 svn_boolean_t auto_checked_out;
292 /* was this resource fetched using our public peg-/working-rev CGI
293 interface (ie: /path/to/item?p=PEGREV)? */
294 svn_boolean_t pegged;
296 /* Cache any revprop change error */
297 svn_error_t *revprop_error;
299 /* was keyword substitution requested using our public CGI interface
300 (ie: /path/to/item?kw=1)? */
301 svn_boolean_t keyword_subst;
303 /* whether this resource parameters are fixed and won't change
304 between requests. */
305 svn_boolean_t idempotent;
309 /* Every provider needs to define an opaque locktoken type. */
310 struct dav_locktoken
312 /* This is identical to the 'token' field of an svn_lock_t. */
313 const char *uuid_str;
317 /* for the repository referred to by this request, where is the SVN FS? */
318 const char *dav_svn__get_fs_path(request_rec *r);
319 const char *dav_svn__get_fs_parent_path(request_rec *r);
321 /* for the repository referred to by this request, is autoversioning active? */
322 svn_boolean_t dav_svn__get_autoversioning_flag(request_rec *r);
324 /* for the repository referred to by this request, are bulk updates allowed? */
325 dav_svn__bulk_upd_conf dav_svn__get_bulk_updates_flag(request_rec *r);
327 /* for the repository referred to by this request, are subrequests active? */
328 svn_boolean_t dav_svn__get_pathauthz_flag(request_rec *r);
330 /* for the repository referred to by this request, is txdelta caching active? */
331 svn_boolean_t dav_svn__get_txdelta_cache_flag(request_rec *r);
333 /* for the repository referred to by this request, is fulltext caching active? */
334 svn_boolean_t dav_svn__get_fulltext_cache_flag(request_rec *r);
336 /* for the repository referred to by this request, is revprop caching active? */
337 svn_boolean_t dav_svn__get_revprop_cache_flag(request_rec *r);
339 /* for the repository referred to by this request, is node prop caching active? */
340 svn_boolean_t
341 dav_svn__get_nodeprop_cache_flag(request_rec *r);
343 /* has block read mode been enabled for the repository referred to by this
344 * request? */
345 svn_boolean_t dav_svn__get_block_read_flag(request_rec *r);
347 /* for the repository referred to by this request, are subrequests bypassed?
348 * A function pointer if yes, NULL if not.
350 authz_svn__subreq_bypass_func_t dav_svn__get_pathauthz_bypass(request_rec *r);
352 /* for the repository referred to by this request, is a GET of
353 SVNParentPath allowed? */
354 svn_boolean_t dav_svn__get_list_parentpath_flag(request_rec *r);
356 /* For the repository referred to by this request, should HTTPv2
357 protocol support be advertised? Note that this also takes into
358 account the support level expected of based on the specified
359 master server version (if provided via SVNMasterVersion). */
360 svn_boolean_t dav_svn__check_httpv2_support(request_rec *r);
364 /* SPECIAL URI
366 SVN needs to create many types of "pseudo resources" -- resources
367 that don't correspond to the users' files/directories in the
368 repository. Specifically, these are:
370 - working resources
371 - activities
372 - version resources
373 - version history resources
375 Each of these will be placed under a portion of the URL namespace
376 that defines the SVN repository. For example, let's say the user
377 has configured an SVN repository at http://host/svn/repos. The
378 special resources could be configured to live at .../!svn/ under
379 that repository. Thus, an activity might be located at
380 http://host/svn/repos/!svn/act/1234.
382 The special URI is configurable on a per-server basis and defaults
383 to "!svn".
385 NOTE: the special URI is RELATIVE to the "root" of the
386 repository. The root is generally available only to
387 dav_svn_get_resource(). This is okay, however, because we can cache
388 the root_dir when the resource structure is built.
391 /* Return the repo-root-relative URI of the special namespace to be used for
392 * this resource.
393 * Comes from the <SVNSpecialURI> directive. */
394 /* ### Is this assumed to be URI-encoded? */
395 const char *dav_svn__get_special_uri(request_rec *r);
397 /* Return a descriptive name for the repository.
398 * Comes from the <SVNReposName> directive. */
399 const char *dav_svn__get_repo_name(request_rec *r);
401 /* Return the server-relative URI of an XSL transform stylesheet.
402 Comes from the <SVNIndexXSLT> directive. */
403 /* ### Is this assumed to be URI-encoded? */
404 const char *dav_svn__get_xslt_uri(request_rec *r);
406 /* Return the full URL of the master repository (for mirroring).
407 Comes from the <SVNMasterURI> directive. */
408 /* ### Is this assumed to be URI-encoded? */
409 const char *dav_svn__get_master_uri(request_rec *r);
411 /* Return the version of the master server (used for mirroring) iff a
412 master URI is in place for this location; otherwise, return NULL.
413 Comes from the <SVNMasterVersion> directive. */
414 svn_version_t *dav_svn__get_master_version(request_rec *r);
416 /* Return the disk path to the activities db.
417 Comes from the <SVNActivitiesDB> directive. */
418 const char *dav_svn__get_activities_db(request_rec *r);
420 /* Return the server-relative URI of the repository root.
421 Comes from the <Location> directive. */
422 /* ### Is this assumed to be URI-encoded? */
423 const char *dav_svn__get_root_dir(request_rec *r);
425 /* Return the data compression level to be used over the wire. */
426 int dav_svn__get_compression_level(request_rec *r);
428 /* Return the hook script environment parsed from the configuration. */
429 const char *dav_svn__get_hooks_env(request_rec *r);
431 /** For HTTP protocol v2, these are the new URIs and URI stubs
432 returned to the client in our OPTIONS response. They all depend
433 on the 'special uri', which is configurable in httpd.conf. **/
435 /* Where REPORT requests are sent (typically "!svn/me") */
436 const char *dav_svn__get_me_resource_uri(request_rec *r);
438 /* For accessing revision resources (typically "!svn/rev") */
439 const char *dav_svn__get_rev_stub(request_rec *r);
441 /* For accessing REV/PATH pairs (typically "!svn/bc") */
442 const char *dav_svn__get_rev_root_stub(request_rec *r);
444 /* For accessing transaction resources (typically "!svn/txn") */
445 const char *dav_svn__get_txn_stub(request_rec *r);
447 /* For accessing transaction properties (typically "!svn/txr") */
448 const char *dav_svn__get_txn_root_stub(request_rec *r);
450 /* For accessing transaction resources (typically "!svn/vtxn") */
451 const char *dav_svn__get_vtxn_stub(request_rec *r);
453 /* For accessing transaction properties (typically "!svn/vtxr") */
454 const char *dav_svn__get_vtxn_root_stub(request_rec *r);
457 /*** Output helpers ***/
459 /* An opaque type which represents an output for a particular request.
461 All writes should target a dav_svn__output object by either using
462 the dav_svn__brigade functions or by preparing a bucket brigade and
463 passing it to the output with dav_svn__output_pass_brigade().
465 IMPORTANT: Don't write to an ap_filter_t coming from mod_dav, and
466 use this wrapper and the corresponding private API instead. Using
467 the ap_filter_t can cause unbounded memory usage with self-removing
468 output filters (e.g., with the filters installed by mod_headers or
469 mod_deflate).
471 See https://mail-archives.apache.org/mod_mbox/httpd-dev/201608.mbox/%3C20160822151917.GA22369%40redhat.com%3E
473 typedef struct dav_svn__output dav_svn__output;
475 /* Create the output wrapper for request R, allocated in POOL. */
476 dav_svn__output *
477 dav_svn__output_create(request_rec *r,
478 apr_pool_t *pool);
480 /* Get a bucket allocator to use for all bucket/brigade creations
481 when writing to OUTPUT. */
482 apr_bucket_alloc_t *
483 dav_svn__output_get_bucket_alloc(dav_svn__output *output);
485 /* Pass the bucket brigade BB down to the OUTPUT's filter stack. */
486 svn_error_t *
487 dav_svn__output_pass_brigade(dav_svn__output *output,
488 apr_bucket_brigade *bb);
491 /*** activity.c ***/
493 /* Create a new transaction based on HEAD in REPOS, setting *PTXN_NAME
494 to the name of that transaction. REVPROPS is an optional hash of
495 const char * property names and const svn_string_t * values which
496 will be set as transactions properties on the transaction this
497 function creates. Use POOL for allocations.
499 NOTE: This function will overwrite the svn:author property, if
500 any, found in REVPROPS. */
501 dav_error *
502 dav_svn__create_txn(dav_svn_repos *repos,
503 const char **ptxn_name,
504 apr_hash_t *revprops,
505 apr_pool_t *pool);
507 /* If it exists, abort the transaction named TXN_NAME from REPOS. Use
508 POOL for allocations. */
509 dav_error *
510 dav_svn__abort_txn(const dav_svn_repos *repos,
511 const char *txn_name,
512 apr_pool_t *pool);
514 /* Functions for looking up, storing, and deleting ACTIVITY->TXN mappings. */
515 const char *
516 dav_svn__get_txn(const dav_svn_repos *repos, const char *activity_id);
518 dav_error *
519 dav_svn__delete_activity(const dav_svn_repos *repos, const char *activity_id);
521 dav_error *
522 dav_svn__store_activity(const dav_svn_repos *repos,
523 const char *activity_id,
524 const char *txn_name);
527 /* POST request handler. (Used by HTTP protocol v2 clients only.) */
528 int dav_svn__method_post(request_rec *r);
530 /* Request handler to GET Subversion internal status (FSFS cache). */
531 int dav_svn__status(request_rec *r);
533 /*** repos.c ***/
535 /* generate an ETag for RESOURCE and return it, allocated in POOL. */
536 const char *
537 dav_svn__getetag(const dav_resource *resource, apr_pool_t *pool);
540 Construct a working resource for a given resource.
542 The internal information (repository, URL parts, etc) for the new
543 resource comes from BASE, the activity to use is specified by
544 ACTIVITY_ID, and the name of the transaction is specified by
545 TXN_NAME. These will be assembled into a new dav_resource and
546 returned.
548 If TWEAK_IN_PLACE is non-zero, then directly tweak BASE into a
549 working resource and return NULL.
551 dav_resource *
552 dav_svn__create_working_resource(dav_resource *base,
553 const char *activity_id,
554 const char *txn_name,
555 int tweak_in_place);
557 Convert a working RESOURCE back into a regular one, in-place.
559 In particular: change the resource type to regular, removing the
560 'working' flag, change the fs root from a txn-root to a rev-root,
561 and set the URL back into either a public URL or bc URL.
563 dav_error *
564 dav_svn__working_to_regular_resource(dav_resource *resource);
567 Given a version-resource URI, construct a new version-resource in
568 POOL and return it in *VERSION_RES.
570 dav_error *
571 dav_svn__create_version_resource(dav_resource **version_res,
572 const char *uri,
573 apr_pool_t *pool);
575 extern const dav_hooks_repository dav_svn__hooks_repository;
578 /*** deadprops.c ***/
579 extern const dav_hooks_propdb dav_svn__hooks_propdb;
582 /*** lock.c ***/
583 extern const dav_hooks_locks dav_svn__hooks_locks;
586 /*** version.c ***/
588 /* For an autoversioning commit, a helper function which attaches an
589 auto-generated 'svn:log' property to a txn, as well as a property
590 that indicates the revision was made via autoversioning. */
591 svn_error_t *
592 dav_svn__attach_auto_revprops(svn_fs_txn_t *txn,
593 const char *fs_path,
594 apr_pool_t *pool);
597 /* Hook function of types 'checkout' and 'checkin', as defined in
598 mod_dav.h's versioning provider hooks table (see dav_hooks_vsn). */
599 dav_error *
600 dav_svn__checkout(dav_resource *resource,
601 int auto_checkout,
602 int is_unreserved,
603 int is_fork_ok,
604 int create_activity,
605 apr_array_header_t *activities,
606 dav_resource **working_resource);
608 dav_error *
609 dav_svn__checkin(dav_resource *resource,
610 int keep_checked_out,
611 dav_resource **version_resource);
614 /* Helper for reading lock-tokens out of request bodies, by looking
615 for cached body in R->pool's userdata.
617 Return a hash that maps (const char *) absolute fs paths to (const
618 char *) locktokens. Allocate the hash and all keys/vals in POOL.
619 PATH_PREFIX is the prefix we need to prepend to each relative
620 'lock-path' in the xml in order to create an absolute fs-path. */
621 dav_error *
622 dav_svn__build_lock_hash(apr_hash_t **locks,
623 request_rec *r,
624 const char *path_prefix,
625 apr_pool_t *pool);
628 /* Helper: push all of the lock-tokens (hash values) in LOCKS into
629 RESOURCE's already-open svn_fs_t. */
630 dav_error *
631 dav_svn__push_locks(dav_resource *resource,
632 apr_hash_t *locks,
633 apr_pool_t *pool);
636 extern const dav_hooks_vsn dav_svn__hooks_vsn;
639 /*** liveprops.c ***/
641 extern const dav_liveprop_group dav_svn__liveprop_group;
644 LIVE PROPERTY HOOKS
646 These are standard hooks defined by mod_dav. We implement them to expose
647 various live properties on the resources under our control.
649 gather_propsets: appends URIs into the array; the property set URIs are
650 used to specify which sets of custom properties we
651 define/expose.
652 find_liveprop: given a namespace and name, return the hooks for the
653 provider who defines that property.
654 insert_all_liveprops: for a given resource, insert all of the live
655 properties defined on that resource. The properties
656 are inserted according to the WHAT parameter.
658 void dav_svn__gather_propsets(apr_array_header_t *uris);
661 dav_svn__find_liveprop(const dav_resource *resource,
662 const char *ns_uri,
663 const char *name,
664 const dav_hooks_liveprop **hooks);
666 void
667 dav_svn__insert_all_liveprops(request_rec *r,
668 const dav_resource *resource,
669 dav_prop_insert what,
670 apr_text_header *phdr);
673 /*** merge.c ***/
675 /* Generate the HTTP response body for a successful MERGE. */
676 /* ### more docco */
677 dav_error *
678 dav_svn__merge_response(dav_svn__output *output,
679 const dav_svn_repos *repos,
680 svn_revnum_t new_rev,
681 const char *post_commit_err,
682 apr_xml_elem *prop_elem,
683 svn_boolean_t disable_merge_response,
684 apr_pool_t *pool);
687 /*** reports/ ***/
689 /* The list of Subversion's custom REPORTs. */
690 /* ### should move these report names to a public header to share with
691 ### the client (and third parties). */
692 static const dav_report_elem dav_svn__reports_list[] = {
693 { SVN_XML_NAMESPACE, "update-report" },
694 { SVN_XML_NAMESPACE, "log-report" },
695 { SVN_XML_NAMESPACE, "dated-rev-report" },
696 { SVN_XML_NAMESPACE, "get-locations" },
697 { SVN_XML_NAMESPACE, "get-location-segments" },
698 { SVN_XML_NAMESPACE, "file-revs-report" },
699 { SVN_XML_NAMESPACE, "get-locks-report" },
700 { SVN_XML_NAMESPACE, "replay-report" },
701 { SVN_XML_NAMESPACE, "get-deleted-rev-report" },
702 { SVN_XML_NAMESPACE, SVN_DAV__MERGEINFO_REPORT },
703 { SVN_XML_NAMESPACE, SVN_DAV__INHERITED_PROPS_REPORT },
704 { SVN_XML_NAMESPACE, "list-report" },
705 { NULL, NULL },
709 /* The various report handlers, defined in reports/, and used by version.c. */
710 dav_error *
711 dav_svn__update_report(const dav_resource *resource,
712 const apr_xml_doc *doc,
713 dav_svn__output *output);
714 dav_error *
715 dav_svn__log_report(const dav_resource *resource,
716 const apr_xml_doc *doc,
717 dav_svn__output *output);
718 dav_error *
719 dav_svn__dated_rev_report(const dav_resource *resource,
720 const apr_xml_doc *doc,
721 dav_svn__output *output);
722 dav_error *
723 dav_svn__get_locations_report(const dav_resource *resource,
724 const apr_xml_doc *doc,
725 dav_svn__output *output);
726 dav_error *
727 dav_svn__get_location_segments_report(const dav_resource *resource,
728 const apr_xml_doc *doc,
729 dav_svn__output *output);
730 dav_error *
731 dav_svn__file_revs_report(const dav_resource *resource,
732 const apr_xml_doc *doc,
733 dav_svn__output *output);
734 dav_error *
735 dav_svn__replay_report(const dav_resource *resource,
736 const apr_xml_doc *doc,
737 dav_svn__output *output);
738 dav_error *
739 dav_svn__get_mergeinfo_report(const dav_resource *resource,
740 const apr_xml_doc *doc,
741 dav_svn__output *output);
742 dav_error *
743 dav_svn__get_locks_report(const dav_resource *resource,
744 const apr_xml_doc *doc,
745 dav_svn__output *output);
747 dav_error *
748 dav_svn__get_deleted_rev_report(const dav_resource *resource,
749 const apr_xml_doc *doc,
750 dav_svn__output *output);
752 dav_error *
753 dav_svn__get_inherited_props_report(const dav_resource *resource,
754 const apr_xml_doc *doc,
755 dav_svn__output *output);
757 dav_error *
758 dav_svn__list_report(const dav_resource *resource,
759 const apr_xml_doc *doc,
760 dav_svn__output *output);
762 /*** posts/ ***/
764 /* The various POST handlers, defined in posts/, and used by repos.c. */
765 dav_error *
766 dav_svn__post_create_txn(const dav_resource *resource,
767 svn_skel_t *request_skel,
768 dav_svn__output *output);
769 dav_error *
770 dav_svn__post_create_txn_with_props(const dav_resource *resource,
771 svn_skel_t *request_skel,
772 dav_svn__output *output);
774 /*** authz.c ***/
776 /* A baton needed by dav_svn__authz_read_func(). */
777 typedef struct dav_svn__authz_read_baton
779 /* The original request, needed to generate a subrequest. */
780 request_rec *r;
782 /* We need this to construct a URI based on a repository abs path. */
783 const dav_svn_repos *repos;
785 } dav_svn__authz_read_baton;
788 /* Return TRUE iff the current user (as determined by Apache's
789 authentication system) has permission to read PATH in REPOS at REV
790 (where an invalid REV means "HEAD"). This will invoke any authz
791 modules loaded into Apache unless this Subversion location has been
792 configured to bypass those in favor of a direct lookup in the
793 Subversion authz subsystem. Use POOL for any temporary allocation.
795 svn_boolean_t
796 dav_svn__allow_read(request_rec *r,
797 const dav_svn_repos *repos,
798 const char *path,
799 svn_revnum_t rev,
800 apr_pool_t *pool);
802 /* Return TRUE iff the current user (as determined by Apache's
803 authentication system) has permission to read RESOURCE in REV
804 (where an invalid REV means "HEAD"). This will invoke any authz
805 modules loaded into Apache unless this Subversion location has been
806 configured to bypass those in favor of a direct lookup in the
807 Subversion authz subsystem. Use POOL for any temporary allocation.
809 svn_boolean_t
810 dav_svn__allow_read_resource(const dav_resource *resource,
811 svn_revnum_t rev,
812 apr_pool_t *pool);
815 /* Return TRUE iff the current user (as determined by Apache's
816 authentication system) has permission to read repository REPOS_NAME.
817 This will invoke any authz modules loaded into Apache unless this
818 Subversion location has been configured to bypass those in favor of a
819 direct lookup in the Subversion authz subsystem. Use POOL for any
820 temporary allocation.
821 IMPORTANT: R must be request for DAV_SVN_RESTYPE_PARENTPATH_COLLECTION
822 resource.
824 svn_boolean_t
825 dav_svn__allow_list_repos(request_rec *r,
826 const char *repos_name,
827 apr_pool_t *pool);
829 /* If authz is enabled in the specified BATON, return a read authorization
830 function. Otherwise, return NULL. */
831 svn_repos_authz_func_t
832 dav_svn__authz_read_func(dav_svn__authz_read_baton *baton);
835 /*** util.c ***/
837 /* A wrapper around mod_dav's dav_new_error_tag, mod_dav_svn uses this
838 instead of the mod_dav function to enable special mod_dav_svn specific
839 processing. See dav_new_error_tag for parameter documentation.
840 Note that DESC may be null (it's hard to track this down from
841 dav_new_error_tag()'s documentation, but see the dav_error type,
842 which says that its desc field may be NULL).
844 If ERROR_ID is 0, SVN_ERR_RA_DAV_REQUEST_FAILED will be used as a
845 default value for the error code.
847 mod_dav is definitive documentation of the parameters, but a
848 guideline to the different error is:
850 STATUS is the HTTP status returned to the client.
852 ERROR_ID is an additional DAV-specific error such as a violation of
853 the DAV rules. mod_dav.h defines some values but callers can pass
854 others.
856 APRERR is any underlying OS/system error.
858 dav_error *
859 dav_svn__new_error_svn(apr_pool_t *pool,
860 int status,
861 int error_id,
862 apr_status_t aprerr,
863 const char *desc);
866 /* A wrapper around mod_dav's dav_new_error, mod_dav_svn uses this
867 instead of the mod_dav function to enable special mod_dav_svn specific
868 processing. See dav_svn__new_error_svn for additional details.
870 dav_error *
871 dav_svn__new_error(apr_pool_t *pool,
872 int status,
873 int error_id,
874 apr_status_t aprerr,
875 const char *desc);
878 /* Convert an svn_error_t into a dav_error, pushing another error based on
879 MESSAGE if MESSAGE is not NULL. Use the provided HTTP status for the
880 DAV errors. Allocate new DAV errors from POOL.
882 NOTE: this function destroys (cleanly, of course) SERR after it has
883 copied/converted its data to the new DAV error.
885 NOTE: MESSAGE needs to hang around for the lifetime of the error since
886 the current implementation doesn't copy it! Lots of callers pass static
887 string constant. */
888 dav_error *
889 dav_svn__convert_err(svn_error_t *serr,
890 int status,
891 const char *message,
892 apr_pool_t *pool);
895 /* Compare (PATH in ROOT) to (PATH in ROOT/PATH's created_rev).
897 If these nodes are identical, then return the created_rev.
899 If the nodes aren't identical, or if PATH simply doesn't exist in
900 the created_rev, then return the revision represented by ROOT.
902 (This is a helper to functions that want to build version-urls and
903 use the CR if possible.) */
904 svn_revnum_t
905 dav_svn__get_safe_cr(svn_fs_root_t *root, const char *path, apr_pool_t *pool);
908 /* Construct various kinds of URIs.
910 REPOS is always required, as all URIs will be built to refer to elements
911 within that repository. WHAT specifies the type of URI to build. The
912 ADD_HREF flag determines whether the URI is to be wrapped inside of
913 <D:href>uri</D:href> elements (for inclusion in a response).
915 Different pieces of information are required for the various URI types:
917 ACT_COLLECTION: no additional params required
918 BASELINE: REVISION should be specified
919 BC: REVISION should be specified
920 PUBLIC: PATH should be specified with a leading slash
921 VERSION: REVISION and PATH should be specified
922 VCC: no additional params required
924 enum dav_svn__build_what {
925 DAV_SVN__BUILD_URI_ACT_COLLECTION, /* the collection of activities */
926 DAV_SVN__BUILD_URI_BASELINE, /* a Baseline */
927 DAV_SVN__BUILD_URI_BC, /* a Baseline Collection */
928 DAV_SVN__BUILD_URI_PUBLIC, /* the "public" VCR */
929 DAV_SVN__BUILD_URI_VERSION, /* a Version Resource */
930 DAV_SVN__BUILD_URI_VCC, /* a Version Controlled Configuration */
931 DAV_SVN__BUILD_URI_REVROOT /* HTTPv2: Revision Root resource */
934 const char *
935 dav_svn__build_uri(const dav_svn_repos *repos,
936 enum dav_svn__build_what what,
937 svn_revnum_t revision,
938 const char *path,
939 svn_boolean_t add_href,
940 apr_pool_t *pool);
943 /* Simple parsing of a URI. This is used for URIs which appear within a
944 request body. It enables us to verify and break out the necessary pieces
945 to figure out what is being referred to.
947 ### this is horribly duplicative with the parsing functions in repos.c
948 ### for now, this implements only a minor subset of the full range of
949 ### URIs which we may need to parse. it also ignores any scheme, host,
950 ### and port in the URI and simply assumes it refers to the same server.
952 typedef struct dav_svn__uri_info {
953 svn_revnum_t rev;
954 const char *repos_path;
955 const char *activity_id;
956 } dav_svn__uri_info;
958 svn_error_t *
959 dav_svn__simple_parse_uri(dav_svn__uri_info *info,
960 const dav_resource *relative,
961 const char *uri,
962 apr_pool_t *pool);
964 /* Test the request R to determine if we should return the list of
965 * repositories at the parent path. Only true if SVNListParentPath directive
966 * is 'on' and the request is for our configured root path. */
967 svn_boolean_t
968 dav_svn__is_parentpath_list(request_rec *r);
971 int dav_svn__find_ns(const apr_array_header_t *namespaces, const char *uri);
975 /*** Brigade I/O wrappers ***/
977 /* Write LEN bytes from DATA to OUTPUT using BB. */
978 svn_error_t *dav_svn__brigade_write(apr_bucket_brigade *bb,
979 dav_svn__output *output,
980 const char *buf,
981 apr_size_t len);
983 /* Write NULL-terminated string STR to OUTPUT using BB. */
984 svn_error_t *dav_svn__brigade_puts(apr_bucket_brigade *bb,
985 dav_svn__output *output,
986 const char *str);
989 /* Write data to OUTPUT using BB, using FMT as the output format string. */
990 svn_error_t *dav_svn__brigade_printf(apr_bucket_brigade *bb,
991 dav_svn__output *output,
992 const char *fmt,
993 ...)
994 __attribute__((format(printf, 3, 4)));
996 /* Write an unspecified number of strings to OUTPUT using BB. */
997 svn_error_t *dav_svn__brigade_putstrs(apr_bucket_brigade *bb,
998 dav_svn__output *output,
999 ...) SVN_NEEDS_SENTINEL_NULL;
1004 /* Test PATH for canonicalness (defined as "what won't make the
1005 svn_path_* functions immediately explode"), returning an
1006 HTTP_BAD_REQUEST error tag if the test fails. */
1007 dav_error *dav_svn__test_canonical(const char *path, apr_pool_t *pool);
1010 /* Convert @a serr into a dav_error. If @a new_msg is non-NULL, use
1011 @a new_msg in the returned error, and write the original
1012 @a serr->message to httpd's log. Destroy the passed-in @a serr,
1013 similarly to dav_svn__convert_err().
1015 @a new_msg is usually a "sanitized" version of @a serr->message.
1016 That is, if @a serr->message contains security-sensitive data,
1017 @a new_msg does not.
1019 The purpose of sanitization is to prevent security-sensitive data
1020 from being transmitted over the network to the client. The error
1021 messages produced by various APIs (e.g., svn_fs, svn_repos) may
1022 contain security-sensitive data such as the actual server file
1023 system's path to the repository. We don't want to send that to the
1024 client, but we do want to log the real error on the server side.
1026 dav_error *
1027 dav_svn__sanitize_error(svn_error_t *serr,
1028 const char *new_msg,
1029 int http_status,
1030 request_rec *r);
1033 /* Return a writable generic stream that will encode its output to base64
1034 and send it to OUTPUT using BB. Allocate the stream in POOL. */
1035 svn_stream_t *
1036 dav_svn__make_base64_output_stream(apr_bucket_brigade *bb,
1037 dav_svn__output *output,
1038 apr_pool_t *pool);
1040 /* In INFO->r->subprocess_env set "SVN-ACTION" to LINE, "SVN-REPOS" to
1041 * INFO->repos->fs_path, and "SVN-REPOS-NAME" to INFO->repos->repo_basename. */
1042 void
1043 dav_svn__operational_log(struct dav_resource_private *info, const char *line);
1045 /* Flush BB if it's okay and useful to do so, but treat PREFERRED_ERR
1046 * as a more important error to return (if it is non-NULL).
1048 * This is intended to be used at the end of response processing,
1049 * probably called as a direct return generator, like so:
1051 * return dav_svn__final_flush_or_error(r, bb, output, derr, resource->pool);
1053 * SOME BACKGROUND INFO:
1055 * We don't flush the brigade unless there's something in it to
1056 * flush; that way, we have the opportunity to package a dav_error up
1057 * for transmission back to the client.
1059 * To understand this, see mod_dav.c:dav_method_report(): as long as
1060 * it doesn't think we've sent anything to the client, it'll send
1061 * the real error, which is what we'd prefer. This situation is
1062 * described in httpd-2.2.6/modules/dav/main/mod_dav.c, line 4066,
1063 * in the comment in dav_method_report() that says:
1065 * If an error occurred during the report delivery, there's
1066 * basically nothing we can do but abort the connection and
1067 * log an error. This is one of the limitations of HTTP; it
1068 * needs to "know" the entire status of the response before
1069 * generating it, which is just impossible in these streamy
1070 * response situations.
1072 * In other words, flushing the brigade causes r->sent_bodyct (see
1073 * dav_method_report()) to become non-zero, even if we hadn't tried to
1074 * send any data to the brigade yet. So we don't flush unless data
1075 * was actually sent.
1077 dav_error *
1078 dav_svn__final_flush_or_error(request_rec *r, apr_bucket_brigade *bb,
1079 dav_svn__output *output,
1080 dav_error *preferred_err,
1081 apr_pool_t *pool);
1083 /* Log a DAV error response.
1085 * NOTE: Copied from mod_dav's dav_log_err which is not public.
1087 void dav_svn__log_err(request_rec *r,
1088 dav_error *err,
1089 int level);
1091 /* Send a "standardized" DAV error response based on the ERR's
1092 * namespace and tag.
1094 * NOTE: This was copied pretty much directory from mod_dav's
1095 * dav_error_response_tag() function which is, sadly, not public.
1097 int dav_svn__error_response_tag(request_rec *r, dav_error *err);
1100 /* Set *SKEL to a parsed skel read from the body of request R, and
1101 * allocated in POOL.
1103 int dav_svn__parse_request_skel(svn_skel_t **skel, request_rec *r,
1104 apr_pool_t *pool);
1106 /* Set *YOUNGEST_P to the number of the youngest revision in REPOS.
1108 * Youngest revision will be cached in REPOS->YOUNGEST_REV to avoid
1109 * fetching the youngest revision multiple times during proccessing
1110 * the request.
1112 * Uses SCRATCH_POOL for temporary allocations.
1114 svn_error_t *
1115 dav_svn__get_youngest_rev(svn_revnum_t *youngest_p,
1116 dav_svn_repos *repos,
1117 apr_pool_t *scratch_pool);
1119 /* Return the liveprop-encoded form of AUTHOR, allocated in RESULT_POOL.
1120 * If IS_SVN_CLIENT is set, assume that the data will be sent to a SVN
1121 * client. This mainly sanitizes AUTHOR strings with control chars in
1122 * them without converting them to escape sequences etc.
1124 * Use SCRATCH_POOL for temporary allocations.
1126 const char *
1127 dav_svn__fuzzy_escape_author(const char *author,
1128 svn_boolean_t is_svn_client,
1129 apr_pool_t *result_pool,
1130 apr_pool_t *scratch_pool);
1132 /*** mirror.c ***/
1134 /* Perform the fixup hook for the R request. */
1135 int dav_svn__proxy_request_fixup(request_rec *r);
1137 /* An Apache input filter which rewrites the locations in headers and
1138 request body. It reads from filter F using BB data, MODE mode, BLOCK
1139 blocking strategy, and READBYTES. */
1140 apr_status_t dav_svn__location_in_filter(ap_filter_t *f,
1141 apr_bucket_brigade *bb,
1142 ap_input_mode_t mode,
1143 apr_read_type_e block,
1144 apr_off_t readbytes);
1146 /* An Apache output filter F which rewrites the response headers for
1147 * location headers. It will modify the stream in BB. */
1148 apr_status_t dav_svn__location_header_filter(ap_filter_t *f,
1149 apr_bucket_brigade *bb);
1151 /* An Apache output filter F which rewrites the response body for
1152 * location headers. It will modify the stream in BB. */
1153 apr_status_t dav_svn__location_body_filter(ap_filter_t *f,
1154 apr_bucket_brigade *bb);
1157 #ifdef __cplusplus
1159 #endif /* __cplusplus */
1161 #endif /* DAV_SVN_H */