In the command-line client, forbid
[svn.git] / subversion / libsvn_ra_serf / ra_serf.h
blob83973ad0a308f3249f15427dcfb61c325e94f49b
1 /*
2 * ra_serf.h : Private declarations for the Serf-based DAV RA module.
4 * ====================================================================
5 * Copyright (c) 2006-2007 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
19 #ifndef SVN_LIBSVN_RA_SERF_RA_SERF_H
20 #define SVN_LIBSVN_RA_SERF_RA_SERF_H
23 #include <serf.h>
24 #include <expat.h>
25 #include <apr_uri.h>
27 #include "svn_types.h"
28 #include "svn_string.h"
29 #include "svn_pools.h"
30 #include "svn_ra.h"
31 #include "svn_delta.h"
32 #include "svn_version.h"
33 #include "svn_dav.h"
35 #include "private/svn_dav_protocol.h"
38 /** Use this to silence compiler warnings about unused parameters. */
39 #define UNUSED_CTX(x) ((void)(x))
41 /** Our User-Agent string. */
42 #define USER_AGENT "SVN/" SVN_VERSION " serf/" \
43 APR_STRINGIFY(SERF_MAJOR_VERSION) "." \
44 APR_STRINGIFY(SERF_MINOR_VERSION) "." \
45 APR_STRINGIFY(SERF_PATCH_VERSION)
47 #ifdef WIN32
48 #if SERF_VERSION_AT_LEAST(0, 1, 3)
49 #define SVN_RA_SERF_SSPI_ENABLED
50 #endif
51 #endif /* WIN32 */
54 /* Forward declarations. */
55 typedef struct svn_ra_serf__session_t svn_ra_serf__session_t;
56 typedef struct svn_ra_serf__auth_protocol_t svn_ra_serf__auth_protocol_t;
57 #ifdef SVN_RA_SERF_SSPI_ENABLED
58 typedef struct serf_sspi_context_t serf_sspi_context_t;
59 #endif
61 /* A serf connection and optionally associated SSL context. */
62 typedef struct {
63 /* Our connection to a server. */
64 serf_connection_t *conn;
66 /* Bucket allocator for this connection. */
67 serf_bucket_alloc_t *bkt_alloc;
69 /* Host name */
70 const char *hostinfo;
72 /* The address where the connections are made to */
73 apr_sockaddr_t *address;
75 /* Are we using ssl */
76 svn_boolean_t using_ssl;
78 /* Should we ask for compressed responses? */
79 svn_boolean_t using_compression;
81 /* What was the last HTTP status code we got on this connection? */
82 int last_status_code;
84 /* Current authorization header used for this connection; may be NULL */
85 const char *auth_header;
87 /* Current authorization value used for this connection; may be NULL */
88 char *auth_value;
90 /* Optional SSL context for this connection. */
91 serf_ssl_context_t *ssl_context;
92 svn_auth_iterstate_t *ssl_client_auth_state;
93 svn_auth_iterstate_t *ssl_client_pw_auth_state;
95 svn_ra_serf__session_t *session;
97 #ifdef SVN_RA_SERF_SSPI_ENABLED
98 /* Optional SSPI context for this connection. */
99 serf_sspi_context_t *sspi_context;
100 #endif
102 /* Current authorization header used for the proxy server; may be NULL */
103 const char *proxy_auth_header;
105 /* Current authorization value used for the proxy server; may be NULL */
106 char *proxy_auth_value;
108 } svn_ra_serf__connection_t;
111 * The master serf RA session.
113 * This is stored in the ra session ->priv field.
115 struct svn_ra_serf__session_t {
116 /* Pool for allocations during this session */
117 apr_pool_t *pool;
119 /* The current context */
120 serf_context_t *context;
122 /* Bucket allocator for this context. */
123 serf_bucket_alloc_t *bkt_alloc;
125 /* Are we using ssl */
126 svn_boolean_t using_ssl;
128 /* Should we ask for compressed responses? */
129 svn_boolean_t using_compression;
131 /* The current connection */
132 svn_ra_serf__connection_t **conns;
133 int num_conns;
134 int cur_conn;
136 /* The URL that was passed into _open() */
137 apr_uri_t repos_url;
138 const char *repos_url_str;
140 /* The actual discovered root; may be NULL until we know it. */
141 apr_uri_t repos_root;
142 const char *repos_root_str;
144 /* Our Version-Controlled-Configuration; may be NULL until we know it. */
145 const char *vcc_url;
147 /* Cached properties */
148 apr_hash_t *cached_props;
150 /* Authentication related properties. */
151 const char *realm;
152 const char *auth_header;
153 char *auth_value;
154 svn_auth_iterstate_t *auth_state;
155 int auth_attempts;
157 /* Callback functions to get info from WC */
158 const svn_ra_callbacks2_t *wc_callbacks;
159 void *wc_callback_baton;
161 /* Error that we've received but not yet returned upstream. */
162 svn_error_t *pending_error;
164 /* vtable and info object handling the authentication */
165 const svn_ra_serf__auth_protocol_t *auth_protocol;
167 /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values.
168 If a capability is not yet discovered, it is absent from the table.
169 The table itself is allocated in the svn_ra_serf__session_t's pool;
170 keys and values must have at least that lifetime. Most likely
171 the keys and values are constants anyway (and sufficiently
172 well-informed internal code may just compare against those
173 constants' addresses, therefore). */
174 apr_hash_t *capabilities;
176 /* Are we using a proxy? */
177 int using_proxy;
179 /* Proxy Authentication related properties */
180 const char *proxy_auth_header;
181 char *proxy_auth_value;
182 const svn_ra_serf__auth_protocol_t *proxy_auth_protocol;
184 const char *proxy_username;
185 const char *proxy_password;
186 int proxy_auth_attempts;
190 * Structure which represents a DAV element with a NAMESPACE and NAME.
192 typedef struct {
193 /* Element namespace */
194 const char *namespace;
195 /* Element name */
196 const char *name;
197 } svn_ra_serf__dav_props_t;
200 * Structure which represents an XML namespace.
202 typedef struct ns_t {
203 /* The assigned name. */
204 const char *namespace;
205 /* The full URL for this namespace. */
206 const char *url;
207 /* The next namespace in our list. */
208 struct ns_t *next;
209 } svn_ra_serf__ns_t;
212 * An incredibly simple list.
214 typedef struct ra_serf_list_t {
215 void *data;
216 struct ra_serf_list_t *next;
217 } svn_ra_serf__list_t;
219 /** DAV property sets **/
221 static const svn_ra_serf__dav_props_t base_props[] =
223 { "DAV:", "version-controlled-configuration" },
224 { "DAV:", "resourcetype" },
225 { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },
226 { SVN_DAV_PROP_NS_DAV, "repository-uuid" },
227 { NULL }
230 static const svn_ra_serf__dav_props_t checked_in_props[] =
232 { "DAV:", "checked-in" },
233 { NULL }
236 static const svn_ra_serf__dav_props_t baseline_props[] =
238 { "DAV:", "baseline-collection" },
239 { "DAV:", SVN_DAV__VERSION_NAME },
240 { NULL }
243 static const svn_ra_serf__dav_props_t all_props[] =
245 { "DAV:", "allprop" },
246 { NULL }
249 static const svn_ra_serf__dav_props_t vcc_props[] =
251 { "DAV:", "version-controlled-configuration" },
252 { NULL }
255 static const svn_ra_serf__dav_props_t check_path_props[] =
257 { "DAV:", "resourcetype" },
258 { NULL }
261 static const svn_ra_serf__dav_props_t uuid_props[] =
263 { SVN_DAV_PROP_NS_DAV, "repository-uuid" },
264 { NULL }
267 static const svn_ra_serf__dav_props_t repos_root_props[] =
269 { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },
270 { NULL }
273 static const svn_ra_serf__dav_props_t href_props[] =
275 { "DAV:", "href" },
276 { NULL }
279 /* WC props compatibility with ra_neon. */
280 #define SVN_RA_SERF__WC_NAMESPACE SVN_PROP_WC_PREFIX "ra_dav:"
281 #define SVN_RA_SERF__WC_ACTIVITY_URL SVN_RA_SERF__WC_NAMESPACE "activity-url"
282 #define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_RA_SERF__WC_NAMESPACE "version-url"
284 /** Serf utility functions **/
286 serf_bucket_t *
287 svn_ra_serf__conn_setup(apr_socket_t *sock,
288 void *baton,
289 apr_pool_t *pool);
291 serf_bucket_t*
292 svn_ra_serf__accept_response(serf_request_t *request,
293 serf_bucket_t *stream,
294 void *acceptor_baton,
295 apr_pool_t *pool);
297 void
298 svn_ra_serf__conn_closed(serf_connection_t *conn,
299 void *closed_baton,
300 apr_status_t why,
301 apr_pool_t *pool);
303 apr_status_t
304 svn_ra_serf__is_conn_closing(serf_bucket_t *response);
306 apr_status_t
307 svn_ra_serf__cleanup_serf_session(void *data);
309 /* Helper function to provide SSL client certificates. */
310 apr_status_t
311 svn_ra_serf__handle_client_cert(void *data,
312 const char **cert_path);
314 /* Helper function to provide SSL client certificate passwords. */
315 apr_status_t
316 svn_ra_serf__handle_client_cert_pw(void *data,
317 const char *cert_path,
318 const char **password);
321 * Create a REQUEST with an associated REQ_BKT in the SESSION.
323 * If HDRS_BKT is not-NULL, it will be set to a headers_bucket that
324 * corresponds to the new request.
326 * The request will be METHOD at URL.
328 * If BODY_BKT is not-NULL, it will be sent as the request body.
330 * If CONTENT_TYPE is not-NULL, it will be sent as the Content-Type header.
332 void
333 svn_ra_serf__setup_serf_req(serf_request_t *request,
334 serf_bucket_t **req_bkt, serf_bucket_t **hdrs_bkt,
335 svn_ra_serf__connection_t *conn,
336 const char *method, const char *url,
337 serf_bucket_t *body_bkt, const char *content_type);
340 * This function will run the serf context in SESS until *DONE is TRUE.
342 svn_error_t *
343 svn_ra_serf__context_run_wait(svn_boolean_t *done,
344 svn_ra_serf__session_t *sess,
345 apr_pool_t *pool);
347 /* Callback for when a request body is needed. */
348 typedef serf_bucket_t*
349 (*svn_ra_serf__request_body_delegate_t)(void *baton,
350 serf_bucket_alloc_t *alloc,
351 apr_pool_t *pool);
353 /* Callback for when request headers are needed. */
354 typedef apr_status_t
355 (*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
356 void *baton,
357 apr_pool_t *pool);
359 /* Callback for when a response has an error. */
360 typedef apr_status_t
361 (*svn_ra_serf__response_error_t)(serf_request_t *request,
362 serf_bucket_t *response,
363 int status_code,
364 void *baton);
367 * Structure that can be passed to our default handler to guide the
368 * execution of the request through its lifecycle.
370 typedef struct {
371 /* The HTTP method string of the request */
372 const char *method;
374 /* The resource to the execute the method on. */
375 const char *path;
377 /* The request's body buckets.
379 * May be NULL if there is no body to send or ->body_delegate is set.
381 * Using the body_delegate function is preferred as it delays the
382 * creation of the body until we're about to deliver the request
383 * instead of creating it earlier.
385 * @see svn_ra_serf__request_body_delegate_t
387 serf_bucket_t *body_buckets;
389 /* The content-type of the request body. */
390 const char *body_type;
392 /* The handler and baton pair for our handler. */
393 serf_response_handler_t response_handler;
394 void *response_baton;
396 /* The handler and baton pair to be executed when a non-recoverable error
397 * is detected. If it is NULL in the presence of an error, an abort() may
398 * be triggered.
400 svn_ra_serf__response_error_t response_error;
401 void *response_error_baton;
403 /* This function and baton will be executed when the request is about
404 * to be delivered by serf.
406 * This just passes through serf's raw request creation parameters.
407 * None of the other parameters will be utilized if this field is set.
409 serf_request_setup_t delegate;
410 void *delegate_baton;
412 /* This function and baton pair allows for custom request headers to
413 * be set.
415 * It will be executed after the request has been set up but before it is
416 * delivered.
418 svn_ra_serf__request_header_delegate_t header_delegate;
419 void *header_delegate_baton;
421 /* This function and baton pair allows a body to be created right before
422 * delivery.
424 * It will be executed after the request has been set up but before it is
425 * delivered.
427 svn_ra_serf__request_body_delegate_t body_delegate;
428 void *body_delegate_baton;
430 /* The connection and session to be used for this request. */
431 svn_ra_serf__connection_t *conn;
432 svn_ra_serf__session_t *session;
433 } svn_ra_serf__handler_t;
436 * Helper function to queue a request in the @a handler's connection.
438 serf_request_t*
439 svn_ra_serf__request_create(svn_ra_serf__handler_t *handler);
441 serf_request_t*
442 svn_ra_serf__priority_request_create(svn_ra_serf__handler_t *handler);
444 /* XML helper callbacks. */
446 typedef struct svn_ra_serf__xml_state_t {
447 /* A numeric value that represents the current state in parsing.
449 * Value 0 is reserved for use as the default state.
451 int current_state;
453 /* Private pointer set by the parsing code. */
454 void *private;
456 /* Allocations should be made in this pool to match the lifetime of the
457 * state.
459 apr_pool_t *pool;
461 /* The currently-declared namespace for this state. */
462 svn_ra_serf__ns_t *ns_list;
464 /* Our previous states. */
465 struct svn_ra_serf__xml_state_t *prev;
466 } svn_ra_serf__xml_state_t;
468 /* Forward declaration of the XML parser structure. */
469 typedef struct svn_ra_serf__xml_parser_t svn_ra_serf__xml_parser_t;
471 /* Callback invoked with @a baton by our XML @a parser when an element with
472 * the @a name containing @a attrs is opened.
474 typedef svn_error_t *
475 (*svn_ra_serf__xml_start_element_t)(svn_ra_serf__xml_parser_t *parser,
476 void *baton,
477 svn_ra_serf__dav_props_t name,
478 const char **attrs);
480 /* Callback invoked with @a baton by our XML @a parser when an element with
481 * the @a name is closed.
483 typedef svn_error_t *
484 (*svn_ra_serf__xml_end_element_t)(svn_ra_serf__xml_parser_t *parser,
485 void *baton,
486 svn_ra_serf__dav_props_t name);
488 /* Callback invoked with @a baton by our XML @a parser when a CDATA portion
489 * of @a data with size @a len is encountered.
491 * This may be invoked multiple times for the same tag.
493 * @see svn_ra_serf__expand_string
495 typedef svn_error_t *
496 (*svn_ra_serf__xml_cdata_chunk_handler_t)(svn_ra_serf__xml_parser_t *parser,
497 void *baton,
498 const char *data,
499 apr_size_t len);
502 * Helper structure associated with handle_xml_parser handler that will
503 * specify how an XML response will be processed.
505 struct svn_ra_serf__xml_parser_t {
506 /* Temporary allocations should be made in this pool. */
507 apr_pool_t *pool;
509 /* Caller-specific data passed to the start, end, cdata callbacks. */
510 void *user_data;
512 /* Callback invoked when a tag is opened. */
513 svn_ra_serf__xml_start_element_t start;
515 /* Callback invoked when a tag is closed. */
516 svn_ra_serf__xml_end_element_t end;
518 /* Callback invoked when a cdata chunk is received. */
519 svn_ra_serf__xml_cdata_chunk_handler_t cdata;
521 /* Our associated expat-based XML parser. */
522 XML_Parser xmlp;
524 /* Our current state. */
525 svn_ra_serf__xml_state_t *state;
527 /* Our previously used states (will be reused). */
528 svn_ra_serf__xml_state_t *free_state;
530 /* If non-NULL, the status code of the response will be stored here.
532 * If this is NULL and an error is received, an abort will be triggered.
534 int *status_code;
536 /* If non-NULL, this value will be set to TRUE when the response is
537 * completed.
539 svn_boolean_t *done;
541 /* If non-NULL, when this parser completes, it will add done_item to
542 * the list.
544 svn_ra_serf__list_t **done_list;
546 /* A pointer to the item that will be inserted into the list upon
547 * completeion.
549 svn_ra_serf__list_t *done_item;
551 /* If this flag is TRUE, errors during parsing will be ignored.
553 * This is mainly used when we are processing an error XML response to
554 * avoid infinite loops.
556 svn_boolean_t ignore_errors;
558 /* If an error occurred, this value will be non-NULL. */
559 svn_error_t *error;
563 * Parses a server-side error message into a local Subversion error.
565 typedef struct {
566 /* Our local representation of the error. */
567 svn_error_t *error;
569 /* Have we checked to see if there's an XML error in this response? */
570 svn_boolean_t init;
572 /* Was there an XML error response? */
573 svn_boolean_t has_xml_response;
575 /* Are we done with the response? */
576 svn_boolean_t done;
578 /* Have we seen an error tag? */
579 svn_boolean_t in_error;
581 /* Should we be collecting the XML cdata? */
582 svn_boolean_t collect_cdata;
584 /* Collected cdata. NULL if cdata not needed. */
585 svn_stringbuf_t *cdata;
587 /* XML parser and namespace used to parse the remote response */
588 svn_ra_serf__xml_parser_t parser;
589 } svn_ra_serf__server_error_t;
591 /* A simple request context that can be passed to handle_status_only. */
592 typedef struct {
593 /* The HTTP status code of the response */
594 int status;
596 /* The HTTP status line of the response */
597 const char *reason;
599 /* This value is set to TRUE when the response is completed. */
600 svn_boolean_t done;
602 /* If an error occurred, this value will be initialized. */
603 svn_ra_serf__server_error_t server_error;
604 } svn_ra_serf__simple_request_context_t;
607 * Serf handler for @a request / @a response pair that takes in a
608 * @a baton (@see svn_ra_serf__simple_request_context_t).
610 * Temporary allocations are made in @a pool.
612 apr_status_t
613 svn_ra_serf__handle_status_only(serf_request_t *request,
614 serf_bucket_t *response,
615 void *baton,
616 apr_pool_t *pool);
619 * Handler that discards the entire @a response body associated with a
620 * @a request.
622 * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an
623 * error is detected, it will be populated for later detection.
625 * All temporary allocations will be made in a @a pool.
627 apr_status_t
628 svn_ra_serf__handle_discard_body(serf_request_t *request,
629 serf_bucket_t *response,
630 void *baton,
631 apr_pool_t *pool);
634 * Handler that retrieves the embedded XML error response from the
635 * the @a response body associated with a @a request.
637 * All temporary allocations will be made in a @a pool.
639 svn_error_t *
640 svn_ra_serf__handle_server_error(serf_request_t *request,
641 serf_bucket_t *response,
642 apr_pool_t *pool);
645 * Handler that retrieves the embedded XML multistatus response from the
646 * the @a RESPONSE body associated with a @a REQUEST. *DONE is set to TRUE.
648 * The @a BATON should be of type svn_ra_serf__simple_request_context_t.
650 * All temporary allocations will be made in a @a pool.
652 apr_status_t
653 svn_ra_serf__handle_multistatus_only(serf_request_t *request,
654 serf_bucket_t *response,
655 void *baton,
656 apr_pool_t *pool);
659 * This function will feed the RESPONSE body into XMLP. When parsing is
660 * completed (i.e. an EOF is received), *DONE is set to TRUE.
662 * If an error occurs during processing RESP_ERR is invoked with the
663 * RESP_ERR_BATON.
665 * Temporary allocations are made in POOL.
667 apr_status_t
668 svn_ra_serf__handle_xml_parser(serf_request_t *request,
669 serf_bucket_t *response,
670 void *handler_baton,
671 apr_pool_t *pool);
673 /** XML helper functions. **/
676 * Advance the internal XML @a parser to the @a state.
678 void
679 svn_ra_serf__xml_push_state(svn_ra_serf__xml_parser_t *parser,
680 int state);
683 * Return to the previous internal XML @a parser state.
685 void
686 svn_ra_serf__xml_pop_state(svn_ra_serf__xml_parser_t *parser);
689 * Add the appropriate serf buckets to @a agg_bucket represented by
690 * the XML * @a tag and @a value.
692 * The bucket will be allocated from @a bkt_alloc.
694 void
695 svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket,
696 const char *tag,
697 const char *value,
698 serf_bucket_alloc_t *bkt_alloc);
701 * Look up the @a attrs array for namespace definitions and add each one
702 * to the @a ns_list of namespaces.
704 * New namespaces will be allocated in @a pool.
706 void
707 svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,
708 const char **attrs,
709 apr_pool_t *pool);
712 * Look up @a name in the @a ns_list list for previously declared namespace
713 * definitions.
715 * @return @a svn_ra_serf__dav_props_t tuple representing the expanded name.
717 svn_ra_serf__dav_props_t
718 svn_ra_serf__expand_ns(svn_ra_serf__ns_t *ns_list,
719 const char *name);
722 * Expand the string represented by @a cur with a current size of @a
723 * cur_len by appending @a new with a size of @a new_len.
725 * The reallocated string is made in @a pool.
727 void
728 svn_ra_serf__expand_string(const char **cur, apr_size_t *cur_len,
729 const char *new, apr_size_t new_len,
730 apr_pool_t *pool);
732 /** PROPFIND-related functions **/
734 /* Opaque structure representing PROPFINDs. */
735 typedef struct svn_ra_serf__propfind_context_t svn_ra_serf__propfind_context_t;
738 * Returns a flag representing whether the PROPFIND @a ctx is completed.
740 svn_boolean_t
741 svn_ra_serf__propfind_is_done(svn_ra_serf__propfind_context_t *ctx);
744 * Returns the response status code of the PROPFIND @a ctx.
747 svn_ra_serf__propfind_status_code(svn_ra_serf__propfind_context_t *ctx);
749 /* Our PROPFIND bucket */
750 serf_bucket_t *
751 svn_ra_serf__bucket_propfind_create(svn_ra_serf__connection_t *conn,
752 const char *path,
753 const char *label,
754 const char *depth,
755 const svn_ra_serf__dav_props_t *find_props,
756 serf_bucket_alloc_t *allocator);
759 * This function will deliver a PROP_CTX PROPFIND request in the SESS
760 * serf context for the properties listed in LOOKUP_PROPS at URL for
761 * DEPTH ("0","1","infinity").
763 * This function will not block waiting for the response. If the
764 * request can be satisfied from a local cache, set PROP_CTX to NULL
765 * as a signal to callers of that fact. Otherwise, callers are
766 * expected to call svn_ra_serf__wait_for_props().
768 svn_error_t *
769 svn_ra_serf__deliver_props(svn_ra_serf__propfind_context_t **prop_ctx,
770 apr_hash_t *prop_vals,
771 svn_ra_serf__session_t *sess,
772 svn_ra_serf__connection_t *conn,
773 const char *url,
774 svn_revnum_t rev,
775 const char *depth,
776 const svn_ra_serf__dav_props_t *lookup_props,
777 svn_boolean_t cache_props,
778 svn_ra_serf__list_t **done_list,
779 apr_pool_t *pool);
782 * This helper function will block until the PROP_CTX indicates that is done
783 * or another error is returned.
785 svn_error_t *
786 svn_ra_serf__wait_for_props(svn_ra_serf__propfind_context_t *prop_ctx,
787 svn_ra_serf__session_t *sess,
788 apr_pool_t *pool);
790 /* Shared helper func: given a public URL which may not exist in HEAD,
791 use SESSION to search up parent directories until we can retrieve a
792 *PROPS (allocated in POOL) containing a standard set of base props:
793 {VCC, resourcetype, baseline-relative-path}.
795 Also return:
796 *MISSING_PATH (allocated in POOL), which is the trailing portion of
797 the URL that did not exist. If an error occurs, *MISSING_PATH isn't
798 changed.
799 *REMAINING_PATH (allocated in POOL), which is the parent path on which
800 we found the PROPS.
802 svn_error_t *
803 svn_ra_serf__search_for_base_props(apr_hash_t *props,
804 const char **remaining_path,
805 const char **missing_path,
806 svn_ra_serf__session_t *session,
807 svn_ra_serf__connection_t *conn,
808 const char *url,
809 apr_pool_t *pool);
812 * This is a blocking version of deliver_props.
814 svn_error_t *
815 svn_ra_serf__retrieve_props(apr_hash_t *prop_vals,
816 svn_ra_serf__session_t *sess,
817 svn_ra_serf__connection_t *conn,
818 const char *url,
819 svn_revnum_t rev,
820 const char *depth,
821 const svn_ra_serf__dav_props_t *props,
822 apr_pool_t *pool);
824 /* ### TODO: doco. */
825 void
826 svn_ra_serf__set_ver_prop(apr_hash_t *props,
827 const char *path, svn_revnum_t rev,
828 const char *ns, const char *name,
829 const svn_string_t *val, apr_pool_t *pool);
831 /** Property walker functions **/
833 typedef svn_error_t *
834 (*svn_ra_serf__walker_visitor_t)(void *baton,
835 const char *ns, apr_ssize_t ns_len,
836 const char *name, apr_ssize_t name_len,
837 const svn_string_t *val,
838 apr_pool_t *pool);
840 void
841 svn_ra_serf__walk_all_props(apr_hash_t *props,
842 const char *name,
843 svn_revnum_t rev,
844 svn_ra_serf__walker_visitor_t walker,
845 void *baton,
846 apr_pool_t *pool);
848 typedef svn_error_t *
849 (*svn_ra_serf__path_rev_walker_t)(void *baton,
850 const char *path, apr_ssize_t path_len,
851 const char *ns, apr_ssize_t ns_len,
852 const char *name, apr_ssize_t name_len,
853 const svn_string_t *val,
854 apr_pool_t *pool);
855 void
856 svn_ra_serf__walk_all_paths(apr_hash_t *props,
857 svn_revnum_t rev,
858 svn_ra_serf__path_rev_walker_t walker,
859 void *baton,
860 apr_pool_t *pool);
862 /* Higher-level variants on the walker. */
863 typedef svn_error_t * (*svn_ra_serf__prop_set_t)(void *baton,
864 const char *name,
865 const svn_string_t *value,
866 apr_pool_t *pool);
868 svn_error_t *
869 svn_ra_serf__set_baton_props(svn_ra_serf__prop_set_t setprop, void *baton,
870 const char *ns, apr_ssize_t ns_len,
871 const char *name, apr_ssize_t name_len,
872 const svn_string_t *val,
873 apr_pool_t *pool);
875 svn_error_t *
876 svn_ra_serf__set_flat_props(void *baton,
877 const char *ns, apr_ssize_t ns_len,
878 const char *name, apr_ssize_t name_len,
879 const svn_string_t *val,
880 apr_pool_t *pool);
882 svn_error_t *
883 svn_ra_serf__set_bare_props(void *baton,
884 const char *ns, apr_ssize_t ns_len,
885 const char *name, apr_ssize_t name_len,
886 const svn_string_t *val,
887 apr_pool_t *pool);
889 /* Get PROPS for PATH at REV revision with a NS:NAME. */
890 const svn_string_t *
891 svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
892 const char *path, svn_revnum_t rev,
893 const char *ns, const char *name);
894 const char *
895 svn_ra_serf__get_ver_prop(apr_hash_t *props,
896 const char *path, svn_revnum_t rev,
897 const char *ns, const char *name);
899 /* Same as get_prop, but for the unknown revision */
900 const char *
901 svn_ra_serf__get_prop(apr_hash_t *props,
902 const char *path,
903 const char *ns,
904 const char *name);
906 /* Set PROPS for PATH at REV revision with a NS:NAME VAL.
908 * The POOL governs allocation.
910 void
911 svn_ra_serf__set_rev_prop(apr_hash_t *props,
912 const char *path, svn_revnum_t rev,
913 const char *ns, const char *name,
914 const svn_string_t *val, apr_pool_t *pool);
916 /* Same as set_rev_prop, but sets it for the unknown revision. */
917 void
918 svn_ra_serf__set_prop(apr_hash_t *props, const char *path,
919 const char *ns, const char *name,
920 const svn_string_t *val, apr_pool_t *pool);
922 /** MERGE-related functions **/
924 typedef struct svn_ra_serf__merge_context_t svn_ra_serf__merge_context_t;
926 svn_boolean_t*
927 svn_ra_serf__merge_get_done_ptr(svn_ra_serf__merge_context_t *ctx);
929 svn_commit_info_t*
930 svn_ra_serf__merge_get_commit_info(svn_ra_serf__merge_context_t *ctx);
933 svn_ra_serf__merge_get_status(svn_ra_serf__merge_context_t *ctx);
935 void
936 svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
937 const char *parent,
938 serf_bucket_t *body,
939 serf_bucket_alloc_t *alloc,
940 apr_pool_t *pool);
942 /* Create an MERGE request */
943 svn_error_t *
944 svn_ra_serf__merge_create_req(svn_ra_serf__merge_context_t **merge_ctx,
945 svn_ra_serf__session_t *session,
946 svn_ra_serf__connection_t *conn,
947 const char *path,
948 const char *activity_url,
949 apr_size_t activity_url_len,
950 apr_hash_t *lock_tokens,
951 svn_boolean_t keep_locks,
952 apr_pool_t *pool);
954 /** OPTIONS-related functions **/
956 typedef struct svn_ra_serf__options_context_t svn_ra_serf__options_context_t;
958 /* Is this OPTIONS-request done yet? */
959 svn_boolean_t*
960 svn_ra_serf__get_options_done_ptr(svn_ra_serf__options_context_t *ctx);
962 const char *
963 svn_ra_serf__options_get_activity_collection(svn_ra_serf__options_context_t *ctx);
965 svn_error_t *
966 svn_ra_serf__get_options_error(svn_ra_serf__options_context_t *ctx);
968 svn_error_t *
969 svn_ra_serf__get_options_parser_error(svn_ra_serf__options_context_t *ctx);
971 /* Create an OPTIONS request */
972 svn_error_t *
973 svn_ra_serf__create_options_req(svn_ra_serf__options_context_t **opt_ctx,
974 svn_ra_serf__session_t *session,
975 svn_ra_serf__connection_t *conn,
976 const char *path,
977 apr_pool_t *pool);
979 /* Try to discover our current root @a vcc_url and the resultant @a rel_path
980 * based on @a orig_path for the @a session on @a conn.
982 * @a rel_path may be NULL if the caller is not interested in the relative
983 * path.
985 * All temporary allocations will be made in @a pool.
987 svn_error_t *
988 svn_ra_serf__discover_root(const char **vcc_url,
989 const char **rel_path,
990 svn_ra_serf__session_t *session,
991 svn_ra_serf__connection_t *conn,
992 const char *orig_path,
993 apr_pool_t *pool);
995 /* Set *BC_URL to the baseline collection url, and set *BC_RELATIVE to
996 * the path relative to that url for URL in REVISION using SESSION.
997 * REVISION may be SVN_INVALID_REVNUM (to mean "the current HEAD
998 * revision"). If URL is NULL, use SESSION's session url.
999 * Use POOL for all allocations.
1001 svn_error_t *
1002 svn_ra_serf__get_baseline_info(const char **bc_url,
1003 const char **bc_relative,
1004 svn_ra_serf__session_t *session,
1005 const char *url,
1006 svn_revnum_t revision,
1007 apr_pool_t *pool);
1009 /** RA functions **/
1011 svn_error_t *
1012 svn_ra_serf__get_log(svn_ra_session_t *session,
1013 const apr_array_header_t *paths,
1014 svn_revnum_t start,
1015 svn_revnum_t end,
1016 int limit,
1017 svn_boolean_t discover_changed_paths,
1018 svn_boolean_t strict_node_history,
1019 svn_boolean_t include_merged_revisions,
1020 apr_array_header_t *revprops,
1021 svn_log_entry_receiver_t receiver,
1022 void *receiver_baton,
1023 apr_pool_t *pool);
1025 svn_error_t *
1026 svn_ra_serf__get_locations(svn_ra_session_t *session,
1027 apr_hash_t **locations,
1028 const char *path,
1029 svn_revnum_t peg_revision,
1030 apr_array_header_t *location_revisions,
1031 apr_pool_t *pool);
1033 svn_error_t *
1034 svn_ra_serf__get_location_segments(svn_ra_session_t *session,
1035 const char *path,
1036 svn_revnum_t peg_revision,
1037 svn_revnum_t start_rev,
1038 svn_revnum_t end_rev,
1039 svn_location_segment_receiver_t receiver,
1040 void *receiver_baton,
1041 apr_pool_t *pool);
1043 svn_error_t *
1044 svn_ra_serf__do_diff(svn_ra_session_t *session,
1045 const svn_ra_reporter3_t **reporter,
1046 void **report_baton,
1047 svn_revnum_t revision,
1048 const char *diff_target,
1049 svn_depth_t depth,
1050 svn_boolean_t ignore_ancestry,
1051 svn_boolean_t text_deltas,
1052 const char *versus_url,
1053 const svn_delta_editor_t *diff_editor,
1054 void *diff_baton,
1055 apr_pool_t *pool);
1057 svn_error_t *
1058 svn_ra_serf__do_status(svn_ra_session_t *ra_session,
1059 const svn_ra_reporter3_t **reporter,
1060 void **report_baton,
1061 const char *status_target,
1062 svn_revnum_t revision,
1063 svn_depth_t depth,
1064 const svn_delta_editor_t *status_editor,
1065 void *status_baton,
1066 apr_pool_t *pool);
1068 svn_error_t *
1069 svn_ra_serf__do_update(svn_ra_session_t *ra_session,
1070 const svn_ra_reporter3_t **reporter,
1071 void **report_baton,
1072 svn_revnum_t revision_to_update_to,
1073 const char *update_target,
1074 svn_depth_t depth,
1075 svn_boolean_t send_copyfrom_args,
1076 const svn_delta_editor_t *update_editor,
1077 void *update_baton,
1078 apr_pool_t *pool);
1080 svn_error_t *
1081 svn_ra_serf__do_switch(svn_ra_session_t *ra_session,
1082 const svn_ra_reporter3_t **reporter,
1083 void **report_baton,
1084 svn_revnum_t revision_to_switch_to,
1085 const char *switch_target,
1086 svn_depth_t depth,
1087 const char *switch_url,
1088 const svn_delta_editor_t *switch_editor,
1089 void *switch_baton,
1090 apr_pool_t *pool);
1092 svn_error_t *
1093 svn_ra_serf__get_file_revs(svn_ra_session_t *session,
1094 const char *path,
1095 svn_revnum_t start,
1096 svn_revnum_t end,
1097 svn_boolean_t include_merged_revisions,
1098 svn_file_rev_handler_t handler,
1099 void *handler_baton,
1100 apr_pool_t *pool);
1102 svn_error_t *
1103 svn_ra_serf__get_dated_revision(svn_ra_session_t *session,
1104 svn_revnum_t *revision,
1105 apr_time_t tm,
1106 apr_pool_t *pool);
1108 svn_error_t *
1109 svn_ra_serf__get_commit_editor(svn_ra_session_t *session,
1110 const svn_delta_editor_t **editor,
1111 void **edit_baton,
1112 apr_hash_t *revprop_table,
1113 svn_commit_callback2_t callback,
1114 void *callback_baton,
1115 apr_hash_t *lock_tokens,
1116 svn_boolean_t keep_locks,
1117 apr_pool_t *pool);
1119 svn_error_t *
1120 svn_ra_serf__get_file(svn_ra_session_t *session,
1121 const char *path,
1122 svn_revnum_t revision,
1123 svn_stream_t *stream,
1124 svn_revnum_t *fetched_rev,
1125 apr_hash_t **props,
1126 apr_pool_t *pool);
1128 svn_error_t *
1129 svn_ra_serf__change_rev_prop(svn_ra_session_t *session,
1130 svn_revnum_t rev,
1131 const char *name,
1132 const svn_string_t *value,
1133 apr_pool_t *pool);
1135 svn_error_t *
1136 svn_ra_serf__replay(svn_ra_session_t *ra_session,
1137 svn_revnum_t revision,
1138 svn_revnum_t low_water_mark,
1139 svn_boolean_t text_deltas,
1140 const svn_delta_editor_t *editor,
1141 void *edit_baton,
1142 apr_pool_t *pool);
1144 svn_error_t *
1145 svn_ra_serf__replay_range(svn_ra_session_t *ra_session,
1146 svn_revnum_t start_revision,
1147 svn_revnum_t end_revision,
1148 svn_revnum_t low_water_mark,
1149 svn_boolean_t send_deltas,
1150 svn_ra_replay_revstart_callback_t revstart_func,
1151 svn_ra_replay_revfinish_callback_t revfinish_func,
1152 void *replay_baton,
1153 apr_pool_t *pool);
1155 svn_error_t *
1156 svn_ra_serf__lock(svn_ra_session_t *ra_session,
1157 apr_hash_t *path_revs,
1158 const char *comment,
1159 svn_boolean_t force,
1160 svn_ra_lock_callback_t lock_func,
1161 void *lock_baton,
1162 apr_pool_t *pool);
1164 svn_error_t *
1165 svn_ra_serf__unlock(svn_ra_session_t *ra_session,
1166 apr_hash_t *path_tokens,
1167 svn_boolean_t force,
1168 svn_ra_lock_callback_t lock_func,
1169 void *lock_baton,
1170 apr_pool_t *pool);
1172 svn_error_t *
1173 svn_ra_serf__get_lock(svn_ra_session_t *ra_session,
1174 svn_lock_t **lock,
1175 const char *path,
1176 apr_pool_t *pool);
1178 svn_error_t *
1179 svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
1180 apr_hash_t **locks,
1181 const char *path,
1182 apr_pool_t *pool);
1184 svn_error_t * svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
1185 apr_hash_t **mergeinfo,
1186 const apr_array_header_t *paths,
1187 svn_revnum_t revision,
1188 svn_mergeinfo_inheritance_t inherit,
1189 apr_pool_t *pool);
1191 /* Implements the has_capability RA layer function. */
1192 svn_error_t *
1193 svn_ra_serf__has_capability(svn_ra_session_t *ra_session,
1194 svn_boolean_t *has,
1195 const char *capability,
1196 apr_pool_t *pool);
1199 /*** Authentication handler declarations ***/
1202 * For each authentication protocol we need a handler function of type
1203 * svn_serf__auth_handler_func_t. This function will be called when an
1204 * authentication challenge is received in a session.
1206 typedef svn_error_t *
1207 (*svn_serf__auth_handler_func_t)(svn_ra_serf__session_t *session,
1208 svn_ra_serf__connection_t *conn,
1209 serf_request_t *request,
1210 serf_bucket_t *response,
1211 char *auth_hdr,
1212 char *auth_attr,
1213 apr_pool_t *pool);
1216 * For each authentication protocol we need an initialization function of type
1217 * svn_serf__init_conn_func_t. This function will be called when a new
1218 * connection is opened.
1220 typedef svn_error_t *
1221 (*svn_serf__init_conn_func_t)(svn_ra_serf__session_t *session,
1222 svn_ra_serf__connection_t *conn,
1223 apr_pool_t *pool);
1226 * For each authentication protocol we need a setup_request function of type
1227 * svn_serf__setup_request_func_t. This function will be called when a
1228 * new serf_request_t object is created and should fill in the correct
1229 * authentication headers (if needed).
1231 typedef svn_error_t *
1232 (*svn_serf__setup_request_func_t)(svn_ra_serf__connection_t *conn,
1233 serf_bucket_t *hdrs_bkt);
1236 * svn_ra_serf__auth_protocol_t: vtable for an authn protocol provider.
1239 struct svn_ra_serf__auth_protocol_t {
1240 /* The http status code that's handled by this authentication protocol.
1241 Normal values are 401 for server authentication and 407 for proxy
1242 authentication */
1243 int code;
1245 /* The name of this authentication protocol. This should be a case
1246 sensitive match of the string sent in the HTTP authentication header. */
1247 const char *auth_name;
1249 /* The initialization function if any; otherwise, NULL */
1250 svn_serf__init_conn_func_t init_conn_func;
1252 /* The authentication handler function */
1253 svn_serf__auth_handler_func_t handle_func;
1255 /* Function to set up the authentication header of a request */
1256 svn_serf__setup_request_func_t setup_request_func;
1260 * This function will be called when an authentication challenge is
1261 * received. Based on the challenge, handle_auth will pick the needed
1262 * authn implementation and forward the call to its authn handler.
1264 svn_error_t *
1265 svn_ra_serf__handle_auth(int code,
1266 svn_ra_serf__session_t *session,
1267 svn_ra_serf__connection_t *conn,
1268 serf_request_t *request,
1269 serf_bucket_t *response,
1270 apr_pool_t *pool);
1273 * encode_auth_header: base64 encodes the authentication data and builds an
1274 * authentication header in this format:
1275 * [PROTOCOL] [BASE64 AUTH DATA]
1277 void
1278 svn_ra_serf__encode_auth_header(const char * protocol,
1279 char **header,
1280 const char * data,
1281 apr_size_t data_len,
1282 apr_pool_t *pool);
1284 #endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */