ra_serf.h revision 251881
1251881Speter/*
2251881Speter * ra_serf.h : Private declarations for the Serf-based DAV RA module.
3251881Speter *
4251881Speter * ====================================================================
5251881Speter *    Licensed to the Apache Software Foundation (ASF) under one
6251881Speter *    or more contributor license agreements.  See the NOTICE file
7251881Speter *    distributed with this work for additional information
8251881Speter *    regarding copyright ownership.  The ASF licenses this file
9251881Speter *    to you under the Apache License, Version 2.0 (the
10251881Speter *    "License"); you may not use this file except in compliance
11251881Speter *    with the License.  You may obtain a copy of the License at
12251881Speter *
13251881Speter *      http://www.apache.org/licenses/LICENSE-2.0
14251881Speter *
15251881Speter *    Unless required by applicable law or agreed to in writing,
16251881Speter *    software distributed under the License is distributed on an
17251881Speter *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18251881Speter *    KIND, either express or implied.  See the License for the
19251881Speter *    specific language governing permissions and limitations
20251881Speter *    under the License.
21251881Speter * ====================================================================
22251881Speter */
23251881Speter
24251881Speter#ifndef SVN_LIBSVN_RA_SERF_RA_SERF_H
25251881Speter#define SVN_LIBSVN_RA_SERF_RA_SERF_H
26251881Speter
27251881Speter
28251881Speter#include <serf.h>
29251881Speter#include <expat.h>  /* for XML_Parser  */
30251881Speter#include <apr_uri.h>
31251881Speter
32251881Speter#include "svn_types.h"
33251881Speter#include "svn_string.h"
34251881Speter#include "svn_pools.h"
35251881Speter#include "svn_ra.h"
36251881Speter#include "svn_delta.h"
37251881Speter#include "svn_version.h"
38251881Speter#include "svn_dav.h"
39251881Speter#include "svn_dirent_uri.h"
40251881Speter
41251881Speter#include "private/svn_dav_protocol.h"
42251881Speter#include "private/svn_subr_private.h"
43251881Speter#include "private/svn_editor.h"
44251881Speter
45251881Speter#include "blncache.h"
46251881Speter
47251881Speter#ifdef __cplusplus
48251881Speterextern "C" {
49251881Speter#endif /* __cplusplus */
50251881Speter
51251881Speter
52251881Speter/* Enforce the minimum version of serf. */
53251881Speter#if !SERF_VERSION_AT_LEAST(1, 2, 1)
54251881Speter#error Please update your version of serf to at least 1.2.1.
55251881Speter#endif
56251881Speter
57251881Speter/** Use this to silence compiler warnings about unused parameters. */
58251881Speter#define UNUSED_CTX(x) ((void)(x))
59251881Speter
60251881Speter/** Our User-Agent string. */
61251881Speter#define USER_AGENT "SVN/" SVN_VER_NUMBER " (" SVN_BUILD_TARGET ")" \
62251881Speter                   " serf/" \
63251881Speter                   APR_STRINGIFY(SERF_MAJOR_VERSION) "." \
64251881Speter                   APR_STRINGIFY(SERF_MINOR_VERSION) "." \
65251881Speter                   APR_STRINGIFY(SERF_PATCH_VERSION)
66251881Speter
67251881Speter/** Wait duration (in microseconds) used in calls to serf_context_run() */
68251881Speter#define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000
69251881Speter
70251881Speter
71251881Speter
72251881Speter/* Forward declarations. */
73251881Spetertypedef struct svn_ra_serf__session_t svn_ra_serf__session_t;
74251881Speter
75251881Speter/* A serf connection and optionally associated SSL context.  */
76251881Spetertypedef struct svn_ra_serf__connection_t {
77251881Speter  /* Our connection to a server. */
78251881Speter  serf_connection_t *conn;
79251881Speter
80251881Speter  /* Bucket allocator for this connection. */
81251881Speter  serf_bucket_alloc_t *bkt_alloc;
82251881Speter
83251881Speter  /* Collected cert failures in chain.  */
84251881Speter  int server_cert_failures;
85251881Speter
86251881Speter  /* What was the last HTTP status code we got on this connection? */
87251881Speter  int last_status_code;
88251881Speter
89251881Speter  /* Optional SSL context for this connection. */
90251881Speter  serf_ssl_context_t *ssl_context;
91251881Speter  svn_auth_iterstate_t *ssl_client_auth_state;
92251881Speter  svn_auth_iterstate_t *ssl_client_pw_auth_state;
93251881Speter
94251881Speter  svn_ra_serf__session_t *session;
95251881Speter
96251881Speter} svn_ra_serf__connection_t;
97251881Speter
98251881Speter/** Maximum value we'll allow for the http-max-connections config option.
99251881Speter *
100251881Speter * Note: minimum 2 connections are required for ra_serf to function
101251881Speter * correctly!
102251881Speter */
103251881Speter#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8
104251881Speter
105251881Speter/*
106251881Speter * The master serf RA session.
107251881Speter *
108251881Speter * This is stored in the ra session ->priv field.
109251881Speter */
110251881Speterstruct svn_ra_serf__session_t {
111251881Speter  /* Pool for allocations during this session */
112251881Speter  apr_pool_t *pool;
113251881Speter
114251881Speter  /* The current context */
115251881Speter  serf_context_t *context;
116251881Speter
117251881Speter  /* The maximum number of connections we'll use for parallelized
118251881Speter     fetch operations (updates, etc.) */
119251881Speter  apr_int64_t max_connections;
120251881Speter
121251881Speter  /* Are we using ssl */
122251881Speter  svn_boolean_t using_ssl;
123251881Speter
124251881Speter  /* Should we ask for compressed responses? */
125251881Speter  svn_boolean_t using_compression;
126251881Speter
127251881Speter  /* The user agent string */
128251881Speter  const char *useragent;
129251881Speter
130251881Speter  /* The current connection */
131251881Speter  svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT];
132251881Speter  int num_conns;
133251881Speter  int cur_conn;
134251881Speter
135251881Speter  /* The URL that was passed into _open() */
136251881Speter  apr_uri_t session_url;
137251881Speter  const char *session_url_str;
138251881Speter
139251881Speter  /* The actual discovered root; may be NULL until we know it. */
140251881Speter  apr_uri_t repos_root;
141251881Speter  const char *repos_root_str;
142251881Speter
143251881Speter  /* The server is not Apache/mod_dav_svn (directly) and only supports
144251881Speter     HTTP/1.0. Thus, we cannot send chunked requests.  */
145251881Speter  svn_boolean_t http10;
146251881Speter
147251881Speter  /* Our Version-Controlled-Configuration; may be NULL until we know it. */
148251881Speter  const char *vcc_url;
149251881Speter
150251881Speter  /* Authentication related properties. */
151251881Speter  svn_auth_iterstate_t *auth_state;
152251881Speter  int auth_attempts;
153251881Speter
154251881Speter  /* Callback functions to get info from WC */
155251881Speter  const svn_ra_callbacks2_t *wc_callbacks;
156251881Speter  void *wc_callback_baton;
157251881Speter
158251881Speter  /* Callback function to send progress info to the client */
159251881Speter  svn_ra_progress_notify_func_t progress_func;
160251881Speter  void *progress_baton;
161251881Speter
162251881Speter  /* Callback function to handle cancellation */
163251881Speter  svn_cancel_func_t cancel_func;
164251881Speter  void *cancel_baton;
165251881Speter
166251881Speter  /* Ev2 shim callbacks */
167251881Speter  svn_delta_shim_callbacks_t *shim_callbacks;
168251881Speter
169251881Speter  /* Error that we've received but not yet returned upstream. */
170251881Speter  svn_error_t *pending_error;
171251881Speter
172251881Speter  /* List of authn types supported by the client.*/
173251881Speter  int authn_types;
174251881Speter
175251881Speter  /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values.
176251881Speter     If a capability is not yet discovered, it is absent from the table.
177251881Speter     The table itself is allocated in the svn_ra_serf__session_t's pool;
178251881Speter     keys and values must have at least that lifetime.  Most likely
179251881Speter     the keys and values are constants anyway (and sufficiently
180251881Speter     well-informed internal code may just compare against those
181251881Speter     constants' addresses, therefore). */
182251881Speter  apr_hash_t *capabilities;
183251881Speter
184251881Speter  /* Activity collection URL.  (Cached from the initial OPTIONS
185251881Speter     request when run against HTTPv1 servers.)  */
186251881Speter  const char *activity_collection_url;
187251881Speter
188251881Speter  /* Are we using a proxy? */
189251881Speter  int using_proxy;
190251881Speter
191251881Speter  const char *proxy_username;
192251881Speter  const char *proxy_password;
193251881Speter  int proxy_auth_attempts;
194251881Speter
195251881Speter  /* SSL server certificates */
196251881Speter  svn_boolean_t trust_default_ca;
197251881Speter  const char *ssl_authorities;
198251881Speter
199251881Speter  /* Repository UUID */
200251881Speter  const char *uuid;
201251881Speter
202251881Speter  /* Connection timeout value */
203251881Speter  apr_interval_time_t timeout;
204251881Speter
205251881Speter  /* HTTPv1 flags */
206251881Speter  svn_tristate_t supports_deadprop_count;
207251881Speter
208251881Speter  /*** HTTP v2 protocol stuff. ***
209251881Speter   *
210251881Speter   * We assume that if mod_dav_svn sends one of the special v2 OPTIONs
211251881Speter   * response headers, it has sent all of them.  Specifically, we'll
212251881Speter   * be looking at the presence of the "me resource" as a flag that
213251881Speter   * the server supports v2 of our HTTP protocol.
214251881Speter   */
215251881Speter
216251881Speter  /* The "me resource".  Typically used as a target for REPORTs that
217251881Speter     are path-agnostic.  If we have this, we can speak HTTP v2 to the
218251881Speter     server.  */
219251881Speter  const char *me_resource;
220251881Speter
221251881Speter  /* Opaque URL "stubs".  If the OPTIONS response returns these, then
222251881Speter     we know we're using HTTP protocol v2. */
223251881Speter  const char *rev_stub;         /* for accessing revisions (i.e. revprops) */
224251881Speter  const char *rev_root_stub;    /* for accessing REV/PATH pairs */
225251881Speter  const char *txn_stub;         /* for accessing transactions (i.e. txnprops) */
226251881Speter  const char *txn_root_stub;    /* for accessing TXN/PATH pairs */
227251881Speter  const char *vtxn_stub;        /* for accessing transactions (i.e. txnprops) */
228251881Speter  const char *vtxn_root_stub;   /* for accessing TXN/PATH pairs */
229251881Speter
230251881Speter  /* Hash mapping const char * server-supported POST types to
231251881Speter     disinteresting-but-non-null values. */
232251881Speter  apr_hash_t *supported_posts;
233251881Speter
234251881Speter  /*** End HTTP v2 stuff ***/
235251881Speter
236251881Speter  svn_ra_serf__blncache_t *blncache;
237251881Speter
238251881Speter  /* Trisate flag that indicates user preference for using bulk updates
239251881Speter     (svn_tristate_true) with all the properties and content in the
240251881Speter     update-report response. If svn_tristate_false, request a skelta
241251881Speter     update-report with inlined properties. If svn_tristate_unknown then use
242251881Speter     server preference. */
243251881Speter  svn_tristate_t bulk_updates;
244251881Speter
245251881Speter  /* Indicates if the server wants bulk update requests (Prefer) or only
246251881Speter     accepts skelta requests (Off). If this value is On both options are
247251881Speter     allowed. */
248251881Speter  const char *server_allows_bulk;
249251881Speter
250251881Speter  /* Indicates if the server supports sending inlined props in update editor
251251881Speter   * in skelta mode (send-all == 'false'). */
252251881Speter  svn_boolean_t supports_inline_props;
253251881Speter
254251881Speter  /* Indicates whether the server supports issuing replay REPORTs
255251881Speter     against rev resources (children of `rev_stub', elsestruct). */
256251881Speter  svn_boolean_t supports_rev_rsrc_replay;
257251881Speter};
258251881Speter
259251881Speter#define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL)
260251881Speter
261251881Speter/*
262251881Speter * Structure which represents a DAV element with a NAMESPACE and NAME.
263251881Speter */
264251881Spetertypedef struct svn_ra_serf__dav_props_t {
265251881Speter  /* Element namespace */
266251881Speter  const char *namespace;
267251881Speter  /* Element name */
268251881Speter  const char *name;
269251881Speter} svn_ra_serf__dav_props_t;
270251881Speter
271251881Speter/*
272251881Speter * Structure which represents an XML namespace.
273251881Speter */
274251881Spetertypedef struct ns_t {
275251881Speter  /* The assigned name. */
276251881Speter  const char *namespace;
277251881Speter  /* The full URL for this namespace. */
278251881Speter  const char *url;
279251881Speter  /* The next namespace in our list. */
280251881Speter  struct ns_t *next;
281251881Speter} svn_ra_serf__ns_t;
282251881Speter
283251881Speter/*
284251881Speter * An incredibly simple list.
285251881Speter */
286251881Spetertypedef struct ra_serf_list_t {
287251881Speter  void *data;
288251881Speter  struct ra_serf_list_t *next;
289251881Speter} svn_ra_serf__list_t;
290251881Speter
291251881Speter/** DAV property sets **/
292251881Speter
293251881Speterstatic const svn_ra_serf__dav_props_t base_props[] =
294251881Speter{
295251881Speter  { "DAV:", "version-controlled-configuration" },
296251881Speter  { "DAV:", "resourcetype" },
297251881Speter  { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },
298251881Speter  { SVN_DAV_PROP_NS_DAV, "repository-uuid" },
299251881Speter  { NULL }
300251881Speter};
301251881Speter
302251881Speterstatic const svn_ra_serf__dav_props_t checked_in_props[] =
303251881Speter{
304251881Speter  { "DAV:", "checked-in" },
305251881Speter  { NULL }
306251881Speter};
307251881Speter
308251881Speterstatic const svn_ra_serf__dav_props_t baseline_props[] =
309251881Speter{
310251881Speter  { "DAV:", "baseline-collection" },
311251881Speter  { "DAV:", SVN_DAV__VERSION_NAME },
312251881Speter  { NULL }
313251881Speter};
314251881Speter
315251881Speterstatic const svn_ra_serf__dav_props_t all_props[] =
316251881Speter{
317251881Speter  { "DAV:", "allprop" },
318251881Speter  { NULL }
319251881Speter};
320251881Speter
321251881Speterstatic const svn_ra_serf__dav_props_t check_path_props[] =
322251881Speter{
323251881Speter  { "DAV:", "resourcetype" },
324251881Speter  { NULL }
325251881Speter};
326251881Speter
327251881Speterstatic const svn_ra_serf__dav_props_t type_and_checksum_props[] =
328251881Speter{
329251881Speter  { "DAV:", "resourcetype" },
330251881Speter  { SVN_DAV_PROP_NS_DAV, "sha1-checksum" },
331251881Speter  { NULL }
332251881Speter};
333251881Speter
334251881Speter/* WC props compatibility with ra_neon. */
335251881Speter#define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
336251881Speter
337251881Speter/** Serf utility functions **/
338251881Speter
339251881Speterapr_status_t
340251881Spetersvn_ra_serf__conn_setup(apr_socket_t *sock,
341251881Speter                        serf_bucket_t **read_bkt,
342251881Speter                        serf_bucket_t **write_bkt,
343251881Speter                        void *baton,
344251881Speter                        apr_pool_t *pool);
345251881Speter
346251881Spetervoid
347251881Spetersvn_ra_serf__conn_closed(serf_connection_t *conn,
348251881Speter                         void *closed_baton,
349251881Speter                         apr_status_t why,
350251881Speter                         apr_pool_t *pool);
351251881Speter
352251881Speter
353251881Speter/* Helper function to provide SSL client certificates.
354251881Speter *
355251881Speter * NOTE: This function sets the session's 'pending_error' member when
356251881Speter *       returning an non-success status.
357251881Speter */
358251881Speterapr_status_t
359251881Spetersvn_ra_serf__handle_client_cert(void *data,
360251881Speter                                const char **cert_path);
361251881Speter
362251881Speter/* Helper function to provide SSL client certificate passwords.
363251881Speter *
364251881Speter * NOTE: This function sets the session's 'pending_error' member when
365251881Speter *       returning an non-success status.
366251881Speter */
367251881Speterapr_status_t
368251881Spetersvn_ra_serf__handle_client_cert_pw(void *data,
369251881Speter                                   const char *cert_path,
370251881Speter                                   const char **password);
371251881Speter
372251881Speter
373251881Speter/*
374251881Speter * This function will run the serf context in SESS until *DONE is TRUE.
375251881Speter */
376251881Spetersvn_error_t *
377251881Spetersvn_ra_serf__context_run_wait(svn_boolean_t *done,
378251881Speter                              svn_ra_serf__session_t *sess,
379251881Speter                              apr_pool_t *scratch_pool);
380251881Speter
381251881Speter/* Callback for response handlers */
382251881Spetertypedef svn_error_t *
383251881Speter(*svn_ra_serf__response_handler_t)(serf_request_t *request,
384251881Speter                                   serf_bucket_t *response,
385251881Speter                                   void *handler_baton,
386251881Speter                                   apr_pool_t *scratch_pool);
387251881Speter
388251881Speter/* Callback for when a request body is needed. */
389251881Speter/* ### should pass a scratch_pool  */
390251881Spetertypedef svn_error_t *
391251881Speter(*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
392251881Speter                                        void *baton,
393251881Speter                                        serf_bucket_alloc_t *alloc,
394251881Speter                                        apr_pool_t *request_pool);
395251881Speter
396251881Speter/* Callback for when request headers are needed. */
397251881Speter/* ### should pass a scratch_pool  */
398251881Spetertypedef svn_error_t *
399251881Speter(*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
400251881Speter                                          void *baton,
401251881Speter                                          apr_pool_t *request_pool);
402251881Speter
403251881Speter/* Callback for when a response has an error. */
404251881Spetertypedef svn_error_t *
405251881Speter(*svn_ra_serf__response_error_t)(serf_request_t *request,
406251881Speter                                 serf_bucket_t *response,
407251881Speter                                 int status_code,
408251881Speter                                 void *baton);
409251881Speter
410251881Speter/* ### we should reorder the types in this file.  */
411251881Spetertypedef struct svn_ra_serf__server_error_t svn_ra_serf__server_error_t;
412251881Speter
413251881Speter/*
414251881Speter * Structure that can be passed to our default handler to guide the
415251881Speter * execution of the request through its lifecycle.
416251881Speter */
417251881Spetertypedef struct svn_ra_serf__handler_t {
418251881Speter  /* The HTTP method string of the request */
419251881Speter  const char *method;
420251881Speter
421251881Speter  /* The resource to the execute the method on. */
422251881Speter  const char *path;
423251881Speter
424251881Speter  /* The content-type of the request body. */
425251881Speter  const char *body_type;
426251881Speter
427251881Speter  /* If TRUE then default Accept-Encoding request header is not configured for
428251881Speter     request. If FALSE then 'gzip' accept encoding will be used if compression
429251881Speter     enabled. */
430251881Speter  svn_boolean_t custom_accept_encoding;
431251881Speter
432251881Speter  /* Has the request/response been completed?  */
433251881Speter  svn_boolean_t done;
434251881Speter
435251881Speter  /* If we captured an error from the server, then this will be non-NULL.
436251881Speter     It will be allocated from HANDLER_POOL.  */
437251881Speter  svn_ra_serf__server_error_t *server_error;
438251881Speter
439251881Speter  /* The handler and baton pair for our handler. */
440251881Speter  svn_ra_serf__response_handler_t response_handler;
441251881Speter  void *response_baton;
442251881Speter
443251881Speter  /* When REPONSE_HANDLER is invoked, the following fields will be set
444251881Speter     based on the response header. HANDLER_POOL must be non-NULL for these
445251881Speter     values to be filled in. SLINE.REASON and LOCATION will be allocated
446251881Speter     within HANDLER_POOL.  */
447251881Speter  serf_status_line sline;  /* The parsed Status-Line  */
448251881Speter  const char *location;  /* The Location: header, if any  */
449251881Speter
450251881Speter  /* The handler and baton pair to be executed when a non-recoverable error
451251881Speter   * is detected.  If it is NULL in the presence of an error, an abort() may
452251881Speter   * be triggered.
453251881Speter   */
454251881Speter  svn_ra_serf__response_error_t response_error;
455251881Speter  void *response_error_baton;
456251881Speter
457251881Speter  /* This function and baton pair allows for custom request headers to
458251881Speter   * be set.
459251881Speter   *
460251881Speter   * It will be executed after the request has been set up but before it is
461251881Speter   * delivered.
462251881Speter   */
463251881Speter  svn_ra_serf__request_header_delegate_t header_delegate;
464251881Speter  void *header_delegate_baton;
465251881Speter
466251881Speter  /* This function and baton pair allows a body to be created right before
467251881Speter   * delivery.
468251881Speter   *
469251881Speter   * It will be executed after the request has been set up but before it is
470251881Speter   * delivered.
471251881Speter   *
472251881Speter   * May be NULL if there is no body to send.
473251881Speter   *
474251881Speter   */
475251881Speter  svn_ra_serf__request_body_delegate_t body_delegate;
476251881Speter  void *body_delegate_baton;
477251881Speter
478251881Speter  /* The connection and session to be used for this request. */
479251881Speter  svn_ra_serf__connection_t *conn;
480251881Speter  svn_ra_serf__session_t *session;
481251881Speter
482251881Speter  /* Internal flag to indicate we've parsed the headers.  */
483251881Speter  svn_boolean_t reading_body;
484251881Speter
485251881Speter  /* When this flag will be set, the core handler will discard any unread
486251881Speter     portion of the response body. The registered response handler will
487251881Speter     no longer be called.  */
488251881Speter  svn_boolean_t discard_body;
489251881Speter
490251881Speter  /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL,
491251881Speter     then the requestor does not care about SLINE and LOCATION.  */
492251881Speter  apr_pool_t *handler_pool;
493251881Speter
494251881Speter} svn_ra_serf__handler_t;
495251881Speter
496251881Speter
497251881Speter/* Run one request and process the response.
498251881Speter
499251881Speter   Similar to context_run_wait(), but this creates the request for HANDLER
500251881Speter   and then waits for it to complete.
501251881Speter
502251881Speter   WARNING: context_run_wait() does NOT create a request, whereas this
503251881Speter   function DOES. Avoid a double-create.  */
504251881Spetersvn_error_t *
505251881Spetersvn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
506251881Speter                             apr_pool_t *scratch_pool);
507251881Speter
508251881Speter
509251881Speter/*
510251881Speter * Helper function to queue a request in the @a handler's connection.
511251881Speter */
512251881Spetervoid svn_ra_serf__request_create(svn_ra_serf__handler_t *handler);
513251881Speter
514251881Speter/* XML helper callbacks. */
515251881Speter
516251881Spetertypedef struct svn_ra_serf__xml_state_t {
517251881Speter  /* A numeric value that represents the current state in parsing.
518251881Speter   *
519251881Speter   * Value 0 is reserved for use as the default state.
520251881Speter   */
521251881Speter  int current_state;
522251881Speter
523251881Speter  /* Private pointer set by the parsing code. */
524251881Speter  void *private;
525251881Speter
526251881Speter  /* Allocations should be made in this pool to match the lifetime of the
527251881Speter   * state.
528251881Speter   */
529251881Speter  apr_pool_t *pool;
530251881Speter
531251881Speter  /* The currently-declared namespace for this state. */
532251881Speter  svn_ra_serf__ns_t *ns_list;
533251881Speter
534251881Speter  /* Our previous states. */
535251881Speter  struct svn_ra_serf__xml_state_t *prev;
536251881Speter} svn_ra_serf__xml_state_t;
537251881Speter
538251881Speter/* Forward declaration of the XML parser structure. */
539251881Spetertypedef struct svn_ra_serf__xml_parser_t svn_ra_serf__xml_parser_t;
540251881Speter
541251881Speter/* Callback invoked with @a baton by our XML @a parser when an element with
542251881Speter * the @a name containing @a attrs is opened.
543251881Speter */
544251881Spetertypedef svn_error_t *
545251881Speter(*svn_ra_serf__xml_start_element_t)(svn_ra_serf__xml_parser_t *parser,
546251881Speter                                    svn_ra_serf__dav_props_t name,
547251881Speter                                    const char **attrs,
548251881Speter                                    apr_pool_t *scratch_pool);
549251881Speter
550251881Speter/* Callback invoked with @a baton by our XML @a parser when an element with
551251881Speter * the @a name is closed.
552251881Speter */
553251881Spetertypedef svn_error_t *
554251881Speter(*svn_ra_serf__xml_end_element_t)(svn_ra_serf__xml_parser_t *parser,
555251881Speter                                  svn_ra_serf__dav_props_t name,
556251881Speter                                  apr_pool_t *scratch_pool);
557251881Speter
558251881Speter/* Callback invoked with @a baton by our XML @a parser when a CDATA portion
559251881Speter * of @a data with size @a len is encountered.
560251881Speter *
561251881Speter * This may be invoked multiple times for the same tag.
562251881Speter */
563251881Spetertypedef svn_error_t *
564251881Speter(*svn_ra_serf__xml_cdata_chunk_handler_t)(svn_ra_serf__xml_parser_t *parser,
565251881Speter                                          const char *data,
566251881Speter                                          apr_size_t len,
567251881Speter                                          apr_pool_t *scratch_pool);
568251881Speter
569251881Speter/*
570251881Speter * Helper structure associated with handle_xml_parser handler that will
571251881Speter * specify how an XML response will be processed.
572251881Speter */
573251881Speterstruct svn_ra_serf__xml_parser_t {
574251881Speter  /* Temporary allocations should be made in this pool. */
575251881Speter  apr_pool_t *pool;
576251881Speter
577251881Speter  /* What kind of response are we parsing? If set, this should typically
578251881Speter     define the report name.  */
579251881Speter  const char *response_type;
580251881Speter
581251881Speter  /* Caller-specific data passed to the start, end, cdata callbacks.  */
582251881Speter  void *user_data;
583251881Speter
584251881Speter  /* Callback invoked when a tag is opened. */
585251881Speter  svn_ra_serf__xml_start_element_t start;
586251881Speter
587251881Speter  /* Callback invoked when a tag is closed. */
588251881Speter  svn_ra_serf__xml_end_element_t end;
589251881Speter
590251881Speter  /* Callback invoked when a cdata chunk is received. */
591251881Speter  svn_ra_serf__xml_cdata_chunk_handler_t cdata;
592251881Speter
593251881Speter  /* Our associated expat-based XML parser. */
594251881Speter  XML_Parser xmlp;
595251881Speter
596251881Speter  /* Our current state. */
597251881Speter  svn_ra_serf__xml_state_t *state;
598251881Speter
599251881Speter  /* Our previously used states (will be reused). */
600251881Speter  svn_ra_serf__xml_state_t *free_state;
601251881Speter
602251881Speter  /* If non-NULL, this value will be set to TRUE when the response is
603251881Speter   * completed.
604251881Speter   */
605251881Speter  svn_boolean_t *done;
606251881Speter
607251881Speter  /* If non-NULL, when this parser completes, it will add done_item to
608251881Speter   * the list.
609251881Speter   */
610251881Speter  svn_ra_serf__list_t **done_list;
611251881Speter
612251881Speter  /* A pointer to the item that will be inserted into the list upon
613251881Speter   * completeion.
614251881Speter   */
615251881Speter  svn_ra_serf__list_t *done_item;
616251881Speter
617251881Speter  /* If this flag is TRUE, errors during parsing will be ignored.
618251881Speter   *
619251881Speter   * This is mainly used when we are processing an error XML response to
620251881Speter   * avoid infinite loops.
621251881Speter   */
622251881Speter  svn_boolean_t ignore_errors;
623251881Speter
624251881Speter  /* If an error occurred, this value will be non-NULL. */
625251881Speter  svn_error_t *error;
626251881Speter
627251881Speter  /* Deciding whether to pause, or not, is performed within the parsing
628251881Speter     callbacks. If a callback decides to set this flag, then the loop
629251881Speter     driving the parse (generally, a series of calls to serf_context_run())
630251881Speter     is going to need to coordinate the un-pausing of the parser by
631251881Speter     processing pending content. Thus, deciding to pause the parser is a
632251881Speter     coordinate effort rather than merely setting this flag.
633251881Speter
634251881Speter     When an XML parsing callback sets this flag, note that additional
635251881Speter     elements may be parsed (as the current buffer is consumed). At some
636251881Speter     point, the flag will be recognized and arriving network content will
637251881Speter     be stashed away in the PENDING structure (see below).
638251881Speter
639251881Speter     At some point, the controlling loop should clear this value. The
640251881Speter     underlying network processing will note the change and begin passing
641251881Speter     content into the XML callbacks.
642251881Speter
643251881Speter     Note that the controlling loop should also process pending content
644251881Speter     since the arriving network content will typically finish first.  */
645251881Speter  svn_boolean_t paused;
646251881Speter
647251881Speter  /* While the XML parser is paused, content arriving from the server
648251881Speter     must be saved locally. We cannot stop reading, or the server may
649251881Speter     decide to drop the connection. The content will be stored in memory
650251881Speter     up to a certain limit, and will then be spilled over to disk.
651251881Speter
652251881Speter     See libsvn_ra_serf/util.c  */
653251881Speter  struct svn_ra_serf__pending_t *pending;
654251881Speter
655251881Speter  /* Response restart support */
656251881Speter  const void *headers_baton; /* Last pointer to headers */
657251881Speter  apr_off_t skip_size; /* Number of bytes to skip */
658251881Speter  apr_off_t read_size; /* Number of bytes read from response */
659251881Speter};
660251881Speter
661251881Speter
662251881Speter/* v2 of the XML parsing functions  */
663251881Speter
664251881Speter/* The XML parsing context.  */
665251881Spetertypedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t;
666251881Speter
667251881Speter
668251881Speter/* An opaque structure for the XML parse element/state.  */
669251881Spetertypedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t;
670251881Speter
671251881Speter/* Called just after the parser moves into ENTERED_STATE. The tag causing
672251881Speter   the transition is passed in TAG.
673251881Speter
674251881Speter   This callback is applied to a parsing context by using the
675251881Speter   svn_ra_serf__xml_context_customize() function.
676251881Speter
677251881Speter   NOTE: this callback, when set, will be invoked on *every* transition.
678251881Speter   The callback must examine ENTERED_STATE to determine if any action
679251881Speter   must be taken. The original state is not provided, but must be derived
680251881Speter   from ENTERED_STATE and/or the TAG causing the transition (if needed).  */
681251881Spetertypedef svn_error_t *
682251881Speter(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
683251881Speter                             void *baton,
684251881Speter                             int entered_state,
685251881Speter                             const svn_ra_serf__dav_props_t *tag,
686251881Speter                             apr_pool_t *scratch_pool);
687251881Speter
688251881Speter
689251881Speter/* Called just before the parser leaves LEAVING_STATE.
690251881Speter
691251881Speter   If cdata collection was enabled for this state, then CDATA will be
692251881Speter   non-NULL and contain the collected cdata.
693251881Speter
694251881Speter   If attribute collection was enabled for this state, then ATTRS will
695251881Speter   contain the attributes collected for this element only, along with
696251881Speter   any values stored via svn_ra_serf__xml_note().
697251881Speter
698251881Speter   Use svn_ra_serf__xml_gather_since() to gather up data from outer states.
699251881Speter
700251881Speter   ATTRS is char* -> char*.
701251881Speter
702251881Speter   Temporary allocations may be made in SCRATCH_POOL.  */
703251881Spetertypedef svn_error_t *
704251881Speter(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes,
705251881Speter                             void *baton,
706251881Speter                             int leaving_state,
707251881Speter                             const svn_string_t *cdata,
708251881Speter                             apr_hash_t *attrs,
709251881Speter                             apr_pool_t *scratch_pool);
710251881Speter
711251881Speter
712251881Speter/* Called for all states that are not using the builtin cdata collection.
713251881Speter   This callback is (only) appropriate for unbounded-size cdata content.
714251881Speter
715251881Speter   CURRENT_STATE may be used to decide what to do with the data.
716251881Speter
717251881Speter   Temporary allocations may be made in SCRATCH_POOL.  */
718251881Spetertypedef svn_error_t *
719251881Speter(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
720251881Speter                            void *baton,
721251881Speter                            int current_state,
722251881Speter                            const char *data,
723251881Speter                            apr_size_t len,
724251881Speter                            apr_pool_t *scratch_pool);
725251881Speter
726251881Speter
727251881Speter/* State transition table.
728251881Speter
729251881Speter   When the XML Context is constructed, it is in state 0. User states are
730251881Speter   positive integers.
731251881Speter
732251881Speter   In a list of transitions, use { 0 } to indicate the end. Specifically,
733251881Speter   the code looks for NS == NULL.
734251881Speter
735251881Speter   ### more docco
736251881Speter*/
737251881Spetertypedef struct svn_ra_serf__xml_transition_t {
738251881Speter  /* This transition applies when in this state  */
739251881Speter  int from_state;
740251881Speter
741251881Speter  /* And when this tag is observed  */
742251881Speter  const char *ns;
743251881Speter  const char *name;
744251881Speter
745251881Speter  /* Moving to this state  */
746251881Speter  int to_state;
747251881Speter
748251881Speter  /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
749251881Speter     be TRUE in order to capture this cdata.  */
750251881Speter  svn_boolean_t collect_cdata;
751251881Speter
752251881Speter  /* Which attributes of NAME should be collected? Terminate with NULL.
753251881Speter     Maximum of 10 attributes may be collected. Note that attribute
754251881Speter     namespaces are ignored at this time.
755251881Speter
756251881Speter     Attribute names beginning with "?" are optional. Other names must
757251881Speter     exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised.  */
758251881Speter  const char *collect_attrs[11];
759251881Speter
760251881Speter  /* When NAME is closed, should the callback be invoked?  */
761251881Speter  svn_boolean_t custom_close;
762251881Speter
763251881Speter} svn_ra_serf__xml_transition_t;
764251881Speter
765251881Speter
766251881Speter/* Construct an XML parsing context, based on the TTABLE transition table.
767251881Speter   As content is parsed, the CLOSED_CB callback will be invoked according
768251881Speter   to the definition in the table.
769251881Speter
770251881Speter   If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
771251881Speter   event. The callback will need to use the ENTERED_STATE and TAG parameters
772251881Speter   to decide what it would like to do.
773251881Speter
774251881Speter   If CDATA_CB is not NULL, then it will be called for all cdata that is
775251881Speter   not be automatically collected (based on the transition table record's
776251881Speter   COLLECT_CDATA flag). It will be called in every state, so the callback
777251881Speter   must examine the CURRENT_STATE parameter to decide what to do.
778251881Speter
779251881Speter   The same BATON value will be passed to all three callbacks.
780251881Speter
781251881Speter   The context will be created within RESULT_POOL.  */
782251881Spetersvn_ra_serf__xml_context_t *
783251881Spetersvn_ra_serf__xml_context_create(
784251881Speter  const svn_ra_serf__xml_transition_t *ttable,
785251881Speter  svn_ra_serf__xml_opened_t opened_cb,
786251881Speter  svn_ra_serf__xml_closed_t closed_cb,
787251881Speter  svn_ra_serf__xml_cdata_t cdata_cb,
788251881Speter  void *baton,
789251881Speter  apr_pool_t *result_pool);
790251881Speter
791251881Speter/* Destroy all subpools for this structure. */
792251881Spetervoid
793251881Spetersvn_ra_serf__xml_context_destroy(
794251881Speter  svn_ra_serf__xml_context_t *xmlctx);
795251881Speter
796251881Speter/* Construct a handler with the response function/baton set up to parse
797251881Speter   a response body using the given XML context. The handler and its
798251881Speter   internal structures are allocated in RESULT_POOL.
799251881Speter
800251881Speter   This also initializes HANDLER_POOL to the given RESULT_POOL.  */
801251881Spetersvn_ra_serf__handler_t *
802251881Spetersvn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx,
803251881Speter                                  apr_pool_t *result_pool);
804251881Speter
805251881Speter
806251881Speter/* Allocated within XES->STATE_POOL. Changes are not allowd (callers
807251881Speter   should make a deep copy if they need to make changes).
808251881Speter
809251881Speter   The resulting hash maps char* names to char* values.  */
810251881Speterapr_hash_t *
811251881Spetersvn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
812251881Speter                              int stop_state);
813251881Speter
814251881Speter
815251881Speter/* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
816251881Speter   The name and value will be copied into the target state's pool.
817251881Speter
818251881Speter   These values will be available to the CLOSED_CB for the target state,
819251881Speter   or part of the gathered state via xml_gather_since().
820251881Speter
821251881Speter   Typically, this function is used by a child state's close callback,
822251881Speter   or within an opening callback to store additional data.
823251881Speter
824251881Speter   Note: if the state is not found, then a programmer error has occurred,
825251881Speter   so the function will invoke SVN_ERR_MALFUNCTION().  */
826251881Spetervoid
827251881Spetersvn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
828251881Speter                      int state,
829251881Speter                      const char *name,
830251881Speter                      const char *value);
831251881Speter
832251881Speter
833251881Speter/* Returns XES->STATE_POOL for allocating structures that should live
834251881Speter   as long as the state identified by XES.
835251881Speter
836251881Speter   Note: a state pool is created upon demand, so only use this function
837251881Speter   when memory is required for a given state.  */
838251881Speterapr_pool_t *
839251881Spetersvn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
840251881Speter
841251881Speter
842251881Speter/* Any XML parser may be used. When an opening tag is seen, call this
843251881Speter   function to feed the information into XMLCTX.  */
844251881Spetersvn_error_t *
845251881Spetersvn_ra_serf__xml_cb_start(svn_ra_serf__xml_context_t *xmlctx,
846251881Speter                          const char *raw_name,
847251881Speter                          const char *const *attrs);
848251881Speter
849251881Speter
850251881Speter/* When a close tag is seen, call this function to feed the information
851251881Speter   into XMLCTX.  */
852251881Spetersvn_error_t *
853251881Spetersvn_ra_serf__xml_cb_end(svn_ra_serf__xml_context_t *xmlctx,
854251881Speter                        const char *raw_name);
855251881Speter
856251881Speter
857251881Speter/* When cdata is parsed by the wrapping XML parser, call this function to
858251881Speter   feed the cdata into the XMLCTX.  */
859251881Spetersvn_error_t *
860251881Spetersvn_ra_serf__xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx,
861251881Speter                          const char *data,
862251881Speter                          apr_size_t len);
863251881Speter
864251881Speter
865251881Speter/*
866251881Speter * Parses a server-side error message into a local Subversion error.
867251881Speter */
868251881Speterstruct svn_ra_serf__server_error_t {
869251881Speter  /* Our local representation of the error. */
870251881Speter  svn_error_t *error;
871251881Speter
872251881Speter  /* Are we done with the response? */
873251881Speter  svn_boolean_t done;
874251881Speter
875251881Speter  /* Have we seen an error tag? */
876251881Speter  svn_boolean_t in_error;
877251881Speter
878251881Speter  /* Have we seen a HTTP "412 Precondition Failed" error? */
879251881Speter  svn_boolean_t contains_precondition_error;
880251881Speter
881251881Speter  /* Should we be collecting the XML cdata? */
882251881Speter  svn_boolean_t collect_cdata;
883251881Speter
884251881Speter  /* Collected cdata. NULL if cdata not needed. */
885251881Speter  svn_stringbuf_t *cdata;
886251881Speter
887251881Speter  /* XML parser and namespace used to parse the remote response */
888251881Speter  svn_ra_serf__xml_parser_t parser;
889251881Speter};
890251881Speter
891251881Speter
892251881Speter/*
893251881Speter * Handler that discards the entire @a response body associated with a
894251881Speter * @a request.  Implements svn_ra_serf__response_handler_t.
895251881Speter *
896251881Speter * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an
897251881Speter * error is detected, it will be populated for later detection.
898251881Speter *
899251881Speter * All temporary allocations will be made in a @a pool.
900251881Speter */
901251881Spetersvn_error_t *
902251881Spetersvn_ra_serf__handle_discard_body(serf_request_t *request,
903251881Speter                                 serf_bucket_t *response,
904251881Speter                                 void *baton,
905251881Speter                                 apr_pool_t *pool);
906251881Speter
907251881Speter
908251881Speter/*
909251881Speter * Handler that retrieves the embedded XML multistatus response from the
910251881Speter * the @a RESPONSE body associated with a @a REQUEST.
911251881Speter *
912251881Speter * Implements svn_ra_serf__response_handler_t.
913251881Speter *
914251881Speter * The @a BATON should be of type svn_ra_serf__handler_t. When the request
915251881Speter * is complete, the handler's DONE flag will be set to TRUE.
916251881Speter *
917251881Speter * All temporary allocations will be made in a @a scratch_pool.
918251881Speter */
919251881Spetersvn_error_t *
920251881Spetersvn_ra_serf__handle_multistatus_only(serf_request_t *request,
921251881Speter                                     serf_bucket_t *response,
922251881Speter                                     void *baton,
923251881Speter                                     apr_pool_t *scratch_pool);
924251881Speter
925251881Speter
926251881Speter/* Handler that expects an empty body.
927251881Speter
928251881Speter   If a body IS present, and it is text/xml, then it will be parsed for
929251881Speter   a server-side error.
930251881Speter
931251881Speter   BATON should be the svn_ra_serf__handler_t running REQUEST.
932251881Speter
933251881Speter   Status line information will be in HANDLER->SLINE.
934251881Speter
935251881Speter   Any parsed errors will be left in HANDLER->SERVER_ERROR. That member
936251881Speter   may be NULL if no body was present, or a problem occurred trying to
937251881Speter   parse the body.
938251881Speter
939251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
940251881Spetersvn_error_t *
941251881Spetersvn_ra_serf__expect_empty_body(serf_request_t *request,
942251881Speter                               serf_bucket_t *response,
943251881Speter                               void *baton,
944251881Speter                               apr_pool_t *scratch_pool);
945251881Speter
946251881Speter
947251881Speter/*
948251881Speter * This function will feed the RESPONSE body into XMLP.  When parsing is
949251881Speter * completed (i.e. an EOF is received), *DONE is set to TRUE.
950251881Speter * Implements svn_ra_serf__response_handler_t.
951251881Speter *
952251881Speter * If an error occurs during processing RESP_ERR is invoked with the
953251881Speter * RESP_ERR_BATON.
954251881Speter *
955251881Speter * Temporary allocations are made in POOL.
956251881Speter */
957251881Spetersvn_error_t *
958251881Spetersvn_ra_serf__handle_xml_parser(serf_request_t *request,
959251881Speter                               serf_bucket_t *response,
960251881Speter                               void *handler_baton,
961251881Speter                               apr_pool_t *pool);
962251881Speter
963251881Speter/* serf_response_handler_t implementation that completely discards
964251881Speter * the response.
965251881Speter *
966251881Speter * All temporary allocations will be made in @a pool.
967251881Speter */
968251881Speterapr_status_t
969251881Spetersvn_ra_serf__response_discard_handler(serf_request_t *request,
970251881Speter                                      serf_bucket_t *response,
971251881Speter                                      void *baton,
972251881Speter                                      apr_pool_t *pool);
973251881Speter
974251881Speter
975251881Speter/** XML helper functions. **/
976251881Speter
977251881Speter/*
978251881Speter * Advance the internal XML @a parser to the @a state.
979251881Speter */
980251881Spetervoid
981251881Spetersvn_ra_serf__xml_push_state(svn_ra_serf__xml_parser_t *parser,
982251881Speter                            int state);
983251881Speter
984251881Speter/*
985251881Speter * Return to the previous internal XML @a parser state.
986251881Speter */
987251881Spetervoid
988251881Spetersvn_ra_serf__xml_pop_state(svn_ra_serf__xml_parser_t *parser);
989251881Speter
990251881Speter
991251881Spetersvn_error_t *
992251881Spetersvn_ra_serf__process_pending(svn_ra_serf__xml_parser_t *parser,
993251881Speter                             svn_boolean_t *network_eof,
994251881Speter                             apr_pool_t *scratch_pool);
995251881Speter
996251881Speter
997251881Speter/*
998251881Speter * Add the appropriate serf buckets to @a agg_bucket represented by
999251881Speter * the XML * @a tag and @a value.
1000251881Speter *
1001251881Speter * The bucket will be allocated from @a bkt_alloc.
1002251881Speter */
1003251881Spetervoid
1004251881Spetersvn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket,
1005251881Speter                             const char *tag,
1006251881Speter                             const char *value,
1007251881Speter                             serf_bucket_alloc_t *bkt_alloc);
1008251881Speter
1009251881Speter/*
1010251881Speter * Add the appropriate serf buckets to AGG_BUCKET with standard XML header:
1011251881Speter *  <?xml version="1.0" encoding="utf-8"?>
1012251881Speter *
1013251881Speter * The bucket will be allocated from BKT_ALLOC.
1014251881Speter */
1015251881Spetervoid
1016251881Spetersvn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket,
1017251881Speter                                    serf_bucket_alloc_t *bkt_alloc);
1018251881Speter
1019251881Speter/*
1020251881Speter * Add the appropriate serf buckets to AGG_BUCKET representing the XML
1021251881Speter * open tag with name TAG.
1022251881Speter *
1023251881Speter * Take the tag's attributes from varargs, a NULL-terminated list of
1024251881Speter * alternating <tt>char *</tt> key and <tt>char *</tt> val.  Attribute
1025251881Speter * will be ignored if it's value is NULL.
1026251881Speter *
1027251881Speter * NOTE: Callers are responsible for XML-escaping attribute values as
1028251881Speter * necessary.
1029251881Speter *
1030251881Speter * The bucket will be allocated from BKT_ALLOC.
1031251881Speter */
1032251881Spetervoid
1033251881Spetersvn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket,
1034251881Speter                                  serf_bucket_alloc_t *bkt_alloc,
1035251881Speter                                  const char *tag,
1036251881Speter                                  ...);
1037251881Speter
1038251881Speter/*
1039251881Speter * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close
1040251881Speter * with name TAG.
1041251881Speter *
1042251881Speter * The bucket will be allocated from BKT_ALLOC.
1043251881Speter */
1044251881Spetervoid
1045251881Spetersvn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket,
1046251881Speter                                   serf_bucket_alloc_t *bkt_alloc,
1047251881Speter                                   const char *tag);
1048251881Speter
1049251881Speter/*
1050251881Speter * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped
1051251881Speter * version of DATA.
1052251881Speter *
1053251881Speter * The bucket will be allocated from BKT_ALLOC.
1054251881Speter */
1055251881Spetervoid
1056251881Spetersvn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket,
1057251881Speter                                   serf_bucket_alloc_t *bkt_alloc,
1058251881Speter                                   const char *data, apr_size_t len);
1059251881Speter/*
1060251881Speter * Look up the @a attrs array for namespace definitions and add each one
1061251881Speter * to the @a ns_list of namespaces.
1062251881Speter *
1063251881Speter * New namespaces will be allocated in RESULT_POOL.
1064251881Speter */
1065251881Spetervoid
1066251881Spetersvn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,
1067251881Speter                       const char *const *attrs,
1068251881Speter                       apr_pool_t *result_pool);
1069251881Speter
1070251881Speter/*
1071251881Speter * Look up @a name in the @a ns_list list for previously declared namespace
1072251881Speter * definitions.
1073251881Speter *
1074251881Speter * Return (in @a *returned_prop_name) a #svn_ra_serf__dav_props_t tuple
1075251881Speter * representing the expanded name.
1076251881Speter */
1077251881Spetervoid
1078251881Spetersvn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
1079251881Speter                       const svn_ra_serf__ns_t *ns_list,
1080251881Speter                       const char *name);
1081251881Speter
1082251881Speter
1083251881Speter/** PROPFIND-related functions **/
1084251881Speter
1085251881Speter/*
1086251881Speter * This function will deliver a PROP_CTX PROPFIND request in the SESS
1087251881Speter * serf context for the properties listed in LOOKUP_PROPS at URL for
1088251881Speter * DEPTH ("0","1","infinity").
1089251881Speter *
1090251881Speter * This function will not block waiting for the response. Callers are
1091251881Speter * expected to call svn_ra_serf__wait_for_props().
1092251881Speter */
1093251881Spetersvn_error_t *
1094251881Spetersvn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
1095251881Speter                           apr_hash_t *prop_vals,
1096251881Speter                           svn_ra_serf__session_t *sess,
1097251881Speter                           svn_ra_serf__connection_t *conn,
1098251881Speter                           const char *url,
1099251881Speter                           svn_revnum_t rev,
1100251881Speter                           const char *depth,
1101251881Speter                           const svn_ra_serf__dav_props_t *lookup_props,
1102251881Speter                           svn_ra_serf__list_t **done_list,
1103251881Speter                           apr_pool_t *pool);
1104251881Speter
1105251881Speter/*
1106251881Speter * This helper function will block until PROPFIND_HANDLER indicates that is
1107251881Speter * done or another error is returned.
1108251881Speter */
1109251881Spetersvn_error_t *
1110251881Spetersvn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
1111251881Speter                            apr_pool_t *scratch_pool);
1112251881Speter
1113251881Speter/* This is a blocking version of deliver_props.
1114251881Speter
1115251881Speter   The properties are fetched and placed into RESULTS, allocated in
1116251881Speter   RESULT_POOL.
1117251881Speter
1118251881Speter   ### more docco about the other params.
1119251881Speter
1120251881Speter   Temporary allocations are made in SCRATCH_POOL.
1121251881Speter*/
1122251881Spetersvn_error_t *
1123251881Spetersvn_ra_serf__retrieve_props(apr_hash_t **results,
1124251881Speter                            svn_ra_serf__session_t *sess,
1125251881Speter                            svn_ra_serf__connection_t *conn,
1126251881Speter                            const char *url,
1127251881Speter                            svn_revnum_t rev,
1128251881Speter                            const char *depth,
1129251881Speter                            const svn_ra_serf__dav_props_t *props,
1130251881Speter                            apr_pool_t *result_pool,
1131251881Speter                            apr_pool_t *scratch_pool);
1132251881Speter
1133251881Speter
1134251881Speter/* Using CONN, fetch the properties specified by WHICH_PROPS using CONN
1135251881Speter   for URL at REVISION. The resulting properties are placed into a 2-level
1136251881Speter   hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which
1137251881Speter   is allocated in RESULT_POOL.
1138251881Speter
1139251881Speter   If REVISION is SVN_INVALID_REVNUM, then the properties are fetched
1140251881Speter   from HEAD for URL.
1141251881Speter
1142251881Speter   This function performs the request synchronously.
1143251881Speter
1144251881Speter   Temporary allocations are made in SCRATCH_POOL.  */
1145251881Spetersvn_error_t *
1146251881Spetersvn_ra_serf__fetch_node_props(apr_hash_t **results,
1147251881Speter                              svn_ra_serf__connection_t *conn,
1148251881Speter                              const char *url,
1149251881Speter                              svn_revnum_t revision,
1150251881Speter                              const svn_ra_serf__dav_props_t *which_props,
1151251881Speter                              apr_pool_t *result_pool,
1152251881Speter                              apr_pool_t *scratch_pool);
1153251881Speter
1154251881Speter
1155251881Speter/* Using CONN, fetch a DAV: property from the resource identified by URL
1156251881Speter   within REVISION. The PROPNAME may be one of:
1157251881Speter
1158251881Speter     "checked-in"
1159251881Speter     "href"
1160251881Speter
1161251881Speter   The resulting value will be allocated in RESULT_POOL, and may be NULL
1162251881Speter   if the property does not exist (note: "href" always exists).
1163251881Speter
1164251881Speter   This function performs the request synchronously.
1165251881Speter
1166251881Speter   Temporary allocations are made in SCRATCH_POOL.  */
1167251881Spetersvn_error_t *
1168251881Spetersvn_ra_serf__fetch_dav_prop(const char **value,
1169251881Speter                            svn_ra_serf__connection_t *conn,
1170251881Speter                            const char *url,
1171251881Speter                            svn_revnum_t revision,
1172251881Speter                            const char *propname,
1173251881Speter                            apr_pool_t *result_pool,
1174251881Speter                            apr_pool_t *scratch_pool);
1175251881Speter
1176251881Speter
1177251881Speter/* Set PROPS for PATH at REV revision with a NS:NAME VAL.
1178251881Speter *
1179251881Speter * The POOL governs allocation.
1180251881Speter */
1181251881Spetervoid
1182251881Spetersvn_ra_serf__set_ver_prop(apr_hash_t *props,
1183251881Speter                          const char *path, svn_revnum_t rev,
1184251881Speter                          const char *ns, const char *name,
1185251881Speter                          const svn_string_t *val, apr_pool_t *pool);
1186251881Speter#define svn_ra_serf__set_rev_prop svn_ra_serf__set_ver_prop
1187251881Speter
1188251881Speter/** Property walker functions **/
1189251881Speter
1190251881Spetertypedef svn_error_t *
1191251881Speter(*svn_ra_serf__walker_visitor_t)(void *baton,
1192251881Speter                                 const char *ns,
1193251881Speter                                 const char *name,
1194251881Speter                                 const svn_string_t *val,
1195251881Speter                                 apr_pool_t *pool);
1196251881Speter
1197251881Spetersvn_error_t *
1198251881Spetersvn_ra_serf__walk_all_props(apr_hash_t *props,
1199251881Speter                            const char *name,
1200251881Speter                            svn_revnum_t rev,
1201251881Speter                            svn_ra_serf__walker_visitor_t walker,
1202251881Speter                            void *baton,
1203251881Speter                            apr_pool_t *pool);
1204251881Speter
1205251881Speter
1206251881Speter/* Like walk_all_props(), but a 2-level hash.  */
1207251881Spetersvn_error_t *
1208251881Spetersvn_ra_serf__walk_node_props(apr_hash_t *props,
1209251881Speter                             svn_ra_serf__walker_visitor_t walker,
1210251881Speter                             void *baton,
1211251881Speter                             apr_pool_t *scratch_pool);
1212251881Speter
1213251881Speter
1214251881Spetertypedef svn_error_t *
1215251881Speter(*svn_ra_serf__path_rev_walker_t)(void *baton,
1216251881Speter                                  const char *path, apr_ssize_t path_len,
1217251881Speter                                  const char *ns, apr_ssize_t ns_len,
1218251881Speter                                  const char *name, apr_ssize_t name_len,
1219251881Speter                                  const svn_string_t *val,
1220251881Speter                                  apr_pool_t *pool);
1221251881Spetersvn_error_t *
1222251881Spetersvn_ra_serf__walk_all_paths(apr_hash_t *props,
1223251881Speter                            svn_revnum_t rev,
1224251881Speter                            svn_ra_serf__path_rev_walker_t walker,
1225251881Speter                            void *baton,
1226251881Speter                            apr_pool_t *pool);
1227251881Speter
1228251881Speter
1229251881Speter/* Map a property name, as passed over the wire, into its corresponding
1230251881Speter   Subversion-internal name. The returned name will be a static value,
1231251881Speter   or allocated within RESULT_POOL.
1232251881Speter
1233251881Speter   If the property should be ignored (eg. some DAV properties), then NULL
1234251881Speter   will be returned.  */
1235251881Speterconst char *
1236251881Spetersvn_ra_serf__svnname_from_wirename(const char *ns,
1237251881Speter                                   const char *name,
1238251881Speter                                   apr_pool_t *result_pool);
1239251881Speter
1240251881Speter
1241251881Speter/* Select the basic revision properties from the set of "all" properties.
1242251881Speter   Return these in *REVPROPS, allocated from RESULT_POOL.  */
1243251881Spetersvn_error_t *
1244251881Spetersvn_ra_serf__select_revprops(apr_hash_t **revprops,
1245251881Speter                             const char *name,
1246251881Speter                             svn_revnum_t rev,
1247251881Speter                             apr_hash_t *all_revprops,
1248251881Speter                             apr_pool_t *result_pool,
1249251881Speter                             apr_pool_t *scratch_pool);
1250251881Speter
1251251881Speter
1252251881Speter/* PROPS is nested hash tables mapping NS -> NAME -> VALUE.
1253251881Speter   This function takes the NS:NAME:VALUE hashes and flattens them into a set of
1254251881Speter   names to VALUE. The names are composed of NS:NAME, with specific
1255251881Speter   rewrite from wire names (DAV) to SVN names. This mapping is managed
1256251881Speter   by the svn_ra_serf__set_baton_props() function.
1257251881Speter
1258251881Speter   FLAT_PROPS is allocated in RESULT_POOL.
1259251881Speter   ### right now, we do a shallow copy from PROPS to FLAT_PROPS. therefore,
1260251881Speter   ### the names and values in PROPS must be in the proper pool.
1261251881Speter
1262251881Speter   Temporary allocations are made in SCRATCH_POOL.  */
1263251881Spetersvn_error_t *
1264251881Spetersvn_ra_serf__flatten_props(apr_hash_t **flat_props,
1265251881Speter                           apr_hash_t *props,
1266251881Speter                           apr_pool_t *result_pool,
1267251881Speter                           apr_pool_t *scratch_pool);
1268251881Speter
1269251881Speter
1270251881Speter/* Return the property value for PATH at REV revision with a NS:NAME.
1271251881Speter * PROPS is a four-level nested hash: (svn_revnum_t => char *path =>
1272251881Speter * char *ns => char *name => svn_string_t *). */
1273251881Speterconst svn_string_t *
1274251881Spetersvn_ra_serf__get_ver_prop_string(apr_hash_t *props,
1275251881Speter                                 const char *path, svn_revnum_t rev,
1276251881Speter                                 const char *ns, const char *name);
1277251881Speter
1278251881Speter/* Same as svn_ra_serf__get_ver_prop_string(), but returns a C string. */
1279251881Speterconst char *
1280251881Spetersvn_ra_serf__get_ver_prop(apr_hash_t *props,
1281251881Speter                          const char *path, svn_revnum_t rev,
1282251881Speter                          const char *ns, const char *name);
1283251881Speter
1284251881Speter/* Same as svn_ra_serf__get_ver_prop_string(), but for the unknown revision. */
1285251881Speterconst svn_string_t *
1286251881Spetersvn_ra_serf__get_prop_string(apr_hash_t *props,
1287251881Speter                             const char *path,
1288251881Speter                             const char *ns,
1289251881Speter                             const char *name);
1290251881Speter
1291251881Speter/* Same as svn_ra_serf__get_ver_prop(), but for the unknown revision. */
1292251881Speterconst char *
1293251881Spetersvn_ra_serf__get_prop(apr_hash_t *props,
1294251881Speter                      const char *path,
1295251881Speter                      const char *ns,
1296251881Speter                      const char *name);
1297251881Speter
1298251881Speter/* Same as svn_ra_serf__set_rev_prop(), but for the unknown revision. */
1299251881Spetervoid
1300251881Spetersvn_ra_serf__set_prop(apr_hash_t *props, const char *path,
1301251881Speter                      const char *ns, const char *name,
1302251881Speter                      const svn_string_t *val, apr_pool_t *pool);
1303251881Speter
1304251881Spetersvn_error_t *
1305251881Spetersvn_ra_serf__get_resource_type(svn_node_kind_t *kind,
1306251881Speter                               apr_hash_t *props);
1307251881Speter
1308251881Speter
1309251881Speter/** MERGE-related functions **/
1310251881Speter
1311251881Spetervoid
1312251881Spetersvn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
1313251881Speter                                   const char *parent,
1314251881Speter                                   serf_bucket_t *body,
1315251881Speter                                   serf_bucket_alloc_t *alloc,
1316251881Speter                                   apr_pool_t *pool);
1317251881Speter
1318251881Speter/* Create an MERGE request aimed at the SESSION url, requesting the
1319251881Speter   merge of the resource identified by MERGE_RESOURCE_URL.
1320251881Speter   LOCK_TOKENS is a hash mapping paths to lock tokens owned by the
1321251881Speter   client.  If KEEP_LOCKS is set, instruct the server to not release
1322251881Speter   locks set on the paths included in this commit.  */
1323251881Spetersvn_error_t *
1324251881Spetersvn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
1325251881Speter                       int *response_code,
1326251881Speter                       svn_ra_serf__session_t *session,
1327251881Speter                       svn_ra_serf__connection_t *conn,
1328251881Speter                       const char *merge_resource_url,
1329251881Speter                       apr_hash_t *lock_tokens,
1330251881Speter                       svn_boolean_t keep_locks,
1331251881Speter                       apr_pool_t *result_pool,
1332251881Speter                       apr_pool_t *scratch_pool);
1333251881Speter
1334251881Speter
1335251881Speter/** OPTIONS-related functions **/
1336251881Speter
1337251881Speter/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
1338251881Speter   current youngest revnum, returning it in *YOUNGEST.
1339251881Speter
1340251881Speter   (the revnum is headers of the OPTIONS response)
1341251881Speter
1342251881Speter   This function performs the request synchronously.
1343251881Speter
1344251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
1345251881Spetersvn_error_t *
1346251881Spetersvn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
1347251881Speter                                    svn_ra_serf__connection_t *conn,
1348251881Speter                                    apr_pool_t *scratch_pool);
1349251881Speter
1350251881Speter
1351251881Speter/* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the
1352251881Speter   activity collection set and return it in *ACTIVITY_URL, allocated
1353251881Speter   from RESULT_POOL.
1354251881Speter
1355251881Speter   (the activity-collection-set is in the body of the OPTIONS response)
1356251881Speter
1357251881Speter   This function performs the request synchronously.
1358251881Speter
1359251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
1360251881Spetersvn_error_t *
1361251881Spetersvn_ra_serf__v1_get_activity_collection(const char **activity_url,
1362251881Speter                                        svn_ra_serf__connection_t *conn,
1363251881Speter                                        apr_pool_t *result_pool,
1364251881Speter                                        apr_pool_t *scratch_pool);
1365251881Speter
1366251881Speter
1367251881Speter/* Set @a VCC_URL to the default VCC for our repository based on @a
1368251881Speter * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and
1369251881Speter * repository root URLs are cached in @a SESSION.  Use @a CONN for any
1370251881Speter * required network communications if it is non-NULL; otherwise use the
1371251881Speter * default connection.
1372251881Speter *
1373251881Speter * All temporary allocations will be made in @a POOL. */
1374251881Spetersvn_error_t *
1375251881Spetersvn_ra_serf__discover_vcc(const char **vcc_url,
1376251881Speter                          svn_ra_serf__session_t *session,
1377251881Speter                          svn_ra_serf__connection_t *conn,
1378251881Speter                          apr_pool_t *pool);
1379251881Speter
1380251881Speter/* Set @a REPORT_TARGET to the URI of the resource at which generic
1381251881Speter * (path-agnostic) REPORTs should be aimed for @a SESSION.  Use @a
1382251881Speter * CONN for any required network communications if it is non-NULL;
1383251881Speter * otherwise use the default connection.
1384251881Speter *
1385251881Speter * All temporary allocations will be made in @a POOL.
1386251881Speter */
1387251881Spetersvn_error_t *
1388251881Spetersvn_ra_serf__report_resource(const char **report_target,
1389251881Speter                             svn_ra_serf__session_t *session,
1390251881Speter                             svn_ra_serf__connection_t *conn,
1391251881Speter                             apr_pool_t *pool);
1392251881Speter
1393251881Speter/* Set @a REL_PATH to a path (not URI-encoded) relative to the root of
1394251881Speter * the repository pointed to by @a SESSION, based on original path
1395251881Speter * (URI-encoded) @a ORIG_PATH.  Use @a CONN for any required network
1396251881Speter * communications if it is non-NULL; otherwise use the default
1397251881Speter * connection.  Use POOL for allocations.  */
1398251881Spetersvn_error_t *
1399251881Spetersvn_ra_serf__get_relative_path(const char **rel_path,
1400251881Speter                               const char *orig_path,
1401251881Speter                               svn_ra_serf__session_t *session,
1402251881Speter                               svn_ra_serf__connection_t *conn,
1403251881Speter                               apr_pool_t *pool);
1404251881Speter
1405251881Speter
1406251881Speter/* Using the default connection in SESSION (conns[0]), get the youngest
1407251881Speter   revnum from the server, returning it in *YOUNGEST.
1408251881Speter
1409251881Speter   This function operates synchronously.
1410251881Speter
1411251881Speter   All temporary allocations are performed in SCRATCH_POOL.  */
1412251881Spetersvn_error_t *
1413251881Spetersvn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest,
1414251881Speter                                 svn_ra_serf__session_t *session,
1415251881Speter                                 apr_pool_t *scratch_pool);
1416251881Speter
1417251881Speter
1418251881Speter/* Generate a revision-stable URL.
1419251881Speter
1420251881Speter   The RA APIs all refer to user/public URLs that float along with the
1421251881Speter   youngest revision. In many cases, we do NOT want to work with that URL
1422251881Speter   since it can change from one moment to the next. Especially if we
1423251881Speter   attempt to operation against multiple floating URLs -- we could end up
1424251881Speter   referring to two separate revisions.
1425251881Speter
1426251881Speter   The DAV RA provider(s) solve this by generating a URL that is specific
1427251881Speter   to a revision by using a URL into a "baseline collection".
1428251881Speter
1429251881Speter   For a specified SESSION, with an optional CONN (if NULL, then the
1430251881Speter   session's default connection will be used; specifically SESSION->conns[0]),
1431251881Speter   generate a revision-stable URL for URL at REVISION. If REVISION is
1432251881Speter   SVN_INVALID_REVNUM, then the stable URL will refer to the youngest
1433251881Speter   revision at the time this function was called.
1434251881Speter
1435251881Speter   If URL is NULL, then the session root will be used.
1436251881Speter
1437251881Speter   The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL.
1438251881Speter
1439251881Speter   If LATEST_REVNUM is not NULL, then the revision used will be placed into
1440251881Speter   *LATEST_REVNUM. That will be equal to youngest, or the given REVISION.
1441251881Speter
1442251881Speter   This function operates synchronously, if any communication to the server
1443251881Speter   is required. Communication is needed if REVISION is SVN_INVALID_REVNUM
1444251881Speter   (to get the current youngest revnum), or if the specified REVISION is not
1445251881Speter   (yet) in our cache of baseline collections.
1446251881Speter
1447251881Speter   All temporary allocations are performed in SCRATCH_POOL.  */
1448251881Spetersvn_error_t *
1449251881Spetersvn_ra_serf__get_stable_url(const char **stable_url,
1450251881Speter                            svn_revnum_t *latest_revnum,
1451251881Speter                            svn_ra_serf__session_t *session,
1452251881Speter                            svn_ra_serf__connection_t *conn,
1453251881Speter                            const char *url,
1454251881Speter                            svn_revnum_t revision,
1455251881Speter                            apr_pool_t *result_pool,
1456251881Speter                            apr_pool_t *scratch_pool);
1457251881Speter
1458251881Speter
1459251881Speter/** RA functions **/
1460251881Speter
1461251881Speter/* Implements svn_ra__vtable_t.get_log(). */
1462251881Spetersvn_error_t *
1463251881Spetersvn_ra_serf__get_log(svn_ra_session_t *session,
1464251881Speter                     const apr_array_header_t *paths,
1465251881Speter                     svn_revnum_t start,
1466251881Speter                     svn_revnum_t end,
1467251881Speter                     int limit,
1468251881Speter                     svn_boolean_t discover_changed_paths,
1469251881Speter                     svn_boolean_t strict_node_history,
1470251881Speter                     svn_boolean_t include_merged_revisions,
1471251881Speter                     const apr_array_header_t *revprops,
1472251881Speter                     svn_log_entry_receiver_t receiver,
1473251881Speter                     void *receiver_baton,
1474251881Speter                     apr_pool_t *pool);
1475251881Speter
1476251881Speter/* Implements svn_ra__vtable_t.get_locations(). */
1477251881Spetersvn_error_t *
1478251881Spetersvn_ra_serf__get_locations(svn_ra_session_t *session,
1479251881Speter                           apr_hash_t **locations,
1480251881Speter                           const char *path,
1481251881Speter                           svn_revnum_t peg_revision,
1482251881Speter                           const apr_array_header_t *location_revisions,
1483251881Speter                           apr_pool_t *pool);
1484251881Speter
1485251881Speter/* Implements svn_ra__vtable_t.get_location_segments(). */
1486251881Spetersvn_error_t *
1487251881Spetersvn_ra_serf__get_location_segments(svn_ra_session_t *session,
1488251881Speter                                   const char *path,
1489251881Speter                                   svn_revnum_t peg_revision,
1490251881Speter                                   svn_revnum_t start_rev,
1491251881Speter                                   svn_revnum_t end_rev,
1492251881Speter                                   svn_location_segment_receiver_t receiver,
1493251881Speter                                   void *receiver_baton,
1494251881Speter                                   apr_pool_t *pool);
1495251881Speter
1496251881Speter/* Implements svn_ra__vtable_t.do_diff(). */
1497251881Spetersvn_error_t *
1498251881Spetersvn_ra_serf__do_diff(svn_ra_session_t *session,
1499251881Speter                     const svn_ra_reporter3_t **reporter,
1500251881Speter                     void **report_baton,
1501251881Speter                     svn_revnum_t revision,
1502251881Speter                     const char *diff_target,
1503251881Speter                     svn_depth_t depth,
1504251881Speter                     svn_boolean_t ignore_ancestry,
1505251881Speter                     svn_boolean_t text_deltas,
1506251881Speter                     const char *versus_url,
1507251881Speter                     const svn_delta_editor_t *diff_editor,
1508251881Speter                     void *diff_baton,
1509251881Speter                     apr_pool_t *pool);
1510251881Speter
1511251881Speter/* Implements svn_ra__vtable_t.do_status(). */
1512251881Spetersvn_error_t *
1513251881Spetersvn_ra_serf__do_status(svn_ra_session_t *ra_session,
1514251881Speter                       const svn_ra_reporter3_t **reporter,
1515251881Speter                       void **report_baton,
1516251881Speter                       const char *status_target,
1517251881Speter                       svn_revnum_t revision,
1518251881Speter                       svn_depth_t depth,
1519251881Speter                       const svn_delta_editor_t *status_editor,
1520251881Speter                       void *status_baton,
1521251881Speter                       apr_pool_t *pool);
1522251881Speter
1523251881Speter/* Implements svn_ra__vtable_t.do_update(). */
1524251881Spetersvn_error_t *
1525251881Spetersvn_ra_serf__do_update(svn_ra_session_t *ra_session,
1526251881Speter                       const svn_ra_reporter3_t **reporter,
1527251881Speter                       void **report_baton,
1528251881Speter                       svn_revnum_t revision_to_update_to,
1529251881Speter                       const char *update_target,
1530251881Speter                       svn_depth_t depth,
1531251881Speter                       svn_boolean_t send_copyfrom_args,
1532251881Speter                       svn_boolean_t ignore_ancestry,
1533251881Speter                       const svn_delta_editor_t *update_editor,
1534251881Speter                       void *update_baton,
1535251881Speter                       apr_pool_t *result_pool,
1536251881Speter                       apr_pool_t *scratch_pool);
1537251881Speter
1538251881Speter/* Implements svn_ra__vtable_t.do_switch(). */
1539251881Spetersvn_error_t *
1540251881Spetersvn_ra_serf__do_switch(svn_ra_session_t *ra_session,
1541251881Speter                       const svn_ra_reporter3_t **reporter,
1542251881Speter                       void **report_baton,
1543251881Speter                       svn_revnum_t revision_to_switch_to,
1544251881Speter                       const char *switch_target,
1545251881Speter                       svn_depth_t depth,
1546251881Speter                       const char *switch_url,
1547251881Speter                       svn_boolean_t send_copyfrom_args,
1548251881Speter                       svn_boolean_t ignore_ancestry,
1549251881Speter                       const svn_delta_editor_t *switch_editor,
1550251881Speter                       void *switch_baton,
1551251881Speter                       apr_pool_t *result_pool,
1552251881Speter                       apr_pool_t *scratch_pool);
1553251881Speter
1554251881Speter/* Implements svn_ra__vtable_t.get_file_revs(). */
1555251881Spetersvn_error_t *
1556251881Spetersvn_ra_serf__get_file_revs(svn_ra_session_t *session,
1557251881Speter                           const char *path,
1558251881Speter                           svn_revnum_t start,
1559251881Speter                           svn_revnum_t end,
1560251881Speter                           svn_boolean_t include_merged_revisions,
1561251881Speter                           svn_file_rev_handler_t handler,
1562251881Speter                           void *handler_baton,
1563251881Speter                           apr_pool_t *pool);
1564251881Speter
1565251881Speter/* Implements svn_ra__vtable_t.get_dated_revision(). */
1566251881Spetersvn_error_t *
1567251881Spetersvn_ra_serf__get_dated_revision(svn_ra_session_t *session,
1568251881Speter                                svn_revnum_t *revision,
1569251881Speter                                apr_time_t tm,
1570251881Speter                                apr_pool_t *pool);
1571251881Speter
1572251881Speter/* Implements svn_ra__vtable_t.get_commit_editor(). */
1573251881Spetersvn_error_t *
1574251881Spetersvn_ra_serf__get_commit_editor(svn_ra_session_t *session,
1575251881Speter                               const svn_delta_editor_t **editor,
1576251881Speter                               void **edit_baton,
1577251881Speter                               apr_hash_t *revprop_table,
1578251881Speter                               svn_commit_callback2_t callback,
1579251881Speter                               void *callback_baton,
1580251881Speter                               apr_hash_t *lock_tokens,
1581251881Speter                               svn_boolean_t keep_locks,
1582251881Speter                               apr_pool_t *pool);
1583251881Speter
1584251881Speter/* Implements svn_ra__vtable_t.get_file(). */
1585251881Spetersvn_error_t *
1586251881Spetersvn_ra_serf__get_file(svn_ra_session_t *session,
1587251881Speter                      const char *path,
1588251881Speter                      svn_revnum_t revision,
1589251881Speter                      svn_stream_t *stream,
1590251881Speter                      svn_revnum_t *fetched_rev,
1591251881Speter                      apr_hash_t **props,
1592251881Speter                      apr_pool_t *pool);
1593251881Speter
1594251881Speter/* Implements svn_ra__vtable_t.change_rev_prop(). */
1595251881Spetersvn_error_t *
1596251881Spetersvn_ra_serf__change_rev_prop(svn_ra_session_t *session,
1597251881Speter                             svn_revnum_t rev,
1598251881Speter                             const char *name,
1599251881Speter                             const svn_string_t *const *old_value_p,
1600251881Speter                             const svn_string_t *value,
1601251881Speter                             apr_pool_t *pool);
1602251881Speter
1603251881Speter/* Implements svn_ra__vtable_t.replay(). */
1604251881Spetersvn_error_t *
1605251881Spetersvn_ra_serf__replay(svn_ra_session_t *ra_session,
1606251881Speter                    svn_revnum_t revision,
1607251881Speter                    svn_revnum_t low_water_mark,
1608251881Speter                    svn_boolean_t text_deltas,
1609251881Speter                    const svn_delta_editor_t *editor,
1610251881Speter                    void *edit_baton,
1611251881Speter                    apr_pool_t *pool);
1612251881Speter
1613251881Speter/* Implements svn_ra__vtable_t.replay_range(). */
1614251881Spetersvn_error_t *
1615251881Spetersvn_ra_serf__replay_range(svn_ra_session_t *ra_session,
1616251881Speter                          svn_revnum_t start_revision,
1617251881Speter                          svn_revnum_t end_revision,
1618251881Speter                          svn_revnum_t low_water_mark,
1619251881Speter                          svn_boolean_t send_deltas,
1620251881Speter                          svn_ra_replay_revstart_callback_t revstart_func,
1621251881Speter                          svn_ra_replay_revfinish_callback_t revfinish_func,
1622251881Speter                          void *replay_baton,
1623251881Speter                          apr_pool_t *pool);
1624251881Speter
1625251881Speter/* Implements svn_ra__vtable_t.lock(). */
1626251881Spetersvn_error_t *
1627251881Spetersvn_ra_serf__lock(svn_ra_session_t *ra_session,
1628251881Speter                  apr_hash_t *path_revs,
1629251881Speter                  const char *comment,
1630251881Speter                  svn_boolean_t force,
1631251881Speter                  svn_ra_lock_callback_t lock_func,
1632251881Speter                  void *lock_baton,
1633251881Speter                  apr_pool_t *pool);
1634251881Speter
1635251881Speter/* Implements svn_ra__vtable_t.unlock(). */
1636251881Spetersvn_error_t *
1637251881Spetersvn_ra_serf__unlock(svn_ra_session_t *ra_session,
1638251881Speter                    apr_hash_t *path_tokens,
1639251881Speter                    svn_boolean_t force,
1640251881Speter                    svn_ra_lock_callback_t lock_func,
1641251881Speter                    void *lock_baton,
1642251881Speter                    apr_pool_t *pool);
1643251881Speter
1644251881Speter/* Implements svn_ra__vtable_t.get_lock(). */
1645251881Spetersvn_error_t *
1646251881Spetersvn_ra_serf__get_lock(svn_ra_session_t *ra_session,
1647251881Speter                      svn_lock_t **lock,
1648251881Speter                      const char *path,
1649251881Speter                      apr_pool_t *pool);
1650251881Speter
1651251881Speter/* Implements svn_ra__vtable_t.get_locks(). */
1652251881Spetersvn_error_t *
1653251881Spetersvn_ra_serf__get_locks(svn_ra_session_t *ra_session,
1654251881Speter                       apr_hash_t **locks,
1655251881Speter                       const char *path,
1656251881Speter                       svn_depth_t depth,
1657251881Speter                       apr_pool_t *pool);
1658251881Speter
1659251881Speter/* Request a mergeinfo-report from the URL attached to SESSION,
1660251881Speter   and fill in the MERGEINFO hash with the results.
1661251881Speter
1662251881Speter   Implements svn_ra__vtable_t.get_mergeinfo().
1663251881Speter */
1664251881Spetersvn_error_t *
1665251881Spetersvn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
1666251881Speter                           apr_hash_t **mergeinfo,
1667251881Speter                           const apr_array_header_t *paths,
1668251881Speter                           svn_revnum_t revision,
1669251881Speter                           svn_mergeinfo_inheritance_t inherit,
1670251881Speter                           svn_boolean_t include_descendants,
1671251881Speter                           apr_pool_t *pool);
1672251881Speter
1673251881Speter/* Exchange capabilities with the server, by sending an OPTIONS
1674251881Speter * request announcing the client's capabilities, and by filling
1675251881Speter * SERF_SESS->capabilities with the server's capabilities as read from
1676251881Speter * the response headers.  Use POOL only for temporary allocation.
1677251881Speter *
1678251881Speter * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to
1679251881Speter * report a server-dictated redirect or relocation (HTTP 301 or 302
1680251881Speter * error codes), setting *CORRECTED_URL to the value of the corrected
1681251881Speter * repository URL.  Otherwise, such responses from the server will
1682251881Speter * generate an error.  (In either case, no capabilities are exchanged
1683251881Speter * if there is, in fact, such a response from the server.)
1684251881Speter */
1685251881Spetersvn_error_t *
1686251881Spetersvn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess,
1687251881Speter                                   const char **corrected_url,
1688251881Speter                                   apr_pool_t *pool);
1689251881Speter
1690251881Speter/* Implements svn_ra__vtable_t.has_capability(). */
1691251881Spetersvn_error_t *
1692251881Spetersvn_ra_serf__has_capability(svn_ra_session_t *ra_session,
1693251881Speter                            svn_boolean_t *has,
1694251881Speter                            const char *capability,
1695251881Speter                            apr_pool_t *pool);
1696251881Speter
1697251881Speter/* Implements svn_ra__vtable_t.get_deleted_rev(). */
1698251881Spetersvn_error_t *
1699251881Spetersvn_ra_serf__get_deleted_rev(svn_ra_session_t *session,
1700251881Speter                             const char *path,
1701251881Speter                             svn_revnum_t peg_revision,
1702251881Speter                             svn_revnum_t end_revision,
1703251881Speter                             svn_revnum_t *revision_deleted,
1704251881Speter                             apr_pool_t *pool);
1705251881Speter
1706251881Speter/* Implements the get_inherited_props RA layer function. */
1707251881Spetersvn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session,
1708251881Speter                                               apr_array_header_t **iprops,
1709251881Speter                                               const char *path,
1710251881Speter                                               svn_revnum_t revision,
1711251881Speter                                               apr_pool_t *result_pool,
1712251881Speter                                               apr_pool_t *scratch_pool);
1713251881Speter
1714251881Speter/* Implements svn_ra__vtable_t.get_repos_root(). */
1715251881Spetersvn_error_t *
1716251881Spetersvn_ra_serf__get_repos_root(svn_ra_session_t *ra_session,
1717251881Speter                            const char **url,
1718251881Speter                            apr_pool_t *pool);
1719251881Speter
1720251881Speter/* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */
1721251881Spetersvn_error_t *
1722251881Spetersvn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
1723251881Speter                                    svn_delta_shim_callbacks_t *callbacks);
1724251881Speter
1725251881Speter/*** Authentication handler declarations ***/
1726251881Speter
1727251881Speter/**
1728251881Speter * Callback function that loads the credentials for Basic and Digest
1729251881Speter * authentications, both for server and proxy authentication.
1730251881Speter */
1731251881Speterapr_status_t
1732251881Spetersvn_ra_serf__credentials_callback(char **username, char **password,
1733251881Speter                                  serf_request_t *request, void *baton,
1734251881Speter                                  int code, const char *authn_type,
1735251881Speter                                  const char *realm,
1736251881Speter                                  apr_pool_t *pool);
1737251881Speter
1738251881Speter
1739251881Speter/*** General utility functions ***/
1740251881Speter
1741251881Speter/**
1742251881Speter * Convert an HTTP STATUS_CODE resulting from a WebDAV request against
1743251881Speter * PATH to the relevant error code.  Use the response-supplied LOCATION
1744251881Speter * where it necessary.
1745251881Speter */
1746251881Spetersvn_error_t *
1747251881Spetersvn_ra_serf__error_on_status(int status_code,
1748251881Speter                             const char *path,
1749251881Speter                             const char *location);
1750251881Speter
1751251881Speter/* ###? */
1752251881Spetersvn_error_t *
1753251881Spetersvn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf,
1754251881Speter                                serf_bucket_t *bkt,
1755251881Speter                                apr_pool_t *result_pool,
1756251881Speter                                apr_pool_t *scratch_pool);
1757251881Speter
1758251881Speter/* ###? */
1759251881Speterserf_bucket_t *
1760251881Spetersvn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf,
1761251881Speter                              serf_bucket_alloc_t *allocator,
1762251881Speter                              apr_pool_t *result_pool,
1763251881Speter                              apr_pool_t *scratch_pool);
1764251881Speter
1765251881Speter/** Wrap STATUS from an serf function. If STATUS is not serf error code,
1766251881Speter  * this is equivalent to svn_error_wrap_apr().
1767251881Speter */
1768251881Spetersvn_error_t *
1769251881Spetersvn_ra_serf__wrap_err(apr_status_t status,
1770251881Speter                      const char *fmt,
1771251881Speter                      ...);
1772251881Speter
1773251881Speter
1774251881Speter#if defined(SVN_DEBUG)
1775251881Speter/* Wrapper macros to collect file and line information */
1776251881Speter#define svn_ra_serf__wrap_err \
1777251881Speter  (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err))
1778251881Speter
1779251881Speter#endif
1780251881Speter
1781251881Speter#ifdef __cplusplus
1782251881Speter}
1783251881Speter#endif /* __cplusplus */
1784251881Speter
1785251881Speter#endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */
1786