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 <apr_uri.h>
30251881Speter
31251881Speter#include "svn_types.h"
32251881Speter#include "svn_string.h"
33251881Speter#include "svn_pools.h"
34251881Speter#include "svn_ra.h"
35251881Speter#include "svn_delta.h"
36251881Speter#include "svn_version.h"
37251881Speter#include "svn_dav.h"
38251881Speter#include "svn_dirent_uri.h"
39251881Speter
40251881Speter#include "private/svn_dav_protocol.h"
41251881Speter#include "private/svn_subr_private.h"
42251881Speter#include "private/svn_editor.h"
43251881Speter
44251881Speter#include "blncache.h"
45251881Speter
46251881Speter#ifdef __cplusplus
47251881Speterextern "C" {
48251881Speter#endif /* __cplusplus */
49251881Speter
50251881Speter
51251881Speter/* Enforce the minimum version of serf. */
52251881Speter#if !SERF_VERSION_AT_LEAST(1, 2, 1)
53251881Speter#error Please update your version of serf to at least 1.2.1.
54251881Speter#endif
55251881Speter
56251881Speter/** Wait duration (in microseconds) used in calls to serf_context_run() */
57251881Speter#define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000
58251881Speter
59251881Speter
60251881Speter
61251881Speter/* Forward declarations. */
62251881Spetertypedef struct svn_ra_serf__session_t svn_ra_serf__session_t;
63251881Speter
64251881Speter/* A serf connection and optionally associated SSL context.  */
65251881Spetertypedef struct svn_ra_serf__connection_t {
66251881Speter  /* Our connection to a server. */
67251881Speter  serf_connection_t *conn;
68251881Speter
69251881Speter  /* Bucket allocator for this connection. */
70251881Speter  serf_bucket_alloc_t *bkt_alloc;
71251881Speter
72251881Speter  /* Collected cert failures in chain.  */
73251881Speter  int server_cert_failures;
74251881Speter
75251881Speter  /* What was the last HTTP status code we got on this connection? */
76251881Speter  int last_status_code;
77251881Speter
78251881Speter  /* Optional SSL context for this connection. */
79251881Speter  serf_ssl_context_t *ssl_context;
80251881Speter  svn_auth_iterstate_t *ssl_client_auth_state;
81251881Speter  svn_auth_iterstate_t *ssl_client_pw_auth_state;
82251881Speter
83251881Speter  svn_ra_serf__session_t *session;
84251881Speter
85251881Speter} svn_ra_serf__connection_t;
86251881Speter
87251881Speter/** Maximum value we'll allow for the http-max-connections config option.
88251881Speter *
89251881Speter * Note: minimum 2 connections are required for ra_serf to function
90251881Speter * correctly!
91251881Speter */
92251881Speter#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8
93251881Speter
94251881Speter/*
95251881Speter * The master serf RA session.
96251881Speter *
97251881Speter * This is stored in the ra session ->priv field.
98289180Speter *
99289180Speter * ### Check ra_serf_dup_session when adding fields.
100251881Speter */
101251881Speterstruct svn_ra_serf__session_t {
102251881Speter  /* Pool for allocations during this session */
103251881Speter  apr_pool_t *pool;
104289180Speter  apr_hash_t *config; /* For duplicating */
105251881Speter
106251881Speter  /* The current context */
107251881Speter  serf_context_t *context;
108251881Speter
109251881Speter  /* The maximum number of connections we'll use for parallelized
110251881Speter     fetch operations (updates, etc.) */
111251881Speter  apr_int64_t max_connections;
112251881Speter
113251881Speter  /* Are we using ssl */
114251881Speter  svn_boolean_t using_ssl;
115251881Speter
116362181Sdim  /* Tristate flag that indicates if we should use compression for
117362181Sdim     network transmissions.  If svn_tristate_true or svn_tristate_false,
118362181Sdim     the compression should be enabled and disabled, respectively.
119362181Sdim     If svn_tristate_unknown, determine this automatically based
120362181Sdim     on network parameters. */
121362181Sdim  svn_tristate_t using_compression;
122251881Speter
123251881Speter  /* The user agent string */
124251881Speter  const char *useragent;
125251881Speter
126251881Speter  /* The current connection */
127251881Speter  svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT];
128251881Speter  int num_conns;
129251881Speter  int cur_conn;
130251881Speter
131251881Speter  /* The URL that was passed into _open() */
132251881Speter  apr_uri_t session_url;
133251881Speter  const char *session_url_str;
134251881Speter
135251881Speter  /* The actual discovered root; may be NULL until we know it. */
136251881Speter  apr_uri_t repos_root;
137251881Speter  const char *repos_root_str;
138251881Speter
139251881Speter  /* The server is not Apache/mod_dav_svn (directly) and only supports
140251881Speter     HTTP/1.0. Thus, we cannot send chunked requests.  */
141251881Speter  svn_boolean_t http10;
142251881Speter
143362181Sdim  /* We are talking to the server via http/2. Responses of scheduled
144362181Sdim     requests may come in any order */
145362181Sdim  svn_boolean_t http20;
146362181Sdim
147253734Speter  /* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */
148253734Speter  svn_boolean_t using_chunked_requests;
149253734Speter
150253734Speter  /* Do we need to detect whether the connection supports chunked requests?
151253734Speter     i.e. is there a (reverse) proxy that does not support them?  */
152253734Speter  svn_boolean_t detect_chunking;
153253734Speter
154251881Speter  /* Our Version-Controlled-Configuration; may be NULL until we know it. */
155251881Speter  const char *vcc_url;
156251881Speter
157251881Speter  /* Authentication related properties. */
158251881Speter  svn_auth_iterstate_t *auth_state;
159251881Speter  int auth_attempts;
160251881Speter
161251881Speter  /* Callback functions to get info from WC */
162251881Speter  const svn_ra_callbacks2_t *wc_callbacks;
163251881Speter  void *wc_callback_baton;
164289180Speter  svn_auth_baton_t *auth_baton;
165251881Speter
166251881Speter  /* Callback function to send progress info to the client */
167251881Speter  svn_ra_progress_notify_func_t progress_func;
168251881Speter  void *progress_baton;
169251881Speter
170251881Speter  /* Callback function to handle cancellation */
171251881Speter  svn_cancel_func_t cancel_func;
172251881Speter  void *cancel_baton;
173251881Speter
174251881Speter  /* Ev2 shim callbacks */
175251881Speter  svn_delta_shim_callbacks_t *shim_callbacks;
176251881Speter
177251881Speter  /* Error that we've received but not yet returned upstream. */
178251881Speter  svn_error_t *pending_error;
179251881Speter
180251881Speter  /* List of authn types supported by the client.*/
181251881Speter  int authn_types;
182251881Speter
183251881Speter  /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values.
184251881Speter     If a capability is not yet discovered, it is absent from the table.
185251881Speter     The table itself is allocated in the svn_ra_serf__session_t's pool;
186251881Speter     keys and values must have at least that lifetime.  Most likely
187251881Speter     the keys and values are constants anyway (and sufficiently
188251881Speter     well-informed internal code may just compare against those
189251881Speter     constants' addresses, therefore). */
190251881Speter  apr_hash_t *capabilities;
191251881Speter
192251881Speter  /* Activity collection URL.  (Cached from the initial OPTIONS
193251881Speter     request when run against HTTPv1 servers.)  */
194251881Speter  const char *activity_collection_url;
195251881Speter
196251881Speter  /* Are we using a proxy? */
197253734Speter  svn_boolean_t using_proxy;
198251881Speter
199251881Speter  const char *proxy_username;
200251881Speter  const char *proxy_password;
201251881Speter  int proxy_auth_attempts;
202251881Speter
203251881Speter  /* SSL server certificates */
204251881Speter  svn_boolean_t trust_default_ca;
205251881Speter  const char *ssl_authorities;
206251881Speter
207251881Speter  /* Repository UUID */
208251881Speter  const char *uuid;
209251881Speter
210251881Speter  /* Connection timeout value */
211251881Speter  apr_interval_time_t timeout;
212251881Speter
213251881Speter  /* HTTPv1 flags */
214251881Speter  svn_tristate_t supports_deadprop_count;
215251881Speter
216251881Speter  /*** HTTP v2 protocol stuff. ***
217251881Speter   *
218251881Speter   * We assume that if mod_dav_svn sends one of the special v2 OPTIONs
219251881Speter   * response headers, it has sent all of them.  Specifically, we'll
220251881Speter   * be looking at the presence of the "me resource" as a flag that
221251881Speter   * the server supports v2 of our HTTP protocol.
222251881Speter   */
223251881Speter
224251881Speter  /* The "me resource".  Typically used as a target for REPORTs that
225251881Speter     are path-agnostic.  If we have this, we can speak HTTP v2 to the
226251881Speter     server.  */
227251881Speter  const char *me_resource;
228251881Speter
229251881Speter  /* Opaque URL "stubs".  If the OPTIONS response returns these, then
230251881Speter     we know we're using HTTP protocol v2. */
231251881Speter  const char *rev_stub;         /* for accessing revisions (i.e. revprops) */
232251881Speter  const char *rev_root_stub;    /* for accessing REV/PATH pairs */
233251881Speter  const char *txn_stub;         /* for accessing transactions (i.e. txnprops) */
234251881Speter  const char *txn_root_stub;    /* for accessing TXN/PATH pairs */
235251881Speter  const char *vtxn_stub;        /* for accessing transactions (i.e. txnprops) */
236251881Speter  const char *vtxn_root_stub;   /* for accessing TXN/PATH pairs */
237251881Speter
238251881Speter  /* Hash mapping const char * server-supported POST types to
239251881Speter     disinteresting-but-non-null values. */
240251881Speter  apr_hash_t *supported_posts;
241251881Speter
242251881Speter  /*** End HTTP v2 stuff ***/
243251881Speter
244251881Speter  svn_ra_serf__blncache_t *blncache;
245251881Speter
246251881Speter  /* Trisate flag that indicates user preference for using bulk updates
247251881Speter     (svn_tristate_true) with all the properties and content in the
248251881Speter     update-report response. If svn_tristate_false, request a skelta
249251881Speter     update-report with inlined properties. If svn_tristate_unknown then use
250251881Speter     server preference. */
251251881Speter  svn_tristate_t bulk_updates;
252251881Speter
253251881Speter  /* Indicates if the server wants bulk update requests (Prefer) or only
254251881Speter     accepts skelta requests (Off). If this value is On both options are
255251881Speter     allowed. */
256251881Speter  const char *server_allows_bulk;
257251881Speter
258251881Speter  /* Indicates if the server supports sending inlined props in update editor
259251881Speter   * in skelta mode (send-all == 'false'). */
260251881Speter  svn_boolean_t supports_inline_props;
261251881Speter
262251881Speter  /* Indicates whether the server supports issuing replay REPORTs
263251881Speter     against rev resources (children of `rev_stub', elsestruct). */
264251881Speter  svn_boolean_t supports_rev_rsrc_replay;
265362181Sdim
266362181Sdim  /* Indicates whether the server can understand svndiff version 1. */
267362181Sdim  svn_boolean_t supports_svndiff1;
268362181Sdim
269362181Sdim  /* Indicates whether the server can understand svndiff version 2. */
270362181Sdim  svn_boolean_t supports_svndiff2;
271362181Sdim
272362181Sdim  /* Indicates whether the server sends the result checksum in the response
273362181Sdim   * to a successful PUT request. */
274362181Sdim  svn_boolean_t supports_put_result_checksum;
275362181Sdim
276362181Sdim  apr_interval_time_t conn_latency;
277251881Speter};
278251881Speter
279251881Speter#define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL)
280251881Speter
281251881Speter/*
282251881Speter * Structure which represents a DAV element with a NAMESPACE and NAME.
283251881Speter */
284251881Spetertypedef struct svn_ra_serf__dav_props_t {
285251881Speter  /* Element namespace */
286289180Speter  const char *xmlns;
287251881Speter  /* Element name */
288251881Speter  const char *name;
289251881Speter} svn_ra_serf__dav_props_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
381289180Speter/* Run the context once. Manage waittime_left to handle timing out when
382289180Speter   nothing happens over the session->timout.
383289180Speter */
384289180Spetersvn_error_t *
385289180Spetersvn_ra_serf__context_run(svn_ra_serf__session_t *sess,
386289180Speter                         apr_interval_time_t *waittime_left,
387289180Speter                         apr_pool_t *scratch_pool);
388289180Speter
389289180Speter
390289180Speter
391251881Speter/* Callback for response handlers */
392251881Spetertypedef svn_error_t *
393251881Speter(*svn_ra_serf__response_handler_t)(serf_request_t *request,
394251881Speter                                   serf_bucket_t *response,
395251881Speter                                   void *handler_baton,
396251881Speter                                   apr_pool_t *scratch_pool);
397251881Speter
398289180Speter/* Callback when the request is done */
399289180Spetertypedef svn_error_t *
400289180Speter(*svn_ra_serf__response_done_delegate_t)(serf_request_t *request,
401289180Speter                                         void *done_baton,
402289180Speter                                         apr_pool_t *scratch_pool);
403289180Speter
404251881Speter/* Callback for when a request body is needed. */
405251881Spetertypedef svn_error_t *
406251881Speter(*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
407251881Speter                                        void *baton,
408251881Speter                                        serf_bucket_alloc_t *alloc,
409289180Speter                                        apr_pool_t *request_pool,
410289180Speter                                        apr_pool_t *scratch_pool);
411251881Speter
412251881Speter/* Callback for when request headers are needed. */
413251881Spetertypedef svn_error_t *
414251881Speter(*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
415251881Speter                                          void *baton,
416289180Speter                                          apr_pool_t *request_pool,
417289180Speter                                          apr_pool_t *scratch_pool);
418251881Speter
419251881Speter/* Callback for when a response has an error. */
420251881Spetertypedef svn_error_t *
421251881Speter(*svn_ra_serf__response_error_t)(serf_request_t *request,
422251881Speter                                 serf_bucket_t *response,
423251881Speter                                 int status_code,
424251881Speter                                 void *baton);
425251881Speter
426251881Speter/* ### we should reorder the types in this file.  */
427251881Spetertypedef struct svn_ra_serf__server_error_t svn_ra_serf__server_error_t;
428251881Speter
429251881Speter/*
430251881Speter * Structure that can be passed to our default handler to guide the
431251881Speter * execution of the request through its lifecycle.
432289180Speter *
433289180Speter * Use svn_ra_serf__create_handler() to create instances of this struct.
434251881Speter */
435251881Spetertypedef struct svn_ra_serf__handler_t {
436251881Speter  /* The HTTP method string of the request */
437251881Speter  const char *method;
438251881Speter
439251881Speter  /* The resource to the execute the method on. */
440251881Speter  const char *path;
441251881Speter
442251881Speter  /* The content-type of the request body. */
443251881Speter  const char *body_type;
444251881Speter
445251881Speter  /* If TRUE then default Accept-Encoding request header is not configured for
446251881Speter     request. If FALSE then 'gzip' accept encoding will be used if compression
447251881Speter     enabled. */
448251881Speter  svn_boolean_t custom_accept_encoding;
449251881Speter
450289180Speter  /* If TRUE then default DAV: capabilities request headers is not configured
451289180Speter     for request. */
452289180Speter  svn_boolean_t no_dav_headers;
453289180Speter
454289180Speter  /* If TRUE doesn't fail requests on HTTP error statuses like 405, 408, 500
455289180Speter     (see util.c response_done()) */
456289180Speter  svn_boolean_t no_fail_on_http_failure_status;
457289180Speter
458289180Speter  /* If TRUE doesn't fail requests on HTTP redirect statuses like 301, 307 */
459289180Speter  svn_boolean_t no_fail_on_http_redirect_status;
460289180Speter
461251881Speter  /* Has the request/response been completed?  */
462251881Speter  svn_boolean_t done;
463289180Speter  svn_boolean_t scheduled; /* Is the request scheduled in a context */
464251881Speter
465251881Speter  /* If we captured an error from the server, then this will be non-NULL.
466251881Speter     It will be allocated from HANDLER_POOL.  */
467251881Speter  svn_ra_serf__server_error_t *server_error;
468251881Speter
469251881Speter  /* The handler and baton pair for our handler. */
470251881Speter  svn_ra_serf__response_handler_t response_handler;
471251881Speter  void *response_baton;
472251881Speter
473251881Speter  /* When REPONSE_HANDLER is invoked, the following fields will be set
474251881Speter     based on the response header. HANDLER_POOL must be non-NULL for these
475251881Speter     values to be filled in. SLINE.REASON and LOCATION will be allocated
476251881Speter     within HANDLER_POOL.  */
477251881Speter  serf_status_line sline;  /* The parsed Status-Line  */
478251881Speter  const char *location;  /* The Location: header, if any  */
479251881Speter
480289180Speter  /* This function and baton pair allows handling the completion of request.
481289180Speter   *
482289180Speter   * The default handler is responsible for the HTTP failure processing.
483289180Speter   *
484289180Speter   * If no_fail_on_http_failure_status is not TRUE, then the callback will
485289180Speter   * return recorded server errors or if there is none and the http status
486289180Speter   * specifies an error returns an error for that.
487289180Speter   *
488289180Speter   * The default baton is the handler itself.
489289180Speter   */
490289180Speter  svn_ra_serf__response_done_delegate_t done_delegate;
491289180Speter  void *done_delegate_baton;
492289180Speter
493251881Speter  /* The handler and baton pair to be executed when a non-recoverable error
494251881Speter   * is detected.  If it is NULL in the presence of an error, an abort() may
495251881Speter   * be triggered.
496251881Speter   */
497251881Speter  svn_ra_serf__response_error_t response_error;
498251881Speter  void *response_error_baton;
499251881Speter
500251881Speter  /* This function and baton pair allows for custom request headers to
501251881Speter   * be set.
502251881Speter   *
503251881Speter   * It will be executed after the request has been set up but before it is
504251881Speter   * delivered.
505251881Speter   */
506251881Speter  svn_ra_serf__request_header_delegate_t header_delegate;
507251881Speter  void *header_delegate_baton;
508251881Speter
509251881Speter  /* This function and baton pair allows a body to be created right before
510251881Speter   * delivery.
511251881Speter   *
512251881Speter   * It will be executed after the request has been set up but before it is
513251881Speter   * delivered.
514251881Speter   *
515251881Speter   * May be NULL if there is no body to send.
516251881Speter   *
517251881Speter   */
518251881Speter  svn_ra_serf__request_body_delegate_t body_delegate;
519251881Speter  void *body_delegate_baton;
520251881Speter
521251881Speter  /* The connection and session to be used for this request. */
522251881Speter  svn_ra_serf__connection_t *conn;
523251881Speter  svn_ra_serf__session_t *session;
524251881Speter
525251881Speter  /* Internal flag to indicate we've parsed the headers.  */
526251881Speter  svn_boolean_t reading_body;
527251881Speter
528251881Speter  /* When this flag will be set, the core handler will discard any unread
529251881Speter     portion of the response body. The registered response handler will
530251881Speter     no longer be called.  */
531251881Speter  svn_boolean_t discard_body;
532251881Speter
533251881Speter  /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL,
534251881Speter     then the requestor does not care about SLINE and LOCATION.  */
535251881Speter  apr_pool_t *handler_pool;
536251881Speter} svn_ra_serf__handler_t;
537251881Speter
538251881Speter
539251881Speter/* Run one request and process the response.
540251881Speter
541251881Speter   Similar to context_run_wait(), but this creates the request for HANDLER
542251881Speter   and then waits for it to complete.
543251881Speter
544251881Speter   WARNING: context_run_wait() does NOT create a request, whereas this
545251881Speter   function DOES. Avoid a double-create.  */
546251881Spetersvn_error_t *
547251881Spetersvn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
548251881Speter                             apr_pool_t *scratch_pool);
549251881Speter
550251881Speter
551251881Speter/*
552251881Speter * Helper function to queue a request in the @a handler's connection.
553251881Speter */
554251881Spetervoid svn_ra_serf__request_create(svn_ra_serf__handler_t *handler);
555251881Speter
556251881Speter/* v2 of the XML parsing functions  */
557251881Speter
558251881Speter/* The XML parsing context.  */
559251881Spetertypedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t;
560251881Speter
561251881Speter
562251881Speter/* An opaque structure for the XML parse element/state.  */
563251881Spetertypedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t;
564251881Speter
565251881Speter/* Called just after the parser moves into ENTERED_STATE. The tag causing
566251881Speter   the transition is passed in TAG.
567251881Speter
568251881Speter   This callback is applied to a parsing context by using the
569251881Speter   svn_ra_serf__xml_context_customize() function.
570251881Speter
571251881Speter   NOTE: this callback, when set, will be invoked on *every* transition.
572251881Speter   The callback must examine ENTERED_STATE to determine if any action
573251881Speter   must be taken. The original state is not provided, but must be derived
574251881Speter   from ENTERED_STATE and/or the TAG causing the transition (if needed).  */
575251881Spetertypedef svn_error_t *
576251881Speter(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
577251881Speter                             void *baton,
578251881Speter                             int entered_state,
579251881Speter                             const svn_ra_serf__dav_props_t *tag,
580251881Speter                             apr_pool_t *scratch_pool);
581251881Speter
582251881Speter
583251881Speter/* Called just before the parser leaves LEAVING_STATE.
584251881Speter
585251881Speter   If cdata collection was enabled for this state, then CDATA will be
586251881Speter   non-NULL and contain the collected cdata.
587251881Speter
588251881Speter   If attribute collection was enabled for this state, then ATTRS will
589251881Speter   contain the attributes collected for this element only, along with
590251881Speter   any values stored via svn_ra_serf__xml_note().
591251881Speter
592251881Speter   Use svn_ra_serf__xml_gather_since() to gather up data from outer states.
593251881Speter
594251881Speter   ATTRS is char* -> char*.
595251881Speter
596251881Speter   Temporary allocations may be made in SCRATCH_POOL.  */
597251881Spetertypedef svn_error_t *
598251881Speter(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes,
599251881Speter                             void *baton,
600251881Speter                             int leaving_state,
601251881Speter                             const svn_string_t *cdata,
602251881Speter                             apr_hash_t *attrs,
603251881Speter                             apr_pool_t *scratch_pool);
604251881Speter
605251881Speter
606251881Speter/* Called for all states that are not using the builtin cdata collection.
607251881Speter   This callback is (only) appropriate for unbounded-size cdata content.
608251881Speter
609251881Speter   CURRENT_STATE may be used to decide what to do with the data.
610251881Speter
611251881Speter   Temporary allocations may be made in SCRATCH_POOL.  */
612251881Spetertypedef svn_error_t *
613251881Speter(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
614251881Speter                            void *baton,
615251881Speter                            int current_state,
616251881Speter                            const char *data,
617251881Speter                            apr_size_t len,
618251881Speter                            apr_pool_t *scratch_pool);
619251881Speter
620251881Speter
621289180Speter/* Magic state value for the initial state in a svn_ra_serf__xml_transition_t
622289180Speter   table */
623289180Speter#define XML_STATE_INITIAL 0
624289180Speter
625251881Speter/* State transition table.
626251881Speter
627251881Speter   When the XML Context is constructed, it is in state 0. User states are
628251881Speter   positive integers.
629251881Speter
630251881Speter   In a list of transitions, use { 0 } to indicate the end. Specifically,
631251881Speter   the code looks for NS == NULL.
632251881Speter
633289180Speter   The initial state for each transition table is XML_STATE_INITIAL.
634289180Speter
635251881Speter   ### more docco
636251881Speter*/
637251881Spetertypedef struct svn_ra_serf__xml_transition_t {
638251881Speter  /* This transition applies when in this state  */
639251881Speter  int from_state;
640251881Speter
641251881Speter  /* And when this tag is observed  */
642251881Speter  const char *ns;
643251881Speter  const char *name;
644251881Speter
645251881Speter  /* Moving to this state  */
646251881Speter  int to_state;
647251881Speter
648251881Speter  /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
649251881Speter     be TRUE in order to capture this cdata.  */
650251881Speter  svn_boolean_t collect_cdata;
651251881Speter
652251881Speter  /* Which attributes of NAME should be collected? Terminate with NULL.
653251881Speter     Maximum of 10 attributes may be collected. Note that attribute
654251881Speter     namespaces are ignored at this time.
655251881Speter
656251881Speter     Attribute names beginning with "?" are optional. Other names must
657251881Speter     exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised.  */
658251881Speter  const char *collect_attrs[11];
659251881Speter
660251881Speter  /* When NAME is closed, should the callback be invoked?  */
661251881Speter  svn_boolean_t custom_close;
662251881Speter
663251881Speter} svn_ra_serf__xml_transition_t;
664251881Speter
665289180Speter/* Constructor for svn_ra_serf__handler_t. Initializes a new handler
666289180Speter   with default settings for SESSION. */
667289180Spetersvn_ra_serf__handler_t *
668289180Spetersvn_ra_serf__create_handler(svn_ra_serf__session_t *session,
669289180Speter                            apr_pool_t *result_pool);
670251881Speter
671251881Speter/* Construct an XML parsing context, based on the TTABLE transition table.
672251881Speter   As content is parsed, the CLOSED_CB callback will be invoked according
673251881Speter   to the definition in the table.
674251881Speter
675251881Speter   If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
676251881Speter   event. The callback will need to use the ENTERED_STATE and TAG parameters
677251881Speter   to decide what it would like to do.
678251881Speter
679251881Speter   If CDATA_CB is not NULL, then it will be called for all cdata that is
680251881Speter   not be automatically collected (based on the transition table record's
681251881Speter   COLLECT_CDATA flag). It will be called in every state, so the callback
682251881Speter   must examine the CURRENT_STATE parameter to decide what to do.
683251881Speter
684251881Speter   The same BATON value will be passed to all three callbacks.
685251881Speter
686251881Speter   The context will be created within RESULT_POOL.  */
687251881Spetersvn_ra_serf__xml_context_t *
688251881Spetersvn_ra_serf__xml_context_create(
689251881Speter  const svn_ra_serf__xml_transition_t *ttable,
690251881Speter  svn_ra_serf__xml_opened_t opened_cb,
691251881Speter  svn_ra_serf__xml_closed_t closed_cb,
692251881Speter  svn_ra_serf__xml_cdata_t cdata_cb,
693251881Speter  void *baton,
694251881Speter  apr_pool_t *result_pool);
695251881Speter
696289180Speter/* Verifies if the parsing completed successfully and destroys
697289180Speter   all subpools. */
698289180Spetersvn_error_t *
699289180Spetersvn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx);
700251881Speter
701251881Speter/* Construct a handler with the response function/baton set up to parse
702251881Speter   a response body using the given XML context. The handler and its
703251881Speter   internal structures are allocated in RESULT_POOL.
704251881Speter
705289180Speter   As part of the handling the http status value is compared to 200, or
706289180Speter   if EXPECTED_STATUS is not NULL to all the values in EXPECTED_STATUS.
707289180Speter   EXPECTED_STATUS is expected to be a list of integers ending with a 0
708289180Speter   that lives at least as long as RESULT_POOL. If the status doesn't
709289180Speter   match the request has failed and will be parsed as en error response.
710289180Speter
711251881Speter   This also initializes HANDLER_POOL to the given RESULT_POOL.  */
712251881Spetersvn_ra_serf__handler_t *
713289180Spetersvn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session,
714289180Speter                                  svn_ra_serf__xml_context_t *xmlctx,
715289180Speter                                  const int *expected_status,
716251881Speter                                  apr_pool_t *result_pool);
717251881Speter
718251881Speter
719251881Speter/* Allocated within XES->STATE_POOL. Changes are not allowd (callers
720251881Speter   should make a deep copy if they need to make changes).
721251881Speter
722251881Speter   The resulting hash maps char* names to char* values.  */
723251881Speterapr_hash_t *
724251881Spetersvn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
725251881Speter                              int stop_state);
726251881Speter
727251881Speter
728251881Speter/* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
729251881Speter   The name and value will be copied into the target state's pool.
730251881Speter
731251881Speter   These values will be available to the CLOSED_CB for the target state,
732251881Speter   or part of the gathered state via xml_gather_since().
733251881Speter
734251881Speter   Typically, this function is used by a child state's close callback,
735251881Speter   or within an opening callback to store additional data.
736251881Speter
737251881Speter   Note: if the state is not found, then a programmer error has occurred,
738251881Speter   so the function will invoke SVN_ERR_MALFUNCTION().  */
739251881Spetervoid
740251881Spetersvn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
741251881Speter                      int state,
742251881Speter                      const char *name,
743251881Speter                      const char *value);
744251881Speter
745251881Speter
746251881Speter/* Returns XES->STATE_POOL for allocating structures that should live
747251881Speter   as long as the state identified by XES.
748251881Speter
749251881Speter   Note: a state pool is created upon demand, so only use this function
750251881Speter   when memory is required for a given state.  */
751251881Speterapr_pool_t *
752251881Spetersvn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
753251881Speter
754251881Speter/*
755251881Speter * Parses a server-side error message into a local Subversion error.
756251881Speter */
757251881Speterstruct svn_ra_serf__server_error_t {
758289180Speter  apr_pool_t *pool;
759251881Speter
760289180Speter  /* XML parser and namespace used to parse the remote response */
761289180Speter  svn_ra_serf__xml_context_t *xmlctx;
762251881Speter
763289180Speter  svn_ra_serf__response_handler_t response_handler;
764289180Speter  void *response_baton;
765251881Speter
766289180Speter  /* The partial errors to construct the final error from */
767289180Speter  apr_array_header_t *items;
768251881Speter
769289180Speter  /* The hooked handler */
770289180Speter  svn_ra_serf__handler_t *handler;
771251881Speter};
772251881Speter
773251881Speter/*
774251881Speter * Handler that discards the entire @a response body associated with a
775251881Speter * @a request.  Implements svn_ra_serf__response_handler_t.
776251881Speter *
777251881Speter * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an
778251881Speter * error is detected, it will be populated for later detection.
779251881Speter *
780251881Speter * All temporary allocations will be made in a @a pool.
781251881Speter */
782251881Spetersvn_error_t *
783251881Spetersvn_ra_serf__handle_discard_body(serf_request_t *request,
784251881Speter                                 serf_bucket_t *response,
785251881Speter                                 void *baton,
786251881Speter                                 apr_pool_t *pool);
787251881Speter
788251881Speter
789251881Speter/*
790251881Speter * Handler that retrieves the embedded XML multistatus response from the
791251881Speter * the @a RESPONSE body associated with a @a REQUEST.
792251881Speter *
793251881Speter * Implements svn_ra_serf__response_handler_t.
794251881Speter *
795251881Speter * The @a BATON should be of type svn_ra_serf__handler_t. When the request
796251881Speter * is complete, the handler's DONE flag will be set to TRUE.
797251881Speter *
798251881Speter * All temporary allocations will be made in a @a scratch_pool.
799251881Speter */
800251881Spetersvn_error_t *
801251881Spetersvn_ra_serf__handle_multistatus_only(serf_request_t *request,
802251881Speter                                     serf_bucket_t *response,
803251881Speter                                     void *baton,
804251881Speter                                     apr_pool_t *scratch_pool);
805251881Speter
806251881Speter
807251881Speter/* Handler that expects an empty body.
808251881Speter
809251881Speter   If a body IS present, and it is text/xml, then it will be parsed for
810251881Speter   a server-side error.
811251881Speter
812251881Speter   BATON should be the svn_ra_serf__handler_t running REQUEST.
813251881Speter
814251881Speter   Status line information will be in HANDLER->SLINE.
815251881Speter
816251881Speter   Any parsed errors will be left in HANDLER->SERVER_ERROR. That member
817251881Speter   may be NULL if no body was present, or a problem occurred trying to
818251881Speter   parse the body.
819251881Speter
820251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
821251881Spetersvn_error_t *
822251881Spetersvn_ra_serf__expect_empty_body(serf_request_t *request,
823251881Speter                               serf_bucket_t *response,
824251881Speter                               void *baton,
825251881Speter                               apr_pool_t *scratch_pool);
826251881Speter
827251881Speter
828251881Speter/*
829289180Speter * This function sets up error parsing for an existing request
830251881Speter */
831251881Spetersvn_error_t *
832289180Spetersvn_ra_serf__setup_error_parsing(svn_ra_serf__server_error_t **server_err,
833289180Speter                                 svn_ra_serf__handler_t *handler,
834289180Speter                                 svn_boolean_t expect_207_only,
835289180Speter                                 apr_pool_t *result_pool,
836289180Speter                                 apr_pool_t *scratch_pool);
837251881Speter
838289180Speter/*
839289180Speter * Forwards response data to the server error parser
840289180Speter */
841289180Spetersvn_error_t *
842289180Spetersvn_ra_serf__handle_server_error(svn_ra_serf__server_error_t *server_error,
843289180Speter                                 svn_ra_serf__handler_t *handler,
844289180Speter                                 serf_request_t *request,
845289180Speter                                 serf_bucket_t *response,
846289180Speter                                 apr_status_t *serf_status,
847289180Speter                                 apr_pool_t *scratch_pool);
848289180Speter
849289180Speter/*
850289180Speter * Creates the svn_error_t * instance from the error recorded in
851289180Speter * HANDLER->server_error
852289180Speter */
853289180Spetersvn_error_t *
854289180Spetersvn_ra_serf__server_error_create(svn_ra_serf__handler_t *handler,
855289180Speter                                 apr_pool_t *scratch_pool);
856289180Speter
857251881Speter/* serf_response_handler_t implementation that completely discards
858251881Speter * the response.
859251881Speter *
860251881Speter * All temporary allocations will be made in @a pool.
861251881Speter */
862251881Speterapr_status_t
863251881Spetersvn_ra_serf__response_discard_handler(serf_request_t *request,
864251881Speter                                      serf_bucket_t *response,
865251881Speter                                      void *baton,
866251881Speter                                      apr_pool_t *pool);
867251881Speter
868251881Speter
869251881Speter/*
870251881Speter * Add the appropriate serf buckets to @a agg_bucket represented by
871251881Speter * the XML * @a tag and @a value.
872251881Speter *
873251881Speter * The bucket will be allocated from @a bkt_alloc.
874251881Speter */
875251881Spetervoid
876251881Spetersvn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket,
877251881Speter                             const char *tag,
878251881Speter                             const char *value,
879251881Speter                             serf_bucket_alloc_t *bkt_alloc);
880251881Speter
881251881Speter/*
882251881Speter * Add the appropriate serf buckets to AGG_BUCKET with standard XML header:
883251881Speter *  <?xml version="1.0" encoding="utf-8"?>
884251881Speter *
885251881Speter * The bucket will be allocated from BKT_ALLOC.
886251881Speter */
887251881Spetervoid
888251881Spetersvn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket,
889251881Speter                                    serf_bucket_alloc_t *bkt_alloc);
890251881Speter
891251881Speter/*
892251881Speter * Add the appropriate serf buckets to AGG_BUCKET representing the XML
893251881Speter * open tag with name TAG.
894251881Speter *
895251881Speter * Take the tag's attributes from varargs, a NULL-terminated list of
896251881Speter * alternating <tt>char *</tt> key and <tt>char *</tt> val.  Attribute
897251881Speter * will be ignored if it's value is NULL.
898251881Speter *
899251881Speter * NOTE: Callers are responsible for XML-escaping attribute values as
900251881Speter * necessary.
901251881Speter *
902251881Speter * The bucket will be allocated from BKT_ALLOC.
903251881Speter */
904251881Spetervoid
905251881Spetersvn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket,
906251881Speter                                  serf_bucket_alloc_t *bkt_alloc,
907251881Speter                                  const char *tag,
908289180Speter                                  ...) SVN_NEEDS_SENTINEL_NULL;
909251881Speter
910251881Speter/*
911251881Speter * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close
912251881Speter * with name TAG.
913251881Speter *
914251881Speter * The bucket will be allocated from BKT_ALLOC.
915251881Speter */
916251881Spetervoid
917251881Spetersvn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket,
918251881Speter                                   serf_bucket_alloc_t *bkt_alloc,
919251881Speter                                   const char *tag);
920251881Speter
921289180Speter/* Add the appropriate serf buckets to AGG_BUCKET representing the XML
922289180Speter * open tag with name TAG, and then immediately closes the tag using the />
923289180Speter * notation
924289180Speter */
925289180Spetervoid
926289180Spetersvn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket,
927289180Speter                                   serf_bucket_alloc_t *bkt_alloc,
928289180Speter                                   const char *tag,
929289180Speter                                   ...) SVN_NEEDS_SENTINEL_NULL;
930289180Speter
931251881Speter/*
932251881Speter * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped
933251881Speter * version of DATA.
934251881Speter *
935251881Speter * The bucket will be allocated from BKT_ALLOC.
936251881Speter */
937251881Spetervoid
938251881Spetersvn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket,
939251881Speter                                   serf_bucket_alloc_t *bkt_alloc,
940251881Speter                                   const char *data, apr_size_t len);
941251881Speter
942289180Speter
943289180Speter/** PROPFIND-related functions **/
944289180Speter
945289180Speter/* Removes all non regular properties from PROPS */
946251881Spetervoid
947289180Spetersvn_ra_serf__keep_only_regular_props(apr_hash_t *props,
948289180Speter                                     apr_pool_t *scratch_pool);
949251881Speter
950251881Speter
951289180Speter/* Callback used via svn_ra_serf__deliver_props2 */
952289180Spetertypedef svn_error_t *
953289180Speter(*svn_ra_serf__prop_func_t)(void *baton,
954289180Speter                            const char *path,
955289180Speter                            const char *ns,
956289180Speter                            const char *name,
957289180Speter                            const svn_string_t *value,
958289180Speter                            apr_pool_t *scratch_pool);
959251881Speter
960251881Speter/*
961289180Speter * Implementation of svn_ra_serf__prop_func_t that just delivers svn compatible
962289180Speter * properties  in the apr_hash_t * that is used as baton.
963251881Speter */
964251881Spetersvn_error_t *
965289180Spetersvn_ra_serf__deliver_svn_props(void *baton,
966289180Speter                               const char *path,
967289180Speter                               const char *ns,
968289180Speter                               const char *name,
969289180Speter                               const svn_string_t *value,
970289180Speter                               apr_pool_t *scratch_pool);
971251881Speter
972251881Speter/*
973289180Speter * This function will create a handler for a PROPFIND request, which will deliver
974289180Speter * properties to PROP_FUNC() with PROP_BATON for the properties listed in LOOKUP_PROPS
975289180Speter * at URL for DEPTH ("0","1","infinity").
976251881Speter */
977251881Spetersvn_error_t *
978289180Spetersvn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **handler,
979289180Speter                                     svn_ra_serf__session_t *session,
980289180Speter                                     const char *path,
981289180Speter                                     svn_revnum_t rev,
982289180Speter                                     const char *depth,
983289180Speter                                     const svn_ra_serf__dav_props_t *find_props,
984289180Speter                                     svn_ra_serf__prop_func_t prop_func,
985289180Speter                                     void *prop_func_baton,
986289180Speter                                     apr_pool_t *result_pool);
987251881Speter
988251881Speter
989289180Speter/* Using SESSION, fetch the properties specified by WHICH_PROPS using CONN
990251881Speter   for URL at REVISION. The resulting properties are placed into a 2-level
991251881Speter   hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which
992251881Speter   is allocated in RESULT_POOL.
993251881Speter
994251881Speter   If REVISION is SVN_INVALID_REVNUM, then the properties are fetched
995251881Speter   from HEAD for URL.
996251881Speter
997251881Speter   This function performs the request synchronously.
998251881Speter
999251881Speter   Temporary allocations are made in SCRATCH_POOL.  */
1000251881Spetersvn_error_t *
1001251881Spetersvn_ra_serf__fetch_node_props(apr_hash_t **results,
1002289180Speter                              svn_ra_serf__session_t *session,
1003251881Speter                              const char *url,
1004251881Speter                              svn_revnum_t revision,
1005251881Speter                              const svn_ra_serf__dav_props_t *which_props,
1006251881Speter                              apr_pool_t *result_pool,
1007251881Speter                              apr_pool_t *scratch_pool);
1008251881Speter
1009251881Speter
1010289180Speter/* Using SESSION, fetch a DAV: property from the resource identified by URL
1011251881Speter   within REVISION. The PROPNAME may be one of:
1012251881Speter
1013251881Speter     "checked-in"
1014251881Speter     "href"
1015251881Speter
1016251881Speter   The resulting value will be allocated in RESULT_POOL, and may be NULL
1017251881Speter   if the property does not exist (note: "href" always exists).
1018251881Speter
1019251881Speter   This function performs the request synchronously.
1020251881Speter
1021251881Speter   Temporary allocations are made in SCRATCH_POOL.  */
1022251881Spetersvn_error_t *
1023251881Spetersvn_ra_serf__fetch_dav_prop(const char **value,
1024289180Speter                            svn_ra_serf__session_t *session,
1025251881Speter                            const char *url,
1026251881Speter                            svn_revnum_t revision,
1027251881Speter                            const char *propname,
1028251881Speter                            apr_pool_t *result_pool,
1029251881Speter                            apr_pool_t *scratch_pool);
1030251881Speter
1031251881Speter/* Map a property name, as passed over the wire, into its corresponding
1032251881Speter   Subversion-internal name. The returned name will be a static value,
1033251881Speter   or allocated within RESULT_POOL.
1034251881Speter
1035251881Speter   If the property should be ignored (eg. some DAV properties), then NULL
1036251881Speter   will be returned.  */
1037251881Speterconst char *
1038251881Spetersvn_ra_serf__svnname_from_wirename(const char *ns,
1039251881Speter                                   const char *name,
1040251881Speter                                   apr_pool_t *result_pool);
1041251881Speter
1042251881Speter/** MERGE-related functions **/
1043251881Speter
1044298845Sdimvoid
1045298845Sdimsvn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
1046298845Sdim                                   const char *parent,
1047298845Sdim                                   serf_bucket_t *body,
1048298845Sdim                                   serf_bucket_alloc_t *alloc,
1049298845Sdim                                   apr_pool_t *pool);
1050298845Sdim
1051251881Speter/* Create an MERGE request aimed at the SESSION url, requesting the
1052251881Speter   merge of the resource identified by MERGE_RESOURCE_URL.
1053251881Speter   LOCK_TOKENS is a hash mapping paths to lock tokens owned by the
1054251881Speter   client.  If KEEP_LOCKS is set, instruct the server to not release
1055251881Speter   locks set on the paths included in this commit.  */
1056251881Spetersvn_error_t *
1057251881Spetersvn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
1058251881Speter                       svn_ra_serf__session_t *session,
1059251881Speter                       const char *merge_resource_url,
1060251881Speter                       apr_hash_t *lock_tokens,
1061251881Speter                       svn_boolean_t keep_locks,
1062251881Speter                       apr_pool_t *result_pool,
1063251881Speter                       apr_pool_t *scratch_pool);
1064251881Speter
1065251881Speter
1066251881Speter/** OPTIONS-related functions **/
1067251881Speter
1068253734Speter/* When running with a proxy, we may need to detect and correct for problems.
1069253734Speter   This probing function will send a simple OPTIONS request to detect problems
1070253734Speter   with the connection.  */
1071253734Spetersvn_error_t *
1072253734Spetersvn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
1073253734Speter                         apr_pool_t *scratch_pool);
1074253734Speter
1075253734Speter
1076251881Speter/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
1077251881Speter   current youngest revnum, returning it in *YOUNGEST.
1078251881Speter
1079251881Speter   (the revnum is headers of the OPTIONS response)
1080251881Speter
1081251881Speter   This function performs the request synchronously.
1082251881Speter
1083251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
1084251881Spetersvn_error_t *
1085251881Spetersvn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
1086289180Speter                                    svn_ra_serf__session_t *session,
1087251881Speter                                    apr_pool_t *scratch_pool);
1088251881Speter
1089251881Speter
1090251881Speter/* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the
1091251881Speter   activity collection set and return it in *ACTIVITY_URL, allocated
1092251881Speter   from RESULT_POOL.
1093251881Speter
1094251881Speter   (the activity-collection-set is in the body of the OPTIONS response)
1095251881Speter
1096251881Speter   This function performs the request synchronously.
1097251881Speter
1098251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
1099251881Spetersvn_error_t *
1100251881Spetersvn_ra_serf__v1_get_activity_collection(const char **activity_url,
1101289180Speter                                        svn_ra_serf__session_t *session,
1102251881Speter                                        apr_pool_t *result_pool,
1103251881Speter                                        apr_pool_t *scratch_pool);
1104251881Speter
1105251881Speter
1106251881Speter/* Set @a VCC_URL to the default VCC for our repository based on @a
1107251881Speter * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and
1108289180Speter * repository root URLs are cached in @a SESSION.
1109251881Speter *
1110289180Speter * All temporary allocations will be made in @a SCRATCH_POOL. */
1111251881Spetersvn_error_t *
1112251881Spetersvn_ra_serf__discover_vcc(const char **vcc_url,
1113251881Speter                          svn_ra_serf__session_t *session,
1114289180Speter                          apr_pool_t *scratch_pool);
1115251881Speter
1116251881Speter/* Set @a REPORT_TARGET to the URI of the resource at which generic
1117289180Speter * (path-agnostic) REPORTs should be aimed for @a SESSION.
1118251881Speter *
1119251881Speter * All temporary allocations will be made in @a POOL.
1120251881Speter */
1121251881Spetersvn_error_t *
1122251881Spetersvn_ra_serf__report_resource(const char **report_target,
1123251881Speter                             svn_ra_serf__session_t *session,
1124251881Speter                             apr_pool_t *pool);
1125251881Speter
1126251881Speter/* Set @a REL_PATH to a path (not URI-encoded) relative to the root of
1127251881Speter * the repository pointed to by @a SESSION, based on original path
1128251881Speter * (URI-encoded) @a ORIG_PATH.  Use @a CONN for any required network
1129251881Speter * communications if it is non-NULL; otherwise use the default
1130251881Speter * connection.  Use POOL for allocations.  */
1131251881Spetersvn_error_t *
1132251881Spetersvn_ra_serf__get_relative_path(const char **rel_path,
1133251881Speter                               const char *orig_path,
1134251881Speter                               svn_ra_serf__session_t *session,
1135251881Speter                               apr_pool_t *pool);
1136251881Speter
1137251881Speter
1138251881Speter/* Using the default connection in SESSION (conns[0]), get the youngest
1139251881Speter   revnum from the server, returning it in *YOUNGEST.
1140251881Speter
1141251881Speter   This function operates synchronously.
1142251881Speter
1143251881Speter   All temporary allocations are performed in SCRATCH_POOL.  */
1144251881Spetersvn_error_t *
1145251881Spetersvn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest,
1146251881Speter                                 svn_ra_serf__session_t *session,
1147251881Speter                                 apr_pool_t *scratch_pool);
1148251881Speter
1149251881Speter
1150251881Speter/* Generate a revision-stable URL.
1151251881Speter
1152251881Speter   The RA APIs all refer to user/public URLs that float along with the
1153251881Speter   youngest revision. In many cases, we do NOT want to work with that URL
1154251881Speter   since it can change from one moment to the next. Especially if we
1155251881Speter   attempt to operation against multiple floating URLs -- we could end up
1156251881Speter   referring to two separate revisions.
1157251881Speter
1158251881Speter   The DAV RA provider(s) solve this by generating a URL that is specific
1159251881Speter   to a revision by using a URL into a "baseline collection".
1160251881Speter
1161289180Speter   For a specified SESSION, generate a revision-stable URL for URL at
1162289180Speter   REVISION. If REVISION is    SVN_INVALID_REVNUM, then the stable URL will
1163289180Speter   refer to the youngest revision at the time this function was called.
1164251881Speter
1165251881Speter   If URL is NULL, then the session root will be used.
1166251881Speter
1167251881Speter   The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL.
1168251881Speter
1169251881Speter   If LATEST_REVNUM is not NULL, then the revision used will be placed into
1170251881Speter   *LATEST_REVNUM. That will be equal to youngest, or the given REVISION.
1171251881Speter
1172251881Speter   This function operates synchronously, if any communication to the server
1173251881Speter   is required. Communication is needed if REVISION is SVN_INVALID_REVNUM
1174251881Speter   (to get the current youngest revnum), or if the specified REVISION is not
1175251881Speter   (yet) in our cache of baseline collections.
1176251881Speter
1177251881Speter   All temporary allocations are performed in SCRATCH_POOL.  */
1178251881Spetersvn_error_t *
1179251881Spetersvn_ra_serf__get_stable_url(const char **stable_url,
1180251881Speter                            svn_revnum_t *latest_revnum,
1181251881Speter                            svn_ra_serf__session_t *session,
1182251881Speter                            const char *url,
1183251881Speter                            svn_revnum_t revision,
1184251881Speter                            apr_pool_t *result_pool,
1185251881Speter                            apr_pool_t *scratch_pool);
1186251881Speter
1187251881Speter
1188251881Speter/** RA functions **/
1189251881Speter
1190289180Speter/* Implements svn_ra__vtable_t.reparent(). */
1191289180Spetersvn_error_t *
1192289180Spetersvn_ra_serf__reparent(svn_ra_session_t *ra_session,
1193289180Speter                      const char *url,
1194289180Speter                      apr_pool_t *pool);
1195289180Speter
1196289180Speter/* Implements svn_ra__vtable_t.rev_prop(). */
1197289180Spetersvn_error_t *
1198289180Spetersvn_ra_serf__rev_prop(svn_ra_session_t *session,
1199289180Speter                      svn_revnum_t rev,
1200289180Speter                      const char *name,
1201289180Speter                      svn_string_t **value,
1202289180Speter                      apr_pool_t *pool);
1203289180Speter
1204251881Speter/* Implements svn_ra__vtable_t.get_log(). */
1205251881Spetersvn_error_t *
1206251881Spetersvn_ra_serf__get_log(svn_ra_session_t *session,
1207251881Speter                     const apr_array_header_t *paths,
1208251881Speter                     svn_revnum_t start,
1209251881Speter                     svn_revnum_t end,
1210251881Speter                     int limit,
1211251881Speter                     svn_boolean_t discover_changed_paths,
1212251881Speter                     svn_boolean_t strict_node_history,
1213251881Speter                     svn_boolean_t include_merged_revisions,
1214251881Speter                     const apr_array_header_t *revprops,
1215251881Speter                     svn_log_entry_receiver_t receiver,
1216251881Speter                     void *receiver_baton,
1217251881Speter                     apr_pool_t *pool);
1218251881Speter
1219289180Speter/* Implements svn_ra__vtable_t.check_path(). */
1220289180Spetersvn_error_t *
1221289180Spetersvn_ra_serf__check_path(svn_ra_session_t *ra_session,
1222289180Speter                        const char *rel_path,
1223289180Speter                        svn_revnum_t revision,
1224289180Speter                        svn_node_kind_t *kind,
1225289180Speter                        apr_pool_t *pool);
1226289180Speter
1227289180Speter/* Implements svn_ra__vtable_t.stat(). */
1228289180Spetersvn_error_t *
1229289180Spetersvn_ra_serf__stat(svn_ra_session_t *ra_session,
1230289180Speter                  const char *rel_path,
1231289180Speter                  svn_revnum_t revision,
1232289180Speter                  svn_dirent_t **dirent,
1233289180Speter                  apr_pool_t *pool);
1234289180Speter
1235251881Speter/* Implements svn_ra__vtable_t.get_locations(). */
1236251881Spetersvn_error_t *
1237251881Spetersvn_ra_serf__get_locations(svn_ra_session_t *session,
1238251881Speter                           apr_hash_t **locations,
1239251881Speter                           const char *path,
1240251881Speter                           svn_revnum_t peg_revision,
1241251881Speter                           const apr_array_header_t *location_revisions,
1242251881Speter                           apr_pool_t *pool);
1243251881Speter
1244251881Speter/* Implements svn_ra__vtable_t.get_location_segments(). */
1245251881Spetersvn_error_t *
1246251881Spetersvn_ra_serf__get_location_segments(svn_ra_session_t *session,
1247251881Speter                                   const char *path,
1248251881Speter                                   svn_revnum_t peg_revision,
1249251881Speter                                   svn_revnum_t start_rev,
1250251881Speter                                   svn_revnum_t end_rev,
1251251881Speter                                   svn_location_segment_receiver_t receiver,
1252251881Speter                                   void *receiver_baton,
1253251881Speter                                   apr_pool_t *pool);
1254251881Speter
1255251881Speter/* Implements svn_ra__vtable_t.do_diff(). */
1256251881Spetersvn_error_t *
1257251881Spetersvn_ra_serf__do_diff(svn_ra_session_t *session,
1258251881Speter                     const svn_ra_reporter3_t **reporter,
1259251881Speter                     void **report_baton,
1260251881Speter                     svn_revnum_t revision,
1261251881Speter                     const char *diff_target,
1262251881Speter                     svn_depth_t depth,
1263251881Speter                     svn_boolean_t ignore_ancestry,
1264251881Speter                     svn_boolean_t text_deltas,
1265251881Speter                     const char *versus_url,
1266251881Speter                     const svn_delta_editor_t *diff_editor,
1267251881Speter                     void *diff_baton,
1268251881Speter                     apr_pool_t *pool);
1269251881Speter
1270251881Speter/* Implements svn_ra__vtable_t.do_status(). */
1271251881Spetersvn_error_t *
1272251881Spetersvn_ra_serf__do_status(svn_ra_session_t *ra_session,
1273251881Speter                       const svn_ra_reporter3_t **reporter,
1274251881Speter                       void **report_baton,
1275251881Speter                       const char *status_target,
1276251881Speter                       svn_revnum_t revision,
1277251881Speter                       svn_depth_t depth,
1278251881Speter                       const svn_delta_editor_t *status_editor,
1279251881Speter                       void *status_baton,
1280251881Speter                       apr_pool_t *pool);
1281251881Speter
1282251881Speter/* Implements svn_ra__vtable_t.do_update(). */
1283251881Spetersvn_error_t *
1284251881Spetersvn_ra_serf__do_update(svn_ra_session_t *ra_session,
1285251881Speter                       const svn_ra_reporter3_t **reporter,
1286251881Speter                       void **report_baton,
1287251881Speter                       svn_revnum_t revision_to_update_to,
1288251881Speter                       const char *update_target,
1289251881Speter                       svn_depth_t depth,
1290251881Speter                       svn_boolean_t send_copyfrom_args,
1291251881Speter                       svn_boolean_t ignore_ancestry,
1292251881Speter                       const svn_delta_editor_t *update_editor,
1293251881Speter                       void *update_baton,
1294251881Speter                       apr_pool_t *result_pool,
1295251881Speter                       apr_pool_t *scratch_pool);
1296251881Speter
1297251881Speter/* Implements svn_ra__vtable_t.do_switch(). */
1298251881Spetersvn_error_t *
1299251881Spetersvn_ra_serf__do_switch(svn_ra_session_t *ra_session,
1300251881Speter                       const svn_ra_reporter3_t **reporter,
1301251881Speter                       void **report_baton,
1302251881Speter                       svn_revnum_t revision_to_switch_to,
1303251881Speter                       const char *switch_target,
1304251881Speter                       svn_depth_t depth,
1305251881Speter                       const char *switch_url,
1306251881Speter                       svn_boolean_t send_copyfrom_args,
1307251881Speter                       svn_boolean_t ignore_ancestry,
1308251881Speter                       const svn_delta_editor_t *switch_editor,
1309251881Speter                       void *switch_baton,
1310251881Speter                       apr_pool_t *result_pool,
1311251881Speter                       apr_pool_t *scratch_pool);
1312251881Speter
1313251881Speter/* Implements svn_ra__vtable_t.get_file_revs(). */
1314251881Spetersvn_error_t *
1315251881Spetersvn_ra_serf__get_file_revs(svn_ra_session_t *session,
1316251881Speter                           const char *path,
1317251881Speter                           svn_revnum_t start,
1318251881Speter                           svn_revnum_t end,
1319251881Speter                           svn_boolean_t include_merged_revisions,
1320251881Speter                           svn_file_rev_handler_t handler,
1321251881Speter                           void *handler_baton,
1322251881Speter                           apr_pool_t *pool);
1323251881Speter
1324251881Speter/* Implements svn_ra__vtable_t.get_dated_revision(). */
1325251881Spetersvn_error_t *
1326251881Spetersvn_ra_serf__get_dated_revision(svn_ra_session_t *session,
1327251881Speter                                svn_revnum_t *revision,
1328251881Speter                                apr_time_t tm,
1329251881Speter                                apr_pool_t *pool);
1330251881Speter
1331289180Speter/* Implements svn_ra__vtable_t.get_commit_editor().
1332289180Speter *
1333289180Speter * Note: Like other commit editors, the returned editor requires that the
1334289180Speter * @c copyfrom_path parameter passed to its @c add_file and @c add_directory
1335289180Speter * methods is a URL, not a relative path.
1336289180Speter */
1337251881Spetersvn_error_t *
1338251881Spetersvn_ra_serf__get_commit_editor(svn_ra_session_t *session,
1339251881Speter                               const svn_delta_editor_t **editor,
1340251881Speter                               void **edit_baton,
1341251881Speter                               apr_hash_t *revprop_table,
1342251881Speter                               svn_commit_callback2_t callback,
1343251881Speter                               void *callback_baton,
1344251881Speter                               apr_hash_t *lock_tokens,
1345251881Speter                               svn_boolean_t keep_locks,
1346251881Speter                               apr_pool_t *pool);
1347251881Speter
1348251881Speter/* Implements svn_ra__vtable_t.get_file(). */
1349251881Spetersvn_error_t *
1350251881Spetersvn_ra_serf__get_file(svn_ra_session_t *session,
1351251881Speter                      const char *path,
1352251881Speter                      svn_revnum_t revision,
1353251881Speter                      svn_stream_t *stream,
1354251881Speter                      svn_revnum_t *fetched_rev,
1355251881Speter                      apr_hash_t **props,
1356251881Speter                      apr_pool_t *pool);
1357251881Speter
1358289180Speter/* Implements svn_ra__vtable_t.get_dir(). */
1359289180Spetersvn_error_t *
1360289180Spetersvn_ra_serf__get_dir(svn_ra_session_t *ra_session,
1361289180Speter                     apr_hash_t **dirents,
1362289180Speter                     svn_revnum_t *fetched_rev,
1363289180Speter                     apr_hash_t **ret_props,
1364289180Speter                     const char *rel_path,
1365289180Speter                     svn_revnum_t revision,
1366289180Speter                     apr_uint32_t dirent_fields,
1367289180Speter                     apr_pool_t *result_pool);
1368289180Speter
1369251881Speter/* Implements svn_ra__vtable_t.change_rev_prop(). */
1370251881Spetersvn_error_t *
1371251881Spetersvn_ra_serf__change_rev_prop(svn_ra_session_t *session,
1372251881Speter                             svn_revnum_t rev,
1373251881Speter                             const char *name,
1374251881Speter                             const svn_string_t *const *old_value_p,
1375251881Speter                             const svn_string_t *value,
1376251881Speter                             apr_pool_t *pool);
1377251881Speter
1378251881Speter/* Implements svn_ra__vtable_t.replay(). */
1379251881Spetersvn_error_t *
1380251881Spetersvn_ra_serf__replay(svn_ra_session_t *ra_session,
1381251881Speter                    svn_revnum_t revision,
1382251881Speter                    svn_revnum_t low_water_mark,
1383251881Speter                    svn_boolean_t text_deltas,
1384251881Speter                    const svn_delta_editor_t *editor,
1385251881Speter                    void *edit_baton,
1386251881Speter                    apr_pool_t *pool);
1387251881Speter
1388251881Speter/* Implements svn_ra__vtable_t.replay_range(). */
1389251881Spetersvn_error_t *
1390251881Spetersvn_ra_serf__replay_range(svn_ra_session_t *ra_session,
1391251881Speter                          svn_revnum_t start_revision,
1392251881Speter                          svn_revnum_t end_revision,
1393251881Speter                          svn_revnum_t low_water_mark,
1394251881Speter                          svn_boolean_t send_deltas,
1395251881Speter                          svn_ra_replay_revstart_callback_t revstart_func,
1396251881Speter                          svn_ra_replay_revfinish_callback_t revfinish_func,
1397251881Speter                          void *replay_baton,
1398251881Speter                          apr_pool_t *pool);
1399251881Speter
1400251881Speter/* Implements svn_ra__vtable_t.lock(). */
1401251881Spetersvn_error_t *
1402251881Spetersvn_ra_serf__lock(svn_ra_session_t *ra_session,
1403251881Speter                  apr_hash_t *path_revs,
1404251881Speter                  const char *comment,
1405251881Speter                  svn_boolean_t force,
1406251881Speter                  svn_ra_lock_callback_t lock_func,
1407251881Speter                  void *lock_baton,
1408251881Speter                  apr_pool_t *pool);
1409251881Speter
1410251881Speter/* Implements svn_ra__vtable_t.unlock(). */
1411251881Spetersvn_error_t *
1412251881Spetersvn_ra_serf__unlock(svn_ra_session_t *ra_session,
1413251881Speter                    apr_hash_t *path_tokens,
1414251881Speter                    svn_boolean_t force,
1415251881Speter                    svn_ra_lock_callback_t lock_func,
1416251881Speter                    void *lock_baton,
1417251881Speter                    apr_pool_t *pool);
1418251881Speter
1419251881Speter/* Implements svn_ra__vtable_t.get_lock(). */
1420251881Spetersvn_error_t *
1421251881Spetersvn_ra_serf__get_lock(svn_ra_session_t *ra_session,
1422251881Speter                      svn_lock_t **lock,
1423251881Speter                      const char *path,
1424251881Speter                      apr_pool_t *pool);
1425251881Speter
1426251881Speter/* Implements svn_ra__vtable_t.get_locks(). */
1427251881Spetersvn_error_t *
1428251881Spetersvn_ra_serf__get_locks(svn_ra_session_t *ra_session,
1429251881Speter                       apr_hash_t **locks,
1430251881Speter                       const char *path,
1431251881Speter                       svn_depth_t depth,
1432251881Speter                       apr_pool_t *pool);
1433251881Speter
1434362181Sdim/* Implements svn_ra__vtable_t.list(). */
1435362181Sdimsvn_error_t *
1436362181Sdimsvn_ra_serf__list(svn_ra_session_t *ra_session,
1437362181Sdim                  const char *path,
1438362181Sdim                  svn_revnum_t revision,
1439362181Sdim                  const apr_array_header_t *patterns,
1440362181Sdim                  svn_depth_t depth,
1441362181Sdim                  apr_uint32_t dirent_fields,
1442362181Sdim                  svn_ra_dirent_receiver_t receiver,
1443362181Sdim                  void *receiver_baton,
1444362181Sdim                  apr_pool_t *scratch_pool);
1445362181Sdim
1446251881Speter/* Request a mergeinfo-report from the URL attached to SESSION,
1447251881Speter   and fill in the MERGEINFO hash with the results.
1448251881Speter
1449251881Speter   Implements svn_ra__vtable_t.get_mergeinfo().
1450251881Speter */
1451251881Spetersvn_error_t *
1452251881Spetersvn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
1453251881Speter                           apr_hash_t **mergeinfo,
1454251881Speter                           const apr_array_header_t *paths,
1455251881Speter                           svn_revnum_t revision,
1456251881Speter                           svn_mergeinfo_inheritance_t inherit,
1457251881Speter                           svn_boolean_t include_descendants,
1458251881Speter                           apr_pool_t *pool);
1459251881Speter
1460251881Speter/* Exchange capabilities with the server, by sending an OPTIONS
1461251881Speter * request announcing the client's capabilities, and by filling
1462251881Speter * SERF_SESS->capabilities with the server's capabilities as read from
1463251881Speter * the response headers.  Use POOL only for temporary allocation.
1464251881Speter *
1465251881Speter * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to
1466251881Speter * report a server-dictated redirect or relocation (HTTP 301 or 302
1467251881Speter * error codes), setting *CORRECTED_URL to the value of the corrected
1468251881Speter * repository URL.  Otherwise, such responses from the server will
1469251881Speter * generate an error.  (In either case, no capabilities are exchanged
1470251881Speter * if there is, in fact, such a response from the server.)
1471251881Speter */
1472251881Spetersvn_error_t *
1473251881Spetersvn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess,
1474251881Speter                                   const char **corrected_url,
1475362181Sdim                                   const char **redirect_url,
1476289180Speter                                   apr_pool_t *result_pool,
1477289180Speter                                   apr_pool_t *scratch_pool);
1478251881Speter
1479251881Speter/* Implements svn_ra__vtable_t.has_capability(). */
1480251881Spetersvn_error_t *
1481251881Spetersvn_ra_serf__has_capability(svn_ra_session_t *ra_session,
1482251881Speter                            svn_boolean_t *has,
1483251881Speter                            const char *capability,
1484251881Speter                            apr_pool_t *pool);
1485251881Speter
1486251881Speter/* Implements svn_ra__vtable_t.get_deleted_rev(). */
1487251881Spetersvn_error_t *
1488251881Spetersvn_ra_serf__get_deleted_rev(svn_ra_session_t *session,
1489251881Speter                             const char *path,
1490251881Speter                             svn_revnum_t peg_revision,
1491251881Speter                             svn_revnum_t end_revision,
1492251881Speter                             svn_revnum_t *revision_deleted,
1493251881Speter                             apr_pool_t *pool);
1494251881Speter
1495251881Speter/* Implements the get_inherited_props RA layer function. */
1496251881Spetersvn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session,
1497251881Speter                                               apr_array_header_t **iprops,
1498251881Speter                                               const char *path,
1499251881Speter                                               svn_revnum_t revision,
1500251881Speter                                               apr_pool_t *result_pool,
1501251881Speter                                               apr_pool_t *scratch_pool);
1502251881Speter
1503251881Speter/* Implements svn_ra__vtable_t.get_repos_root(). */
1504251881Spetersvn_error_t *
1505251881Spetersvn_ra_serf__get_repos_root(svn_ra_session_t *ra_session,
1506251881Speter                            const char **url,
1507251881Speter                            apr_pool_t *pool);
1508251881Speter
1509251881Speter/* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */
1510251881Spetersvn_error_t *
1511251881Spetersvn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
1512251881Speter                                    svn_delta_shim_callbacks_t *callbacks);
1513251881Speter
1514251881Speter/*** Authentication handler declarations ***/
1515251881Speter
1516251881Speter/**
1517251881Speter * Callback function that loads the credentials for Basic and Digest
1518251881Speter * authentications, both for server and proxy authentication.
1519251881Speter */
1520251881Speterapr_status_t
1521251881Spetersvn_ra_serf__credentials_callback(char **username, char **password,
1522251881Speter                                  serf_request_t *request, void *baton,
1523251881Speter                                  int code, const char *authn_type,
1524251881Speter                                  const char *realm,
1525251881Speter                                  apr_pool_t *pool);
1526251881Speter
1527251881Speter
1528251881Speter/*** General utility functions ***/
1529251881Speter
1530251881Speter/**
1531251881Speter * Convert an HTTP STATUS_CODE resulting from a WebDAV request against
1532251881Speter * PATH to the relevant error code.  Use the response-supplied LOCATION
1533251881Speter * where it necessary.
1534289180Speter *
1535289180Speter * Returns SVN_NO_ERROR if sline doesn't specify an error condition
1536251881Speter */
1537251881Spetersvn_error_t *
1538253734Spetersvn_ra_serf__error_on_status(serf_status_line sline,
1539251881Speter                             const char *path,
1540251881Speter                             const char *location);
1541251881Speter
1542289180Speter/**
1543289180Speter * Convert an unexpected HTTP STATUS_CODE from a request to the relevant error
1544289180Speter * code. Unlike svn_ra_serf__error_on_status() this function creates an error
1545289180Speter * for any result
1546289180Speter */
1547289180Spetersvn_error_t *
1548289180Spetersvn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler);
1549289180Speter
1550362181Sdim/* Make sure handler is no longer scheduled on its connection. Resetting
1551362181Sdim   the connection if necessary */
1552362181Sdimvoid
1553362181Sdimsvn_ra_serf__unschedule_handler(svn_ra_serf__handler_t *handler);
1554289180Speter
1555362181Sdim
1556251881Speter/* ###? */
1557251881Spetersvn_error_t *
1558251881Spetersvn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf,
1559251881Speter                                serf_bucket_t *bkt,
1560251881Speter                                apr_pool_t *result_pool,
1561251881Speter                                apr_pool_t *scratch_pool);
1562251881Speter
1563251881Speter/* ###? */
1564251881Speterserf_bucket_t *
1565251881Spetersvn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf,
1566251881Speter                              serf_bucket_alloc_t *allocator,
1567251881Speter                              apr_pool_t *result_pool,
1568251881Speter                              apr_pool_t *scratch_pool);
1569251881Speter
1570251881Speter/** Wrap STATUS from an serf function. If STATUS is not serf error code,
1571251881Speter  * this is equivalent to svn_error_wrap_apr().
1572251881Speter */
1573251881Spetersvn_error_t *
1574251881Spetersvn_ra_serf__wrap_err(apr_status_t status,
1575251881Speter                      const char *fmt,
1576251881Speter                      ...);
1577251881Speter
1578289180Speter/* Create a bucket that just returns DATA (with length LEN) and then returns
1579289180Speter   the APR_EAGAIN status */
1580289180Speterserf_bucket_t *
1581289180Spetersvn_ra_serf__create_bucket_with_eagain(const char *data,
1582289180Speter                                       apr_size_t len,
1583289180Speter                                       serf_bucket_alloc_t *allocator);
1584251881Speter
1585298845Sdim/* Parse a given URL_STR, fill in all supplied fields of URI
1586298845Sdim * structure.
1587298845Sdim *
1588298845Sdim * This function is a compatibility wrapper around apr_uri_parse().
1589298845Sdim * Different apr-util versions set apr_uri_t.path to either NULL or ""
1590298845Sdim * for root paths, and serf expects to see "/". This function always
1591298845Sdim * sets URI.path to "/" for these paths. */
1592298845Sdimsvn_error_t *
1593298845Sdimsvn_ra_serf__uri_parse(apr_uri_t *uri,
1594298845Sdim                       const char *url_str,
1595298845Sdim                       apr_pool_t *result_pool);
1596289180Speter
1597362181Sdim/* Setup the "Accept-Encoding" header value for requests that expect
1598362181Sdim   svndiff-encoded deltas, depending on the SESSION state. */
1599362181Sdimvoid
1600362181Sdimsvn_ra_serf__setup_svndiff_accept_encoding(serf_bucket_t *headers,
1601362181Sdim                                           svn_ra_serf__session_t *session);
1602289180Speter
1603362181Sdimsvn_boolean_t
1604362181Sdimsvn_ra_serf__is_low_latency_connection(svn_ra_serf__session_t *session);
1605362181Sdim
1606362181Sdim/* Return an APR array of svn_ra_serf__dav_props_t containing the
1607362181Sdim * properties (names and namespaces) corresponding to the flegs set
1608362181Sdim * in DIRENT_FIELDS.  If SESSION does not support deadprops, only
1609362181Sdim * the generic "DAV:allprop" will be returned.  Allocate the result
1610362181Sdim * in RESULT_POOL. */
1611362181Sdimapr_array_header_t *
1612362181Sdimsvn_ra_serf__get_dirent_props(apr_uint32_t dirent_fields,
1613362181Sdim                              svn_ra_serf__session_t *session,
1614362181Sdim                              apr_pool_t *result_pool);
1615362181Sdim
1616362181Sdim/* Default limit for in-memory size of a request body. */
1617362181Sdim#define SVN_RA_SERF__REQUEST_BODY_IN_MEM_SIZE 256 * 1024
1618362181Sdim
1619362181Sdim/* An opaque structure used to prepare a request body. */
1620362181Sdimtypedef struct svn_ra_serf__request_body_t svn_ra_serf__request_body_t;
1621362181Sdim
1622362181Sdim/* Constructor for svn_ra_serf__request_body_t.  Creates a new writable
1623362181Sdim   buffer for the request body.  Request bodies under IN_MEMORY_SIZE
1624362181Sdim   bytes will be held in memory, otherwise, the body content will be
1625362181Sdim   spilled to a temporary file. */
1626362181Sdimsvn_ra_serf__request_body_t *
1627362181Sdimsvn_ra_serf__request_body_create(apr_size_t in_memory_size,
1628362181Sdim                                 apr_pool_t *result_pool);
1629362181Sdim
1630362181Sdim/* Get the writable stream associated with BODY. */
1631362181Sdimsvn_stream_t *
1632362181Sdimsvn_ra_serf__request_body_get_stream(svn_ra_serf__request_body_t *body);
1633362181Sdim
1634362181Sdim/* Get a svn_ra_serf__request_body_delegate_t and baton for BODY. */
1635362181Sdimvoid
1636362181Sdimsvn_ra_serf__request_body_get_delegate(svn_ra_serf__request_body_delegate_t *del,
1637362181Sdim                                       void **baton,
1638362181Sdim                                       svn_ra_serf__request_body_t *body);
1639362181Sdim
1640362181Sdim/* Release intermediate resources associated with BODY.  These resources
1641362181Sdim   (such as open file handles) will be automatically released when the
1642362181Sdim   pool used to construct BODY is cleared or destroyed, but this optional
1643362181Sdim   function allows doing that explicitly. */
1644362181Sdimsvn_error_t *
1645362181Sdimsvn_ra_serf__request_body_cleanup(svn_ra_serf__request_body_t *body,
1646362181Sdim                                  apr_pool_t *scratch_pool);
1647362181Sdim
1648362181Sdim/* Callback used in svn_ra_serf__create_stream_bucket().  ERR will be
1649362181Sdim   will be cleared and becomes invalid after the callback returns,
1650362181Sdim   use svn_error_dup() to preserve it. */
1651362181Sdimtypedef void
1652362181Sdim(*svn_ra_serf__stream_bucket_errfunc_t)(void *baton, svn_error_t *err);
1653362181Sdim
1654362181Sdim/* Create a bucket that wraps a generic readable STREAM.  This function
1655362181Sdim   takes ownership of the passed-in stream, and will close it. */
1656362181Sdimserf_bucket_t *
1657362181Sdimsvn_ra_serf__create_stream_bucket(svn_stream_t *stream,
1658362181Sdim                                  serf_bucket_alloc_t *allocator,
1659362181Sdim                                  svn_ra_serf__stream_bucket_errfunc_t errfunc,
1660362181Sdim                                  void *errfunc_baton);
1661362181Sdim
1662251881Speter#if defined(SVN_DEBUG)
1663251881Speter/* Wrapper macros to collect file and line information */
1664251881Speter#define svn_ra_serf__wrap_err \
1665251881Speter  (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err))
1666251881Speter
1667251881Speter#endif
1668251881Speter
1669251881Speter#ifdef __cplusplus
1670251881Speter}
1671251881Speter#endif /* __cplusplus */
1672251881Speter
1673251881Speter#endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */
1674