]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/libsvn_ra_serf/ra_serf.h
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / libsvn_ra_serf / ra_serf.h
1 /*
2  * ra_serf.h : Private declarations for the Serf-based DAV RA module.
3  *
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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  * ====================================================================
22  */
23
24 #ifndef SVN_LIBSVN_RA_SERF_RA_SERF_H
25 #define SVN_LIBSVN_RA_SERF_RA_SERF_H
26
27 \f
28 #include <serf.h>
29 #include <expat.h>  /* for XML_Parser  */
30 #include <apr_uri.h>
31
32 #include "svn_types.h"
33 #include "svn_string.h"
34 #include "svn_pools.h"
35 #include "svn_ra.h"
36 #include "svn_delta.h"
37 #include "svn_version.h"
38 #include "svn_dav.h"
39 #include "svn_dirent_uri.h"
40
41 #include "private/svn_dav_protocol.h"
42 #include "private/svn_subr_private.h"
43 #include "private/svn_editor.h"
44
45 #include "blncache.h"
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif /* __cplusplus */
50
51 \f
52 /* Enforce the minimum version of serf. */
53 #if !SERF_VERSION_AT_LEAST(1, 2, 1)
54 #error Please update your version of serf to at least 1.2.1.
55 #endif
56
57 /** Wait duration (in microseconds) used in calls to serf_context_run() */
58 #define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000
59
60
61 \f
62 /* Forward declarations. */
63 typedef struct svn_ra_serf__session_t svn_ra_serf__session_t;
64
65 /* A serf connection and optionally associated SSL context.  */
66 typedef struct svn_ra_serf__connection_t {
67   /* Our connection to a server. */
68   serf_connection_t *conn;
69
70   /* Bucket allocator for this connection. */
71   serf_bucket_alloc_t *bkt_alloc;
72
73   /* Collected cert failures in chain.  */
74   int server_cert_failures;
75
76   /* What was the last HTTP status code we got on this connection? */
77   int last_status_code;
78
79   /* Optional SSL context for this connection. */
80   serf_ssl_context_t *ssl_context;
81   svn_auth_iterstate_t *ssl_client_auth_state;
82   svn_auth_iterstate_t *ssl_client_pw_auth_state;
83
84   svn_ra_serf__session_t *session;
85
86 } svn_ra_serf__connection_t;
87
88 /** Maximum value we'll allow for the http-max-connections config option.
89  *
90  * Note: minimum 2 connections are required for ra_serf to function
91  * correctly!
92  */
93 #define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8
94
95 /*
96  * The master serf RA session.
97  *
98  * This is stored in the ra session ->priv field.
99  *
100  * ### Check ra_serf_dup_session when adding fields.
101  */
102 struct svn_ra_serf__session_t {
103   /* Pool for allocations during this session */
104   apr_pool_t *pool;
105   apr_hash_t *config; /* For duplicating */
106
107   /* The current context */
108   serf_context_t *context;
109
110   /* The maximum number of connections we'll use for parallelized
111      fetch operations (updates, etc.) */
112   apr_int64_t max_connections;
113
114   /* Are we using ssl */
115   svn_boolean_t using_ssl;
116
117   /* Should we ask for compressed responses? */
118   svn_boolean_t using_compression;
119
120   /* The user agent string */
121   const char *useragent;
122
123   /* The current connection */
124   svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT];
125   int num_conns;
126   int cur_conn;
127
128   /* The URL that was passed into _open() */
129   apr_uri_t session_url;
130   const char *session_url_str;
131
132   /* The actual discovered root; may be NULL until we know it. */
133   apr_uri_t repos_root;
134   const char *repos_root_str;
135
136   /* The server is not Apache/mod_dav_svn (directly) and only supports
137      HTTP/1.0. Thus, we cannot send chunked requests.  */
138   svn_boolean_t http10;
139
140   /* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */
141   svn_boolean_t using_chunked_requests;
142
143   /* Do we need to detect whether the connection supports chunked requests?
144      i.e. is there a (reverse) proxy that does not support them?  */
145   svn_boolean_t detect_chunking;
146
147   /* Our Version-Controlled-Configuration; may be NULL until we know it. */
148   const char *vcc_url;
149
150   /* Authentication related properties. */
151   svn_auth_iterstate_t *auth_state;
152   int auth_attempts;
153
154   /* Callback functions to get info from WC */
155   const svn_ra_callbacks2_t *wc_callbacks;
156   void *wc_callback_baton;
157   svn_auth_baton_t *auth_baton;
158
159   /* Callback function to send progress info to the client */
160   svn_ra_progress_notify_func_t progress_func;
161   void *progress_baton;
162
163   /* Callback function to handle cancellation */
164   svn_cancel_func_t cancel_func;
165   void *cancel_baton;
166
167   /* Ev2 shim callbacks */
168   svn_delta_shim_callbacks_t *shim_callbacks;
169
170   /* Error that we've received but not yet returned upstream. */
171   svn_error_t *pending_error;
172
173   /* List of authn types supported by the client.*/
174   int authn_types;
175
176   /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values.
177      If a capability is not yet discovered, it is absent from the table.
178      The table itself is allocated in the svn_ra_serf__session_t's pool;
179      keys and values must have at least that lifetime.  Most likely
180      the keys and values are constants anyway (and sufficiently
181      well-informed internal code may just compare against those
182      constants' addresses, therefore). */
183   apr_hash_t *capabilities;
184
185   /* Activity collection URL.  (Cached from the initial OPTIONS
186      request when run against HTTPv1 servers.)  */
187   const char *activity_collection_url;
188
189   /* Are we using a proxy? */
190   svn_boolean_t using_proxy;
191
192   const char *proxy_username;
193   const char *proxy_password;
194   int proxy_auth_attempts;
195
196   /* SSL server certificates */
197   svn_boolean_t trust_default_ca;
198   const char *ssl_authorities;
199
200   /* Repository UUID */
201   const char *uuid;
202
203   /* Connection timeout value */
204   apr_interval_time_t timeout;
205
206   /* HTTPv1 flags */
207   svn_tristate_t supports_deadprop_count;
208
209   /*** HTTP v2 protocol stuff. ***
210    *
211    * We assume that if mod_dav_svn sends one of the special v2 OPTIONs
212    * response headers, it has sent all of them.  Specifically, we'll
213    * be looking at the presence of the "me resource" as a flag that
214    * the server supports v2 of our HTTP protocol.
215    */
216
217   /* The "me resource".  Typically used as a target for REPORTs that
218      are path-agnostic.  If we have this, we can speak HTTP v2 to the
219      server.  */
220   const char *me_resource;
221
222   /* Opaque URL "stubs".  If the OPTIONS response returns these, then
223      we know we're using HTTP protocol v2. */
224   const char *rev_stub;         /* for accessing revisions (i.e. revprops) */
225   const char *rev_root_stub;    /* for accessing REV/PATH pairs */
226   const char *txn_stub;         /* for accessing transactions (i.e. txnprops) */
227   const char *txn_root_stub;    /* for accessing TXN/PATH pairs */
228   const char *vtxn_stub;        /* for accessing transactions (i.e. txnprops) */
229   const char *vtxn_root_stub;   /* for accessing TXN/PATH pairs */
230
231   /* Hash mapping const char * server-supported POST types to
232      disinteresting-but-non-null values. */
233   apr_hash_t *supported_posts;
234
235   /*** End HTTP v2 stuff ***/
236
237   svn_ra_serf__blncache_t *blncache;
238
239   /* Trisate flag that indicates user preference for using bulk updates
240      (svn_tristate_true) with all the properties and content in the
241      update-report response. If svn_tristate_false, request a skelta
242      update-report with inlined properties. If svn_tristate_unknown then use
243      server preference. */
244   svn_tristate_t bulk_updates;
245
246   /* Indicates if the server wants bulk update requests (Prefer) or only
247      accepts skelta requests (Off). If this value is On both options are
248      allowed. */
249   const char *server_allows_bulk;
250
251   /* Indicates if the server supports sending inlined props in update editor
252    * in skelta mode (send-all == 'false'). */
253   svn_boolean_t supports_inline_props;
254
255   /* Indicates whether the server supports issuing replay REPORTs
256      against rev resources (children of `rev_stub', elsestruct). */
257   svn_boolean_t supports_rev_rsrc_replay;
258 };
259
260 #define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL)
261
262 /*
263  * Structure which represents a DAV element with a NAMESPACE and NAME.
264  */
265 typedef struct svn_ra_serf__dav_props_t {
266   /* Element namespace */
267   const char *xmlns;
268   /* Element name */
269   const char *name;
270 } svn_ra_serf__dav_props_t;
271
272 /** DAV property sets **/
273
274 static const svn_ra_serf__dav_props_t base_props[] =
275 {
276   { "DAV:", "version-controlled-configuration" },
277   { "DAV:", "resourcetype" },
278   { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },
279   { SVN_DAV_PROP_NS_DAV, "repository-uuid" },
280   { NULL }
281 };
282
283 static const svn_ra_serf__dav_props_t checked_in_props[] =
284 {
285   { "DAV:", "checked-in" },
286   { NULL }
287 };
288
289 static const svn_ra_serf__dav_props_t baseline_props[] =
290 {
291   { "DAV:", "baseline-collection" },
292   { "DAV:", SVN_DAV__VERSION_NAME },
293   { NULL }
294 };
295
296 static const svn_ra_serf__dav_props_t all_props[] =
297 {
298   { "DAV:", "allprop" },
299   { NULL }
300 };
301
302 static const svn_ra_serf__dav_props_t check_path_props[] =
303 {
304   { "DAV:", "resourcetype" },
305   { NULL }
306 };
307
308 static const svn_ra_serf__dav_props_t type_and_checksum_props[] =
309 {
310   { "DAV:", "resourcetype" },
311   { SVN_DAV_PROP_NS_DAV, "sha1-checksum" },
312   { NULL }
313 };
314
315 /* WC props compatibility with ra_neon. */
316 #define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
317
318 /** Serf utility functions **/
319
320 apr_status_t
321 svn_ra_serf__conn_setup(apr_socket_t *sock,
322                         serf_bucket_t **read_bkt,
323                         serf_bucket_t **write_bkt,
324                         void *baton,
325                         apr_pool_t *pool);
326
327 void
328 svn_ra_serf__conn_closed(serf_connection_t *conn,
329                          void *closed_baton,
330                          apr_status_t why,
331                          apr_pool_t *pool);
332
333
334 /* Helper function to provide SSL client certificates.
335  *
336  * NOTE: This function sets the session's 'pending_error' member when
337  *       returning an non-success status.
338  */
339 apr_status_t
340 svn_ra_serf__handle_client_cert(void *data,
341                                 const char **cert_path);
342
343 /* Helper function to provide SSL client certificate passwords.
344  *
345  * NOTE: This function sets the session's 'pending_error' member when
346  *       returning an non-success status.
347  */
348 apr_status_t
349 svn_ra_serf__handle_client_cert_pw(void *data,
350                                    const char *cert_path,
351                                    const char **password);
352
353
354 /*
355  * This function will run the serf context in SESS until *DONE is TRUE.
356  */
357 svn_error_t *
358 svn_ra_serf__context_run_wait(svn_boolean_t *done,
359                               svn_ra_serf__session_t *sess,
360                               apr_pool_t *scratch_pool);
361
362 /* Run the context once. Manage waittime_left to handle timing out when
363    nothing happens over the session->timout.
364  */
365 svn_error_t *
366 svn_ra_serf__context_run(svn_ra_serf__session_t *sess,
367                          apr_interval_time_t *waittime_left,
368                          apr_pool_t *scratch_pool);
369
370
371
372 /* Callback for response handlers */
373 typedef svn_error_t *
374 (*svn_ra_serf__response_handler_t)(serf_request_t *request,
375                                    serf_bucket_t *response,
376                                    void *handler_baton,
377                                    apr_pool_t *scratch_pool);
378
379 /* Callback when the request is done */
380 typedef svn_error_t *
381 (*svn_ra_serf__response_done_delegate_t)(serf_request_t *request,
382                                          void *done_baton,
383                                          apr_pool_t *scratch_pool);
384
385 /* Callback for when a request body is needed. */
386 typedef svn_error_t *
387 (*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
388                                         void *baton,
389                                         serf_bucket_alloc_t *alloc,
390                                         apr_pool_t *request_pool,
391                                         apr_pool_t *scratch_pool);
392
393 /* Callback for when request headers are needed. */
394 typedef svn_error_t *
395 (*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
396                                           void *baton,
397                                           apr_pool_t *request_pool,
398                                           apr_pool_t *scratch_pool);
399
400 /* Callback for when a response has an error. */
401 typedef svn_error_t *
402 (*svn_ra_serf__response_error_t)(serf_request_t *request,
403                                  serf_bucket_t *response,
404                                  int status_code,
405                                  void *baton);
406
407 /* ### we should reorder the types in this file.  */
408 typedef struct svn_ra_serf__server_error_t svn_ra_serf__server_error_t;
409
410 /*
411  * Structure that can be passed to our default handler to guide the
412  * execution of the request through its lifecycle.
413  *
414  * Use svn_ra_serf__create_handler() to create instances of this struct.
415  */
416 typedef struct svn_ra_serf__handler_t {
417   /* The HTTP method string of the request */
418   const char *method;
419
420   /* The resource to the execute the method on. */
421   const char *path;
422
423   /* The content-type of the request body. */
424   const char *body_type;
425
426   /* If TRUE then default Accept-Encoding request header is not configured for
427      request. If FALSE then 'gzip' accept encoding will be used if compression
428      enabled. */
429   svn_boolean_t custom_accept_encoding;
430
431   /* If TRUE then default DAV: capabilities request headers is not configured
432      for request. */
433   svn_boolean_t no_dav_headers;
434
435   /* If TRUE doesn't fail requests on HTTP error statuses like 405, 408, 500
436      (see util.c response_done()) */
437   svn_boolean_t no_fail_on_http_failure_status;
438
439   /* If TRUE doesn't fail requests on HTTP redirect statuses like 301, 307 */
440   svn_boolean_t no_fail_on_http_redirect_status;
441
442   /* Has the request/response been completed?  */
443   svn_boolean_t done;
444   svn_boolean_t scheduled; /* Is the request scheduled in a context */
445
446   /* If we captured an error from the server, then this will be non-NULL.
447      It will be allocated from HANDLER_POOL.  */
448   svn_ra_serf__server_error_t *server_error;
449
450   /* The handler and baton pair for our handler. */
451   svn_ra_serf__response_handler_t response_handler;
452   void *response_baton;
453
454   /* When REPONSE_HANDLER is invoked, the following fields will be set
455      based on the response header. HANDLER_POOL must be non-NULL for these
456      values to be filled in. SLINE.REASON and LOCATION will be allocated
457      within HANDLER_POOL.  */
458   serf_status_line sline;  /* The parsed Status-Line  */
459   const char *location;  /* The Location: header, if any  */
460
461   /* This function and baton pair allows handling the completion of request.
462    *
463    * The default handler is responsible for the HTTP failure processing.
464    *
465    * If no_fail_on_http_failure_status is not TRUE, then the callback will
466    * return recorded server errors or if there is none and the http status
467    * specifies an error returns an error for that.
468    *
469    * The default baton is the handler itself.
470    */
471   svn_ra_serf__response_done_delegate_t done_delegate;
472   void *done_delegate_baton;
473
474   /* The handler and baton pair to be executed when a non-recoverable error
475    * is detected.  If it is NULL in the presence of an error, an abort() may
476    * be triggered.
477    */
478   svn_ra_serf__response_error_t response_error;
479   void *response_error_baton;
480
481   /* This function and baton pair allows for custom request headers to
482    * be set.
483    *
484    * It will be executed after the request has been set up but before it is
485    * delivered.
486    */
487   svn_ra_serf__request_header_delegate_t header_delegate;
488   void *header_delegate_baton;
489
490   /* This function and baton pair allows a body to be created right before
491    * delivery.
492    *
493    * It will be executed after the request has been set up but before it is
494    * delivered.
495    *
496    * May be NULL if there is no body to send.
497    *
498    */
499   svn_ra_serf__request_body_delegate_t body_delegate;
500   void *body_delegate_baton;
501
502   /* The connection and session to be used for this request. */
503   svn_ra_serf__connection_t *conn;
504   svn_ra_serf__session_t *session;
505
506   /* Internal flag to indicate we've parsed the headers.  */
507   svn_boolean_t reading_body;
508
509   /* When this flag will be set, the core handler will discard any unread
510      portion of the response body. The registered response handler will
511      no longer be called.  */
512   svn_boolean_t discard_body;
513
514   /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL,
515      then the requestor does not care about SLINE and LOCATION.  */
516   apr_pool_t *handler_pool;
517 } svn_ra_serf__handler_t;
518
519
520 /* Run one request and process the response.
521
522    Similar to context_run_wait(), but this creates the request for HANDLER
523    and then waits for it to complete.
524
525    WARNING: context_run_wait() does NOT create a request, whereas this
526    function DOES. Avoid a double-create.  */
527 svn_error_t *
528 svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
529                              apr_pool_t *scratch_pool);
530
531
532 /*
533  * Helper function to queue a request in the @a handler's connection.
534  */
535 void svn_ra_serf__request_create(svn_ra_serf__handler_t *handler);
536
537 /* v2 of the XML parsing functions  */
538
539 /* The XML parsing context.  */
540 typedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t;
541
542
543 /* An opaque structure for the XML parse element/state.  */
544 typedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t;
545
546 /* Called just after the parser moves into ENTERED_STATE. The tag causing
547    the transition is passed in TAG.
548
549    This callback is applied to a parsing context by using the
550    svn_ra_serf__xml_context_customize() function.
551
552    NOTE: this callback, when set, will be invoked on *every* transition.
553    The callback must examine ENTERED_STATE to determine if any action
554    must be taken. The original state is not provided, but must be derived
555    from ENTERED_STATE and/or the TAG causing the transition (if needed).  */
556 typedef svn_error_t *
557 (*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
558                              void *baton,
559                              int entered_state,
560                              const svn_ra_serf__dav_props_t *tag,
561                              apr_pool_t *scratch_pool);
562
563
564 /* Called just before the parser leaves LEAVING_STATE.
565
566    If cdata collection was enabled for this state, then CDATA will be
567    non-NULL and contain the collected cdata.
568
569    If attribute collection was enabled for this state, then ATTRS will
570    contain the attributes collected for this element only, along with
571    any values stored via svn_ra_serf__xml_note().
572
573    Use svn_ra_serf__xml_gather_since() to gather up data from outer states.
574
575    ATTRS is char* -> char*.
576
577    Temporary allocations may be made in SCRATCH_POOL.  */
578 typedef svn_error_t *
579 (*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes,
580                              void *baton,
581                              int leaving_state,
582                              const svn_string_t *cdata,
583                              apr_hash_t *attrs,
584                              apr_pool_t *scratch_pool);
585
586
587 /* Called for all states that are not using the builtin cdata collection.
588    This callback is (only) appropriate for unbounded-size cdata content.
589
590    CURRENT_STATE may be used to decide what to do with the data.
591
592    Temporary allocations may be made in SCRATCH_POOL.  */
593 typedef svn_error_t *
594 (*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
595                             void *baton,
596                             int current_state,
597                             const char *data,
598                             apr_size_t len,
599                             apr_pool_t *scratch_pool);
600
601
602 /* Magic state value for the initial state in a svn_ra_serf__xml_transition_t
603    table */
604 #define XML_STATE_INITIAL 0
605
606 /* State transition table.
607
608    When the XML Context is constructed, it is in state 0. User states are
609    positive integers.
610
611    In a list of transitions, use { 0 } to indicate the end. Specifically,
612    the code looks for NS == NULL.
613
614    The initial state for each transition table is XML_STATE_INITIAL.
615
616    ### more docco
617 */
618 typedef struct svn_ra_serf__xml_transition_t {
619   /* This transition applies when in this state  */
620   int from_state;
621
622   /* And when this tag is observed  */
623   const char *ns;
624   const char *name;
625
626   /* Moving to this state  */
627   int to_state;
628
629   /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
630      be TRUE in order to capture this cdata.  */
631   svn_boolean_t collect_cdata;
632
633   /* Which attributes of NAME should be collected? Terminate with NULL.
634      Maximum of 10 attributes may be collected. Note that attribute
635      namespaces are ignored at this time.
636
637      Attribute names beginning with "?" are optional. Other names must
638      exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised.  */
639   const char *collect_attrs[11];
640
641   /* When NAME is closed, should the callback be invoked?  */
642   svn_boolean_t custom_close;
643
644 } svn_ra_serf__xml_transition_t;
645
646 /* Constructor for svn_ra_serf__handler_t. Initializes a new handler
647    with default settings for SESSION. */
648 svn_ra_serf__handler_t *
649 svn_ra_serf__create_handler(svn_ra_serf__session_t *session,
650                             apr_pool_t *result_pool);
651
652 /* Construct an XML parsing context, based on the TTABLE transition table.
653    As content is parsed, the CLOSED_CB callback will be invoked according
654    to the definition in the table.
655
656    If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
657    event. The callback will need to use the ENTERED_STATE and TAG parameters
658    to decide what it would like to do.
659
660    If CDATA_CB is not NULL, then it will be called for all cdata that is
661    not be automatically collected (based on the transition table record's
662    COLLECT_CDATA flag). It will be called in every state, so the callback
663    must examine the CURRENT_STATE parameter to decide what to do.
664
665    The same BATON value will be passed to all three callbacks.
666
667    The context will be created within RESULT_POOL.  */
668 svn_ra_serf__xml_context_t *
669 svn_ra_serf__xml_context_create(
670   const svn_ra_serf__xml_transition_t *ttable,
671   svn_ra_serf__xml_opened_t opened_cb,
672   svn_ra_serf__xml_closed_t closed_cb,
673   svn_ra_serf__xml_cdata_t cdata_cb,
674   void *baton,
675   apr_pool_t *result_pool);
676
677 /* Verifies if the parsing completed successfully and destroys
678    all subpools. */
679 svn_error_t *
680 svn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx);
681
682 /* Construct a handler with the response function/baton set up to parse
683    a response body using the given XML context. The handler and its
684    internal structures are allocated in RESULT_POOL.
685
686    As part of the handling the http status value is compared to 200, or
687    if EXPECTED_STATUS is not NULL to all the values in EXPECTED_STATUS.
688    EXPECTED_STATUS is expected to be a list of integers ending with a 0
689    that lives at least as long as RESULT_POOL. If the status doesn't
690    match the request has failed and will be parsed as en error response.
691
692    This also initializes HANDLER_POOL to the given RESULT_POOL.  */
693 svn_ra_serf__handler_t *
694 svn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session,
695                                   svn_ra_serf__xml_context_t *xmlctx,
696                                   const int *expected_status,
697                                   apr_pool_t *result_pool);
698
699
700 /* Allocated within XES->STATE_POOL. Changes are not allowd (callers
701    should make a deep copy if they need to make changes).
702
703    The resulting hash maps char* names to char* values.  */
704 apr_hash_t *
705 svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
706                               int stop_state);
707
708
709 /* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
710    The name and value will be copied into the target state's pool.
711
712    These values will be available to the CLOSED_CB for the target state,
713    or part of the gathered state via xml_gather_since().
714
715    Typically, this function is used by a child state's close callback,
716    or within an opening callback to store additional data.
717
718    Note: if the state is not found, then a programmer error has occurred,
719    so the function will invoke SVN_ERR_MALFUNCTION().  */
720 void
721 svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
722                       int state,
723                       const char *name,
724                       const char *value);
725
726
727 /* Returns XES->STATE_POOL for allocating structures that should live
728    as long as the state identified by XES.
729
730    Note: a state pool is created upon demand, so only use this function
731    when memory is required for a given state.  */
732 apr_pool_t *
733 svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
734
735 /*
736  * Parses a server-side error message into a local Subversion error.
737  */
738 struct svn_ra_serf__server_error_t {
739   apr_pool_t *pool;
740
741   /* XML parser and namespace used to parse the remote response */
742   svn_ra_serf__xml_context_t *xmlctx;
743
744   svn_ra_serf__response_handler_t response_handler;
745   void *response_baton;
746
747   /* The partial errors to construct the final error from */
748   apr_array_header_t *items;
749
750   /* The hooked handler */
751   svn_ra_serf__handler_t *handler;
752 };
753
754 /*
755  * Handler that discards the entire @a response body associated with a
756  * @a request.  Implements svn_ra_serf__response_handler_t.
757  *
758  * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an
759  * error is detected, it will be populated for later detection.
760  *
761  * All temporary allocations will be made in a @a pool.
762  */
763 svn_error_t *
764 svn_ra_serf__handle_discard_body(serf_request_t *request,
765                                  serf_bucket_t *response,
766                                  void *baton,
767                                  apr_pool_t *pool);
768
769
770 /*
771  * Handler that retrieves the embedded XML multistatus response from the
772  * the @a RESPONSE body associated with a @a REQUEST.
773  *
774  * Implements svn_ra_serf__response_handler_t.
775  *
776  * The @a BATON should be of type svn_ra_serf__handler_t. When the request
777  * is complete, the handler's DONE flag will be set to TRUE.
778  *
779  * All temporary allocations will be made in a @a scratch_pool.
780  */
781 svn_error_t *
782 svn_ra_serf__handle_multistatus_only(serf_request_t *request,
783                                      serf_bucket_t *response,
784                                      void *baton,
785                                      apr_pool_t *scratch_pool);
786
787
788 /* Handler that expects an empty body.
789
790    If a body IS present, and it is text/xml, then it will be parsed for
791    a server-side error.
792
793    BATON should be the svn_ra_serf__handler_t running REQUEST.
794
795    Status line information will be in HANDLER->SLINE.
796
797    Any parsed errors will be left in HANDLER->SERVER_ERROR. That member
798    may be NULL if no body was present, or a problem occurred trying to
799    parse the body.
800
801    All temporary allocations will be made in SCRATCH_POOL.  */
802 svn_error_t *
803 svn_ra_serf__expect_empty_body(serf_request_t *request,
804                                serf_bucket_t *response,
805                                void *baton,
806                                apr_pool_t *scratch_pool);
807
808
809 /*
810  * This function sets up error parsing for an existing request
811  */
812 svn_error_t *
813 svn_ra_serf__setup_error_parsing(svn_ra_serf__server_error_t **server_err,
814                                  svn_ra_serf__handler_t *handler,
815                                  svn_boolean_t expect_207_only,
816                                  apr_pool_t *result_pool,
817                                  apr_pool_t *scratch_pool);
818
819 /*
820  * Forwards response data to the server error parser
821  */
822 svn_error_t *
823 svn_ra_serf__handle_server_error(svn_ra_serf__server_error_t *server_error,
824                                  svn_ra_serf__handler_t *handler,
825                                  serf_request_t *request,
826                                  serf_bucket_t *response,
827                                  apr_status_t *serf_status,
828                                  apr_pool_t *scratch_pool);
829
830 /*
831  * Creates the svn_error_t * instance from the error recorded in
832  * HANDLER->server_error
833  */
834 svn_error_t *
835 svn_ra_serf__server_error_create(svn_ra_serf__handler_t *handler,
836                                  apr_pool_t *scratch_pool);
837
838 /* serf_response_handler_t implementation that completely discards
839  * the response.
840  *
841  * All temporary allocations will be made in @a pool.
842  */
843 apr_status_t
844 svn_ra_serf__response_discard_handler(serf_request_t *request,
845                                       serf_bucket_t *response,
846                                       void *baton,
847                                       apr_pool_t *pool);
848
849
850 /*
851  * Add the appropriate serf buckets to @a agg_bucket represented by
852  * the XML * @a tag and @a value.
853  *
854  * The bucket will be allocated from @a bkt_alloc.
855  */
856 void
857 svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket,
858                              const char *tag,
859                              const char *value,
860                              serf_bucket_alloc_t *bkt_alloc);
861
862 /*
863  * Add the appropriate serf buckets to AGG_BUCKET with standard XML header:
864  *  <?xml version="1.0" encoding="utf-8"?>
865  *
866  * The bucket will be allocated from BKT_ALLOC.
867  */
868 void
869 svn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket,
870                                     serf_bucket_alloc_t *bkt_alloc);
871
872 /*
873  * Add the appropriate serf buckets to AGG_BUCKET representing the XML
874  * open tag with name TAG.
875  *
876  * Take the tag's attributes from varargs, a NULL-terminated list of
877  * alternating <tt>char *</tt> key and <tt>char *</tt> val.  Attribute
878  * will be ignored if it's value is NULL.
879  *
880  * NOTE: Callers are responsible for XML-escaping attribute values as
881  * necessary.
882  *
883  * The bucket will be allocated from BKT_ALLOC.
884  */
885 void
886 svn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket,
887                                   serf_bucket_alloc_t *bkt_alloc,
888                                   const char *tag,
889                                   ...) SVN_NEEDS_SENTINEL_NULL;
890
891 /*
892  * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close
893  * with name TAG.
894  *
895  * The bucket will be allocated from BKT_ALLOC.
896  */
897 void
898 svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket,
899                                    serf_bucket_alloc_t *bkt_alloc,
900                                    const char *tag);
901
902 /* Add the appropriate serf buckets to AGG_BUCKET representing the XML
903  * open tag with name TAG, and then immediately closes the tag using the />
904  * notation
905  */
906 void
907 svn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket,
908                                    serf_bucket_alloc_t *bkt_alloc,
909                                    const char *tag,
910                                    ...) SVN_NEEDS_SENTINEL_NULL;
911
912 /*
913  * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped
914  * version of DATA.
915  *
916  * The bucket will be allocated from BKT_ALLOC.
917  */
918 void
919 svn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket,
920                                    serf_bucket_alloc_t *bkt_alloc,
921                                    const char *data, apr_size_t len);
922
923
924 /** PROPFIND-related functions **/
925
926 /* Removes all non regular properties from PROPS */
927 void
928 svn_ra_serf__keep_only_regular_props(apr_hash_t *props,
929                                      apr_pool_t *scratch_pool);
930
931
932 /* Callback used via svn_ra_serf__deliver_props2 */
933 typedef svn_error_t *
934 (*svn_ra_serf__prop_func_t)(void *baton,
935                             const char *path,
936                             const char *ns,
937                             const char *name,
938                             const svn_string_t *value,
939                             apr_pool_t *scratch_pool);
940
941 /*
942  * Implementation of svn_ra_serf__prop_func_t that just delivers svn compatible
943  * properties  in the apr_hash_t * that is used as baton.
944  */
945 svn_error_t *
946 svn_ra_serf__deliver_svn_props(void *baton,
947                                const char *path,
948                                const char *ns,
949                                const char *name,
950                                const svn_string_t *value,
951                                apr_pool_t *scratch_pool);
952
953 /*
954  * This function will create a handler for a PROPFIND request, which will deliver
955  * properties to PROP_FUNC() with PROP_BATON for the properties listed in LOOKUP_PROPS
956  * at URL for DEPTH ("0","1","infinity").
957  */
958 svn_error_t *
959 svn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **handler,
960                                      svn_ra_serf__session_t *session,
961                                      const char *path,
962                                      svn_revnum_t rev,
963                                      const char *depth,
964                                      const svn_ra_serf__dav_props_t *find_props,
965                                      svn_ra_serf__prop_func_t prop_func,
966                                      void *prop_func_baton,
967                                      apr_pool_t *result_pool);
968
969
970 /* Using SESSION, fetch the properties specified by WHICH_PROPS using CONN
971    for URL at REVISION. The resulting properties are placed into a 2-level
972    hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which
973    is allocated in RESULT_POOL.
974
975    If REVISION is SVN_INVALID_REVNUM, then the properties are fetched
976    from HEAD for URL.
977
978    This function performs the request synchronously.
979
980    Temporary allocations are made in SCRATCH_POOL.  */
981 svn_error_t *
982 svn_ra_serf__fetch_node_props(apr_hash_t **results,
983                               svn_ra_serf__session_t *session,
984                               const char *url,
985                               svn_revnum_t revision,
986                               const svn_ra_serf__dav_props_t *which_props,
987                               apr_pool_t *result_pool,
988                               apr_pool_t *scratch_pool);
989
990
991 /* Using SESSION, fetch a DAV: property from the resource identified by URL
992    within REVISION. The PROPNAME may be one of:
993
994      "checked-in"
995      "href"
996
997    The resulting value will be allocated in RESULT_POOL, and may be NULL
998    if the property does not exist (note: "href" always exists).
999
1000    This function performs the request synchronously.
1001
1002    Temporary allocations are made in SCRATCH_POOL.  */
1003 svn_error_t *
1004 svn_ra_serf__fetch_dav_prop(const char **value,
1005                             svn_ra_serf__session_t *session,
1006                             const char *url,
1007                             svn_revnum_t revision,
1008                             const char *propname,
1009                             apr_pool_t *result_pool,
1010                             apr_pool_t *scratch_pool);
1011
1012 /* Map a property name, as passed over the wire, into its corresponding
1013    Subversion-internal name. The returned name will be a static value,
1014    or allocated within RESULT_POOL.
1015
1016    If the property should be ignored (eg. some DAV properties), then NULL
1017    will be returned.  */
1018 const char *
1019 svn_ra_serf__svnname_from_wirename(const char *ns,
1020                                    const char *name,
1021                                    apr_pool_t *result_pool);
1022
1023 /** MERGE-related functions **/
1024
1025 void
1026 svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
1027                                    const char *parent,
1028                                    serf_bucket_t *body,
1029                                    serf_bucket_alloc_t *alloc,
1030                                    apr_pool_t *pool);
1031
1032 /* Create an MERGE request aimed at the SESSION url, requesting the
1033    merge of the resource identified by MERGE_RESOURCE_URL.
1034    LOCK_TOKENS is a hash mapping paths to lock tokens owned by the
1035    client.  If KEEP_LOCKS is set, instruct the server to not release
1036    locks set on the paths included in this commit.  */
1037 svn_error_t *
1038 svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
1039                        svn_ra_serf__session_t *session,
1040                        const char *merge_resource_url,
1041                        apr_hash_t *lock_tokens,
1042                        svn_boolean_t keep_locks,
1043                        apr_pool_t *result_pool,
1044                        apr_pool_t *scratch_pool);
1045
1046
1047 /** OPTIONS-related functions **/
1048
1049 /* When running with a proxy, we may need to detect and correct for problems.
1050    This probing function will send a simple OPTIONS request to detect problems
1051    with the connection.  */
1052 svn_error_t *
1053 svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
1054                          apr_pool_t *scratch_pool);
1055
1056
1057 /* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
1058    current youngest revnum, returning it in *YOUNGEST.
1059
1060    (the revnum is headers of the OPTIONS response)
1061
1062    This function performs the request synchronously.
1063
1064    All temporary allocations will be made in SCRATCH_POOL.  */
1065 svn_error_t *
1066 svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
1067                                     svn_ra_serf__session_t *session,
1068                                     apr_pool_t *scratch_pool);
1069
1070
1071 /* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the
1072    activity collection set and return it in *ACTIVITY_URL, allocated
1073    from RESULT_POOL.
1074
1075    (the activity-collection-set is in the body of the OPTIONS response)
1076
1077    This function performs the request synchronously.
1078
1079    All temporary allocations will be made in SCRATCH_POOL.  */
1080 svn_error_t *
1081 svn_ra_serf__v1_get_activity_collection(const char **activity_url,
1082                                         svn_ra_serf__session_t *session,
1083                                         apr_pool_t *result_pool,
1084                                         apr_pool_t *scratch_pool);
1085
1086
1087 /* Set @a VCC_URL to the default VCC for our repository based on @a
1088  * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and
1089  * repository root URLs are cached in @a SESSION.
1090  *
1091  * All temporary allocations will be made in @a SCRATCH_POOL. */
1092 svn_error_t *
1093 svn_ra_serf__discover_vcc(const char **vcc_url,
1094                           svn_ra_serf__session_t *session,
1095                           apr_pool_t *scratch_pool);
1096
1097 /* Set @a REPORT_TARGET to the URI of the resource at which generic
1098  * (path-agnostic) REPORTs should be aimed for @a SESSION.
1099  *
1100  * All temporary allocations will be made in @a POOL.
1101  */
1102 svn_error_t *
1103 svn_ra_serf__report_resource(const char **report_target,
1104                              svn_ra_serf__session_t *session,
1105                              apr_pool_t *pool);
1106
1107 /* Set @a REL_PATH to a path (not URI-encoded) relative to the root of
1108  * the repository pointed to by @a SESSION, based on original path
1109  * (URI-encoded) @a ORIG_PATH.  Use @a CONN for any required network
1110  * communications if it is non-NULL; otherwise use the default
1111  * connection.  Use POOL for allocations.  */
1112 svn_error_t *
1113 svn_ra_serf__get_relative_path(const char **rel_path,
1114                                const char *orig_path,
1115                                svn_ra_serf__session_t *session,
1116                                apr_pool_t *pool);
1117
1118
1119 /* Using the default connection in SESSION (conns[0]), get the youngest
1120    revnum from the server, returning it in *YOUNGEST.
1121
1122    This function operates synchronously.
1123
1124    All temporary allocations are performed in SCRATCH_POOL.  */
1125 svn_error_t *
1126 svn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest,
1127                                  svn_ra_serf__session_t *session,
1128                                  apr_pool_t *scratch_pool);
1129
1130
1131 /* Generate a revision-stable URL.
1132
1133    The RA APIs all refer to user/public URLs that float along with the
1134    youngest revision. In many cases, we do NOT want to work with that URL
1135    since it can change from one moment to the next. Especially if we
1136    attempt to operation against multiple floating URLs -- we could end up
1137    referring to two separate revisions.
1138
1139    The DAV RA provider(s) solve this by generating a URL that is specific
1140    to a revision by using a URL into a "baseline collection".
1141
1142    For a specified SESSION, generate a revision-stable URL for URL at
1143    REVISION. If REVISION is    SVN_INVALID_REVNUM, then the stable URL will
1144    refer to the youngest revision at the time this function was called.
1145
1146    If URL is NULL, then the session root will be used.
1147
1148    The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL.
1149
1150    If LATEST_REVNUM is not NULL, then the revision used will be placed into
1151    *LATEST_REVNUM. That will be equal to youngest, or the given REVISION.
1152
1153    This function operates synchronously, if any communication to the server
1154    is required. Communication is needed if REVISION is SVN_INVALID_REVNUM
1155    (to get the current youngest revnum), or if the specified REVISION is not
1156    (yet) in our cache of baseline collections.
1157
1158    All temporary allocations are performed in SCRATCH_POOL.  */
1159 svn_error_t *
1160 svn_ra_serf__get_stable_url(const char **stable_url,
1161                             svn_revnum_t *latest_revnum,
1162                             svn_ra_serf__session_t *session,
1163                             const char *url,
1164                             svn_revnum_t revision,
1165                             apr_pool_t *result_pool,
1166                             apr_pool_t *scratch_pool);
1167
1168
1169 /** RA functions **/
1170
1171 /* Implements svn_ra__vtable_t.reparent(). */
1172 svn_error_t *
1173 svn_ra_serf__reparent(svn_ra_session_t *ra_session,
1174                       const char *url,
1175                       apr_pool_t *pool);
1176
1177 /* Implements svn_ra__vtable_t.rev_prop(). */
1178 svn_error_t *
1179 svn_ra_serf__rev_prop(svn_ra_session_t *session,
1180                       svn_revnum_t rev,
1181                       const char *name,
1182                       svn_string_t **value,
1183                       apr_pool_t *pool);
1184
1185 /* Implements svn_ra__vtable_t.get_log(). */
1186 svn_error_t *
1187 svn_ra_serf__get_log(svn_ra_session_t *session,
1188                      const apr_array_header_t *paths,
1189                      svn_revnum_t start,
1190                      svn_revnum_t end,
1191                      int limit,
1192                      svn_boolean_t discover_changed_paths,
1193                      svn_boolean_t strict_node_history,
1194                      svn_boolean_t include_merged_revisions,
1195                      const apr_array_header_t *revprops,
1196                      svn_log_entry_receiver_t receiver,
1197                      void *receiver_baton,
1198                      apr_pool_t *pool);
1199
1200 /* Implements svn_ra__vtable_t.check_path(). */
1201 svn_error_t *
1202 svn_ra_serf__check_path(svn_ra_session_t *ra_session,
1203                         const char *rel_path,
1204                         svn_revnum_t revision,
1205                         svn_node_kind_t *kind,
1206                         apr_pool_t *pool);
1207
1208 /* Implements svn_ra__vtable_t.stat(). */
1209 svn_error_t *
1210 svn_ra_serf__stat(svn_ra_session_t *ra_session,
1211                   const char *rel_path,
1212                   svn_revnum_t revision,
1213                   svn_dirent_t **dirent,
1214                   apr_pool_t *pool);
1215
1216 /* Implements svn_ra__vtable_t.get_locations(). */
1217 svn_error_t *
1218 svn_ra_serf__get_locations(svn_ra_session_t *session,
1219                            apr_hash_t **locations,
1220                            const char *path,
1221                            svn_revnum_t peg_revision,
1222                            const apr_array_header_t *location_revisions,
1223                            apr_pool_t *pool);
1224
1225 /* Implements svn_ra__vtable_t.get_location_segments(). */
1226 svn_error_t *
1227 svn_ra_serf__get_location_segments(svn_ra_session_t *session,
1228                                    const char *path,
1229                                    svn_revnum_t peg_revision,
1230                                    svn_revnum_t start_rev,
1231                                    svn_revnum_t end_rev,
1232                                    svn_location_segment_receiver_t receiver,
1233                                    void *receiver_baton,
1234                                    apr_pool_t *pool);
1235
1236 /* Implements svn_ra__vtable_t.do_diff(). */
1237 svn_error_t *
1238 svn_ra_serf__do_diff(svn_ra_session_t *session,
1239                      const svn_ra_reporter3_t **reporter,
1240                      void **report_baton,
1241                      svn_revnum_t revision,
1242                      const char *diff_target,
1243                      svn_depth_t depth,
1244                      svn_boolean_t ignore_ancestry,
1245                      svn_boolean_t text_deltas,
1246                      const char *versus_url,
1247                      const svn_delta_editor_t *diff_editor,
1248                      void *diff_baton,
1249                      apr_pool_t *pool);
1250
1251 /* Implements svn_ra__vtable_t.do_status(). */
1252 svn_error_t *
1253 svn_ra_serf__do_status(svn_ra_session_t *ra_session,
1254                        const svn_ra_reporter3_t **reporter,
1255                        void **report_baton,
1256                        const char *status_target,
1257                        svn_revnum_t revision,
1258                        svn_depth_t depth,
1259                        const svn_delta_editor_t *status_editor,
1260                        void *status_baton,
1261                        apr_pool_t *pool);
1262
1263 /* Implements svn_ra__vtable_t.do_update(). */
1264 svn_error_t *
1265 svn_ra_serf__do_update(svn_ra_session_t *ra_session,
1266                        const svn_ra_reporter3_t **reporter,
1267                        void **report_baton,
1268                        svn_revnum_t revision_to_update_to,
1269                        const char *update_target,
1270                        svn_depth_t depth,
1271                        svn_boolean_t send_copyfrom_args,
1272                        svn_boolean_t ignore_ancestry,
1273                        const svn_delta_editor_t *update_editor,
1274                        void *update_baton,
1275                        apr_pool_t *result_pool,
1276                        apr_pool_t *scratch_pool);
1277
1278 /* Implements svn_ra__vtable_t.do_switch(). */
1279 svn_error_t *
1280 svn_ra_serf__do_switch(svn_ra_session_t *ra_session,
1281                        const svn_ra_reporter3_t **reporter,
1282                        void **report_baton,
1283                        svn_revnum_t revision_to_switch_to,
1284                        const char *switch_target,
1285                        svn_depth_t depth,
1286                        const char *switch_url,
1287                        svn_boolean_t send_copyfrom_args,
1288                        svn_boolean_t ignore_ancestry,
1289                        const svn_delta_editor_t *switch_editor,
1290                        void *switch_baton,
1291                        apr_pool_t *result_pool,
1292                        apr_pool_t *scratch_pool);
1293
1294 /* Implements svn_ra__vtable_t.get_file_revs(). */
1295 svn_error_t *
1296 svn_ra_serf__get_file_revs(svn_ra_session_t *session,
1297                            const char *path,
1298                            svn_revnum_t start,
1299                            svn_revnum_t end,
1300                            svn_boolean_t include_merged_revisions,
1301                            svn_file_rev_handler_t handler,
1302                            void *handler_baton,
1303                            apr_pool_t *pool);
1304
1305 /* Implements svn_ra__vtable_t.get_dated_revision(). */
1306 svn_error_t *
1307 svn_ra_serf__get_dated_revision(svn_ra_session_t *session,
1308                                 svn_revnum_t *revision,
1309                                 apr_time_t tm,
1310                                 apr_pool_t *pool);
1311
1312 /* Implements svn_ra__vtable_t.get_commit_editor().
1313  *
1314  * Note: Like other commit editors, the returned editor requires that the
1315  * @c copyfrom_path parameter passed to its @c add_file and @c add_directory
1316  * methods is a URL, not a relative path.
1317  */
1318 svn_error_t *
1319 svn_ra_serf__get_commit_editor(svn_ra_session_t *session,
1320                                const svn_delta_editor_t **editor,
1321                                void **edit_baton,
1322                                apr_hash_t *revprop_table,
1323                                svn_commit_callback2_t callback,
1324                                void *callback_baton,
1325                                apr_hash_t *lock_tokens,
1326                                svn_boolean_t keep_locks,
1327                                apr_pool_t *pool);
1328
1329 /* Implements svn_ra__vtable_t.get_file(). */
1330 svn_error_t *
1331 svn_ra_serf__get_file(svn_ra_session_t *session,
1332                       const char *path,
1333                       svn_revnum_t revision,
1334                       svn_stream_t *stream,
1335                       svn_revnum_t *fetched_rev,
1336                       apr_hash_t **props,
1337                       apr_pool_t *pool);
1338
1339 /* Implements svn_ra__vtable_t.get_dir(). */
1340 svn_error_t *
1341 svn_ra_serf__get_dir(svn_ra_session_t *ra_session,
1342                      apr_hash_t **dirents,
1343                      svn_revnum_t *fetched_rev,
1344                      apr_hash_t **ret_props,
1345                      const char *rel_path,
1346                      svn_revnum_t revision,
1347                      apr_uint32_t dirent_fields,
1348                      apr_pool_t *result_pool);
1349
1350 /* Implements svn_ra__vtable_t.change_rev_prop(). */
1351 svn_error_t *
1352 svn_ra_serf__change_rev_prop(svn_ra_session_t *session,
1353                              svn_revnum_t rev,
1354                              const char *name,
1355                              const svn_string_t *const *old_value_p,
1356                              const svn_string_t *value,
1357                              apr_pool_t *pool);
1358
1359 /* Implements svn_ra__vtable_t.replay(). */
1360 svn_error_t *
1361 svn_ra_serf__replay(svn_ra_session_t *ra_session,
1362                     svn_revnum_t revision,
1363                     svn_revnum_t low_water_mark,
1364                     svn_boolean_t text_deltas,
1365                     const svn_delta_editor_t *editor,
1366                     void *edit_baton,
1367                     apr_pool_t *pool);
1368
1369 /* Implements svn_ra__vtable_t.replay_range(). */
1370 svn_error_t *
1371 svn_ra_serf__replay_range(svn_ra_session_t *ra_session,
1372                           svn_revnum_t start_revision,
1373                           svn_revnum_t end_revision,
1374                           svn_revnum_t low_water_mark,
1375                           svn_boolean_t send_deltas,
1376                           svn_ra_replay_revstart_callback_t revstart_func,
1377                           svn_ra_replay_revfinish_callback_t revfinish_func,
1378                           void *replay_baton,
1379                           apr_pool_t *pool);
1380
1381 /* Implements svn_ra__vtable_t.lock(). */
1382 svn_error_t *
1383 svn_ra_serf__lock(svn_ra_session_t *ra_session,
1384                   apr_hash_t *path_revs,
1385                   const char *comment,
1386                   svn_boolean_t force,
1387                   svn_ra_lock_callback_t lock_func,
1388                   void *lock_baton,
1389                   apr_pool_t *pool);
1390
1391 /* Implements svn_ra__vtable_t.unlock(). */
1392 svn_error_t *
1393 svn_ra_serf__unlock(svn_ra_session_t *ra_session,
1394                     apr_hash_t *path_tokens,
1395                     svn_boolean_t force,
1396                     svn_ra_lock_callback_t lock_func,
1397                     void *lock_baton,
1398                     apr_pool_t *pool);
1399
1400 /* Implements svn_ra__vtable_t.get_lock(). */
1401 svn_error_t *
1402 svn_ra_serf__get_lock(svn_ra_session_t *ra_session,
1403                       svn_lock_t **lock,
1404                       const char *path,
1405                       apr_pool_t *pool);
1406
1407 /* Implements svn_ra__vtable_t.get_locks(). */
1408 svn_error_t *
1409 svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
1410                        apr_hash_t **locks,
1411                        const char *path,
1412                        svn_depth_t depth,
1413                        apr_pool_t *pool);
1414
1415 /* Request a mergeinfo-report from the URL attached to SESSION,
1416    and fill in the MERGEINFO hash with the results.
1417
1418    Implements svn_ra__vtable_t.get_mergeinfo().
1419  */
1420 svn_error_t *
1421 svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
1422                            apr_hash_t **mergeinfo,
1423                            const apr_array_header_t *paths,
1424                            svn_revnum_t revision,
1425                            svn_mergeinfo_inheritance_t inherit,
1426                            svn_boolean_t include_descendants,
1427                            apr_pool_t *pool);
1428
1429 /* Exchange capabilities with the server, by sending an OPTIONS
1430  * request announcing the client's capabilities, and by filling
1431  * SERF_SESS->capabilities with the server's capabilities as read from
1432  * the response headers.  Use POOL only for temporary allocation.
1433  *
1434  * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to
1435  * report a server-dictated redirect or relocation (HTTP 301 or 302
1436  * error codes), setting *CORRECTED_URL to the value of the corrected
1437  * repository URL.  Otherwise, such responses from the server will
1438  * generate an error.  (In either case, no capabilities are exchanged
1439  * if there is, in fact, such a response from the server.)
1440  */
1441 svn_error_t *
1442 svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess,
1443                                    const char **corrected_url,
1444                                    apr_pool_t *result_pool,
1445                                    apr_pool_t *scratch_pool);
1446
1447 /* Implements svn_ra__vtable_t.has_capability(). */
1448 svn_error_t *
1449 svn_ra_serf__has_capability(svn_ra_session_t *ra_session,
1450                             svn_boolean_t *has,
1451                             const char *capability,
1452                             apr_pool_t *pool);
1453
1454 /* Implements svn_ra__vtable_t.get_deleted_rev(). */
1455 svn_error_t *
1456 svn_ra_serf__get_deleted_rev(svn_ra_session_t *session,
1457                              const char *path,
1458                              svn_revnum_t peg_revision,
1459                              svn_revnum_t end_revision,
1460                              svn_revnum_t *revision_deleted,
1461                              apr_pool_t *pool);
1462
1463 /* Implements the get_inherited_props RA layer function. */
1464 svn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session,
1465                                                apr_array_header_t **iprops,
1466                                                const char *path,
1467                                                svn_revnum_t revision,
1468                                                apr_pool_t *result_pool,
1469                                                apr_pool_t *scratch_pool);
1470
1471 /* Implements svn_ra__vtable_t.get_repos_root(). */
1472 svn_error_t *
1473 svn_ra_serf__get_repos_root(svn_ra_session_t *ra_session,
1474                             const char **url,
1475                             apr_pool_t *pool);
1476
1477 /* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */
1478 svn_error_t *
1479 svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
1480                                     svn_delta_shim_callbacks_t *callbacks);
1481
1482 /*** Authentication handler declarations ***/
1483
1484 /**
1485  * Callback function that loads the credentials for Basic and Digest
1486  * authentications, both for server and proxy authentication.
1487  */
1488 apr_status_t
1489 svn_ra_serf__credentials_callback(char **username, char **password,
1490                                   serf_request_t *request, void *baton,
1491                                   int code, const char *authn_type,
1492                                   const char *realm,
1493                                   apr_pool_t *pool);
1494
1495
1496 /*** General utility functions ***/
1497
1498 /**
1499  * Convert an HTTP STATUS_CODE resulting from a WebDAV request against
1500  * PATH to the relevant error code.  Use the response-supplied LOCATION
1501  * where it necessary.
1502  *
1503  * Returns SVN_NO_ERROR if sline doesn't specify an error condition
1504  */
1505 svn_error_t *
1506 svn_ra_serf__error_on_status(serf_status_line sline,
1507                              const char *path,
1508                              const char *location);
1509
1510 /**
1511  * Convert an unexpected HTTP STATUS_CODE from a request to the relevant error
1512  * code. Unlike svn_ra_serf__error_on_status() this function creates an error
1513  * for any result
1514  */
1515 svn_error_t *
1516 svn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler);
1517
1518
1519 /* ###? */
1520 svn_error_t *
1521 svn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf,
1522                                 serf_bucket_t *bkt,
1523                                 apr_pool_t *result_pool,
1524                                 apr_pool_t *scratch_pool);
1525
1526 /* ###? */
1527 serf_bucket_t *
1528 svn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf,
1529                               serf_bucket_alloc_t *allocator,
1530                               apr_pool_t *result_pool,
1531                               apr_pool_t *scratch_pool);
1532
1533 /** Wrap STATUS from an serf function. If STATUS is not serf error code,
1534   * this is equivalent to svn_error_wrap_apr().
1535  */
1536 svn_error_t *
1537 svn_ra_serf__wrap_err(apr_status_t status,
1538                       const char *fmt,
1539                       ...);
1540
1541 /* Create a bucket that just returns DATA (with length LEN) and then returns
1542    the APR_EAGAIN status */
1543 serf_bucket_t *
1544 svn_ra_serf__create_bucket_with_eagain(const char *data,
1545                                        apr_size_t len,
1546                                        serf_bucket_alloc_t *allocator);
1547
1548 /* Parse a given URL_STR, fill in all supplied fields of URI
1549  * structure.
1550  *
1551  * This function is a compatibility wrapper around apr_uri_parse().
1552  * Different apr-util versions set apr_uri_t.path to either NULL or ""
1553  * for root paths, and serf expects to see "/". This function always
1554  * sets URI.path to "/" for these paths. */
1555 svn_error_t *
1556 svn_ra_serf__uri_parse(apr_uri_t *uri,
1557                        const char *url_str,
1558                        apr_pool_t *result_pool);
1559
1560
1561 #if defined(SVN_DEBUG)
1562 /* Wrapper macros to collect file and line information */
1563 #define svn_ra_serf__wrap_err \
1564   (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err))
1565
1566 #endif
1567
1568 #ifdef __cplusplus
1569 }
1570 #endif /* __cplusplus */
1571
1572 #endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */