ra_serf.h revision 298845
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/** Wait duration (in microseconds) used in calls to serf_context_run() */
58251881Speter#define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000
59251881Speter
60251881Speter
61251881Speter
62251881Speter/* Forward declarations. */
63251881Spetertypedef struct svn_ra_serf__session_t svn_ra_serf__session_t;
64251881Speter
65251881Speter/* A serf connection and optionally associated SSL context.  */
66251881Spetertypedef struct svn_ra_serf__connection_t {
67251881Speter  /* Our connection to a server. */
68251881Speter  serf_connection_t *conn;
69251881Speter
70251881Speter  /* Bucket allocator for this connection. */
71251881Speter  serf_bucket_alloc_t *bkt_alloc;
72251881Speter
73251881Speter  /* Collected cert failures in chain.  */
74251881Speter  int server_cert_failures;
75251881Speter
76251881Speter  /* What was the last HTTP status code we got on this connection? */
77251881Speter  int last_status_code;
78251881Speter
79251881Speter  /* Optional SSL context for this connection. */
80251881Speter  serf_ssl_context_t *ssl_context;
81251881Speter  svn_auth_iterstate_t *ssl_client_auth_state;
82251881Speter  svn_auth_iterstate_t *ssl_client_pw_auth_state;
83251881Speter
84251881Speter  svn_ra_serf__session_t *session;
85251881Speter
86251881Speter} svn_ra_serf__connection_t;
87251881Speter
88251881Speter/** Maximum value we'll allow for the http-max-connections config option.
89251881Speter *
90251881Speter * Note: minimum 2 connections are required for ra_serf to function
91251881Speter * correctly!
92251881Speter */
93251881Speter#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8
94251881Speter
95251881Speter/*
96251881Speter * The master serf RA session.
97251881Speter *
98251881Speter * This is stored in the ra session ->priv field.
99289180Speter *
100289180Speter * ### Check ra_serf_dup_session when adding fields.
101251881Speter */
102251881Speterstruct svn_ra_serf__session_t {
103251881Speter  /* Pool for allocations during this session */
104251881Speter  apr_pool_t *pool;
105289180Speter  apr_hash_t *config; /* For duplicating */
106251881Speter
107251881Speter  /* The current context */
108251881Speter  serf_context_t *context;
109251881Speter
110251881Speter  /* The maximum number of connections we'll use for parallelized
111251881Speter     fetch operations (updates, etc.) */
112251881Speter  apr_int64_t max_connections;
113251881Speter
114251881Speter  /* Are we using ssl */
115251881Speter  svn_boolean_t using_ssl;
116251881Speter
117251881Speter  /* Should we ask for compressed responses? */
118251881Speter  svn_boolean_t using_compression;
119251881Speter
120251881Speter  /* The user agent string */
121251881Speter  const char *useragent;
122251881Speter
123251881Speter  /* The current connection */
124251881Speter  svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT];
125251881Speter  int num_conns;
126251881Speter  int cur_conn;
127251881Speter
128251881Speter  /* The URL that was passed into _open() */
129251881Speter  apr_uri_t session_url;
130251881Speter  const char *session_url_str;
131251881Speter
132251881Speter  /* The actual discovered root; may be NULL until we know it. */
133251881Speter  apr_uri_t repos_root;
134251881Speter  const char *repos_root_str;
135251881Speter
136251881Speter  /* The server is not Apache/mod_dav_svn (directly) and only supports
137251881Speter     HTTP/1.0. Thus, we cannot send chunked requests.  */
138251881Speter  svn_boolean_t http10;
139251881Speter
140253734Speter  /* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */
141253734Speter  svn_boolean_t using_chunked_requests;
142253734Speter
143253734Speter  /* Do we need to detect whether the connection supports chunked requests?
144253734Speter     i.e. is there a (reverse) proxy that does not support them?  */
145253734Speter  svn_boolean_t detect_chunking;
146253734Speter
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;
157289180Speter  svn_auth_baton_t *auth_baton;
158251881Speter
159251881Speter  /* Callback function to send progress info to the client */
160251881Speter  svn_ra_progress_notify_func_t progress_func;
161251881Speter  void *progress_baton;
162251881Speter
163251881Speter  /* Callback function to handle cancellation */
164251881Speter  svn_cancel_func_t cancel_func;
165251881Speter  void *cancel_baton;
166251881Speter
167251881Speter  /* Ev2 shim callbacks */
168251881Speter  svn_delta_shim_callbacks_t *shim_callbacks;
169251881Speter
170251881Speter  /* Error that we've received but not yet returned upstream. */
171251881Speter  svn_error_t *pending_error;
172251881Speter
173251881Speter  /* List of authn types supported by the client.*/
174251881Speter  int authn_types;
175251881Speter
176251881Speter  /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values.
177251881Speter     If a capability is not yet discovered, it is absent from the table.
178251881Speter     The table itself is allocated in the svn_ra_serf__session_t's pool;
179251881Speter     keys and values must have at least that lifetime.  Most likely
180251881Speter     the keys and values are constants anyway (and sufficiently
181251881Speter     well-informed internal code may just compare against those
182251881Speter     constants' addresses, therefore). */
183251881Speter  apr_hash_t *capabilities;
184251881Speter
185251881Speter  /* Activity collection URL.  (Cached from the initial OPTIONS
186251881Speter     request when run against HTTPv1 servers.)  */
187251881Speter  const char *activity_collection_url;
188251881Speter
189251881Speter  /* Are we using a proxy? */
190253734Speter  svn_boolean_t using_proxy;
191251881Speter
192251881Speter  const char *proxy_username;
193251881Speter  const char *proxy_password;
194251881Speter  int proxy_auth_attempts;
195251881Speter
196251881Speter  /* SSL server certificates */
197251881Speter  svn_boolean_t trust_default_ca;
198251881Speter  const char *ssl_authorities;
199251881Speter
200251881Speter  /* Repository UUID */
201251881Speter  const char *uuid;
202251881Speter
203251881Speter  /* Connection timeout value */
204251881Speter  apr_interval_time_t timeout;
205251881Speter
206251881Speter  /* HTTPv1 flags */
207251881Speter  svn_tristate_t supports_deadprop_count;
208251881Speter
209251881Speter  /*** HTTP v2 protocol stuff. ***
210251881Speter   *
211251881Speter   * We assume that if mod_dav_svn sends one of the special v2 OPTIONs
212251881Speter   * response headers, it has sent all of them.  Specifically, we'll
213251881Speter   * be looking at the presence of the "me resource" as a flag that
214251881Speter   * the server supports v2 of our HTTP protocol.
215251881Speter   */
216251881Speter
217251881Speter  /* The "me resource".  Typically used as a target for REPORTs that
218251881Speter     are path-agnostic.  If we have this, we can speak HTTP v2 to the
219251881Speter     server.  */
220251881Speter  const char *me_resource;
221251881Speter
222251881Speter  /* Opaque URL "stubs".  If the OPTIONS response returns these, then
223251881Speter     we know we're using HTTP protocol v2. */
224251881Speter  const char *rev_stub;         /* for accessing revisions (i.e. revprops) */
225251881Speter  const char *rev_root_stub;    /* for accessing REV/PATH pairs */
226251881Speter  const char *txn_stub;         /* for accessing transactions (i.e. txnprops) */
227251881Speter  const char *txn_root_stub;    /* for accessing TXN/PATH pairs */
228251881Speter  const char *vtxn_stub;        /* for accessing transactions (i.e. txnprops) */
229251881Speter  const char *vtxn_root_stub;   /* for accessing TXN/PATH pairs */
230251881Speter
231251881Speter  /* Hash mapping const char * server-supported POST types to
232251881Speter     disinteresting-but-non-null values. */
233251881Speter  apr_hash_t *supported_posts;
234251881Speter
235251881Speter  /*** End HTTP v2 stuff ***/
236251881Speter
237251881Speter  svn_ra_serf__blncache_t *blncache;
238251881Speter
239251881Speter  /* Trisate flag that indicates user preference for using bulk updates
240251881Speter     (svn_tristate_true) with all the properties and content in the
241251881Speter     update-report response. If svn_tristate_false, request a skelta
242251881Speter     update-report with inlined properties. If svn_tristate_unknown then use
243251881Speter     server preference. */
244251881Speter  svn_tristate_t bulk_updates;
245251881Speter
246251881Speter  /* Indicates if the server wants bulk update requests (Prefer) or only
247251881Speter     accepts skelta requests (Off). If this value is On both options are
248251881Speter     allowed. */
249251881Speter  const char *server_allows_bulk;
250251881Speter
251251881Speter  /* Indicates if the server supports sending inlined props in update editor
252251881Speter   * in skelta mode (send-all == 'false'). */
253251881Speter  svn_boolean_t supports_inline_props;
254251881Speter
255251881Speter  /* Indicates whether the server supports issuing replay REPORTs
256251881Speter     against rev resources (children of `rev_stub', elsestruct). */
257251881Speter  svn_boolean_t supports_rev_rsrc_replay;
258251881Speter};
259251881Speter
260251881Speter#define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL)
261251881Speter
262251881Speter/*
263251881Speter * Structure which represents a DAV element with a NAMESPACE and NAME.
264251881Speter */
265251881Spetertypedef struct svn_ra_serf__dav_props_t {
266251881Speter  /* Element namespace */
267289180Speter  const char *xmlns;
268251881Speter  /* Element name */
269251881Speter  const char *name;
270251881Speter} svn_ra_serf__dav_props_t;
271251881Speter
272251881Speter/** DAV property sets **/
273251881Speter
274251881Speterstatic const svn_ra_serf__dav_props_t base_props[] =
275251881Speter{
276251881Speter  { "DAV:", "version-controlled-configuration" },
277251881Speter  { "DAV:", "resourcetype" },
278251881Speter  { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },
279251881Speter  { SVN_DAV_PROP_NS_DAV, "repository-uuid" },
280251881Speter  { NULL }
281251881Speter};
282251881Speter
283251881Speterstatic const svn_ra_serf__dav_props_t checked_in_props[] =
284251881Speter{
285251881Speter  { "DAV:", "checked-in" },
286251881Speter  { NULL }
287251881Speter};
288251881Speter
289251881Speterstatic const svn_ra_serf__dav_props_t baseline_props[] =
290251881Speter{
291251881Speter  { "DAV:", "baseline-collection" },
292251881Speter  { "DAV:", SVN_DAV__VERSION_NAME },
293251881Speter  { NULL }
294251881Speter};
295251881Speter
296251881Speterstatic const svn_ra_serf__dav_props_t all_props[] =
297251881Speter{
298251881Speter  { "DAV:", "allprop" },
299251881Speter  { NULL }
300251881Speter};
301251881Speter
302251881Speterstatic const svn_ra_serf__dav_props_t check_path_props[] =
303251881Speter{
304251881Speter  { "DAV:", "resourcetype" },
305251881Speter  { NULL }
306251881Speter};
307251881Speter
308251881Speterstatic const svn_ra_serf__dav_props_t type_and_checksum_props[] =
309251881Speter{
310251881Speter  { "DAV:", "resourcetype" },
311251881Speter  { SVN_DAV_PROP_NS_DAV, "sha1-checksum" },
312251881Speter  { NULL }
313251881Speter};
314251881Speter
315251881Speter/* WC props compatibility with ra_neon. */
316251881Speter#define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
317251881Speter
318251881Speter/** Serf utility functions **/
319251881Speter
320251881Speterapr_status_t
321251881Spetersvn_ra_serf__conn_setup(apr_socket_t *sock,
322251881Speter                        serf_bucket_t **read_bkt,
323251881Speter                        serf_bucket_t **write_bkt,
324251881Speter                        void *baton,
325251881Speter                        apr_pool_t *pool);
326251881Speter
327251881Spetervoid
328251881Spetersvn_ra_serf__conn_closed(serf_connection_t *conn,
329251881Speter                         void *closed_baton,
330251881Speter                         apr_status_t why,
331251881Speter                         apr_pool_t *pool);
332251881Speter
333251881Speter
334251881Speter/* Helper function to provide SSL client certificates.
335251881Speter *
336251881Speter * NOTE: This function sets the session's 'pending_error' member when
337251881Speter *       returning an non-success status.
338251881Speter */
339251881Speterapr_status_t
340251881Spetersvn_ra_serf__handle_client_cert(void *data,
341251881Speter                                const char **cert_path);
342251881Speter
343251881Speter/* Helper function to provide SSL client certificate passwords.
344251881Speter *
345251881Speter * NOTE: This function sets the session's 'pending_error' member when
346251881Speter *       returning an non-success status.
347251881Speter */
348251881Speterapr_status_t
349251881Spetersvn_ra_serf__handle_client_cert_pw(void *data,
350251881Speter                                   const char *cert_path,
351251881Speter                                   const char **password);
352251881Speter
353251881Speter
354251881Speter/*
355251881Speter * This function will run the serf context in SESS until *DONE is TRUE.
356251881Speter */
357251881Spetersvn_error_t *
358251881Spetersvn_ra_serf__context_run_wait(svn_boolean_t *done,
359251881Speter                              svn_ra_serf__session_t *sess,
360251881Speter                              apr_pool_t *scratch_pool);
361251881Speter
362289180Speter/* Run the context once. Manage waittime_left to handle timing out when
363289180Speter   nothing happens over the session->timout.
364289180Speter */
365289180Spetersvn_error_t *
366289180Spetersvn_ra_serf__context_run(svn_ra_serf__session_t *sess,
367289180Speter                         apr_interval_time_t *waittime_left,
368289180Speter                         apr_pool_t *scratch_pool);
369289180Speter
370289180Speter
371289180Speter
372251881Speter/* Callback for response handlers */
373251881Spetertypedef svn_error_t *
374251881Speter(*svn_ra_serf__response_handler_t)(serf_request_t *request,
375251881Speter                                   serf_bucket_t *response,
376251881Speter                                   void *handler_baton,
377251881Speter                                   apr_pool_t *scratch_pool);
378251881Speter
379289180Speter/* Callback when the request is done */
380289180Spetertypedef svn_error_t *
381289180Speter(*svn_ra_serf__response_done_delegate_t)(serf_request_t *request,
382289180Speter                                         void *done_baton,
383289180Speter                                         apr_pool_t *scratch_pool);
384289180Speter
385251881Speter/* Callback for when a request body is needed. */
386251881Spetertypedef svn_error_t *
387251881Speter(*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
388251881Speter                                        void *baton,
389251881Speter                                        serf_bucket_alloc_t *alloc,
390289180Speter                                        apr_pool_t *request_pool,
391289180Speter                                        apr_pool_t *scratch_pool);
392251881Speter
393251881Speter/* Callback for when request headers are needed. */
394251881Spetertypedef svn_error_t *
395251881Speter(*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
396251881Speter                                          void *baton,
397289180Speter                                          apr_pool_t *request_pool,
398289180Speter                                          apr_pool_t *scratch_pool);
399251881Speter
400251881Speter/* Callback for when a response has an error. */
401251881Spetertypedef svn_error_t *
402251881Speter(*svn_ra_serf__response_error_t)(serf_request_t *request,
403251881Speter                                 serf_bucket_t *response,
404251881Speter                                 int status_code,
405251881Speter                                 void *baton);
406251881Speter
407251881Speter/* ### we should reorder the types in this file.  */
408251881Spetertypedef struct svn_ra_serf__server_error_t svn_ra_serf__server_error_t;
409251881Speter
410251881Speter/*
411251881Speter * Structure that can be passed to our default handler to guide the
412251881Speter * execution of the request through its lifecycle.
413289180Speter *
414289180Speter * Use svn_ra_serf__create_handler() to create instances of this struct.
415251881Speter */
416251881Spetertypedef struct svn_ra_serf__handler_t {
417251881Speter  /* The HTTP method string of the request */
418251881Speter  const char *method;
419251881Speter
420251881Speter  /* The resource to the execute the method on. */
421251881Speter  const char *path;
422251881Speter
423251881Speter  /* The content-type of the request body. */
424251881Speter  const char *body_type;
425251881Speter
426251881Speter  /* If TRUE then default Accept-Encoding request header is not configured for
427251881Speter     request. If FALSE then 'gzip' accept encoding will be used if compression
428251881Speter     enabled. */
429251881Speter  svn_boolean_t custom_accept_encoding;
430251881Speter
431289180Speter  /* If TRUE then default DAV: capabilities request headers is not configured
432289180Speter     for request. */
433289180Speter  svn_boolean_t no_dav_headers;
434289180Speter
435289180Speter  /* If TRUE doesn't fail requests on HTTP error statuses like 405, 408, 500
436289180Speter     (see util.c response_done()) */
437289180Speter  svn_boolean_t no_fail_on_http_failure_status;
438289180Speter
439289180Speter  /* If TRUE doesn't fail requests on HTTP redirect statuses like 301, 307 */
440289180Speter  svn_boolean_t no_fail_on_http_redirect_status;
441289180Speter
442251881Speter  /* Has the request/response been completed?  */
443251881Speter  svn_boolean_t done;
444289180Speter  svn_boolean_t scheduled; /* Is the request scheduled in a context */
445251881Speter
446251881Speter  /* If we captured an error from the server, then this will be non-NULL.
447251881Speter     It will be allocated from HANDLER_POOL.  */
448251881Speter  svn_ra_serf__server_error_t *server_error;
449251881Speter
450251881Speter  /* The handler and baton pair for our handler. */
451251881Speter  svn_ra_serf__response_handler_t response_handler;
452251881Speter  void *response_baton;
453251881Speter
454251881Speter  /* When REPONSE_HANDLER is invoked, the following fields will be set
455251881Speter     based on the response header. HANDLER_POOL must be non-NULL for these
456251881Speter     values to be filled in. SLINE.REASON and LOCATION will be allocated
457251881Speter     within HANDLER_POOL.  */
458251881Speter  serf_status_line sline;  /* The parsed Status-Line  */
459251881Speter  const char *location;  /* The Location: header, if any  */
460251881Speter
461289180Speter  /* This function and baton pair allows handling the completion of request.
462289180Speter   *
463289180Speter   * The default handler is responsible for the HTTP failure processing.
464289180Speter   *
465289180Speter   * If no_fail_on_http_failure_status is not TRUE, then the callback will
466289180Speter   * return recorded server errors or if there is none and the http status
467289180Speter   * specifies an error returns an error for that.
468289180Speter   *
469289180Speter   * The default baton is the handler itself.
470289180Speter   */
471289180Speter  svn_ra_serf__response_done_delegate_t done_delegate;
472289180Speter  void *done_delegate_baton;
473289180Speter
474251881Speter  /* The handler and baton pair to be executed when a non-recoverable error
475251881Speter   * is detected.  If it is NULL in the presence of an error, an abort() may
476251881Speter   * be triggered.
477251881Speter   */
478251881Speter  svn_ra_serf__response_error_t response_error;
479251881Speter  void *response_error_baton;
480251881Speter
481251881Speter  /* This function and baton pair allows for custom request headers to
482251881Speter   * be set.
483251881Speter   *
484251881Speter   * It will be executed after the request has been set up but before it is
485251881Speter   * delivered.
486251881Speter   */
487251881Speter  svn_ra_serf__request_header_delegate_t header_delegate;
488251881Speter  void *header_delegate_baton;
489251881Speter
490251881Speter  /* This function and baton pair allows a body to be created right before
491251881Speter   * delivery.
492251881Speter   *
493251881Speter   * It will be executed after the request has been set up but before it is
494251881Speter   * delivered.
495251881Speter   *
496251881Speter   * May be NULL if there is no body to send.
497251881Speter   *
498251881Speter   */
499251881Speter  svn_ra_serf__request_body_delegate_t body_delegate;
500251881Speter  void *body_delegate_baton;
501251881Speter
502251881Speter  /* The connection and session to be used for this request. */
503251881Speter  svn_ra_serf__connection_t *conn;
504251881Speter  svn_ra_serf__session_t *session;
505251881Speter
506251881Speter  /* Internal flag to indicate we've parsed the headers.  */
507251881Speter  svn_boolean_t reading_body;
508251881Speter
509251881Speter  /* When this flag will be set, the core handler will discard any unread
510251881Speter     portion of the response body. The registered response handler will
511251881Speter     no longer be called.  */
512251881Speter  svn_boolean_t discard_body;
513251881Speter
514251881Speter  /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL,
515251881Speter     then the requestor does not care about SLINE and LOCATION.  */
516251881Speter  apr_pool_t *handler_pool;
517251881Speter} svn_ra_serf__handler_t;
518251881Speter
519251881Speter
520251881Speter/* Run one request and process the response.
521251881Speter
522251881Speter   Similar to context_run_wait(), but this creates the request for HANDLER
523251881Speter   and then waits for it to complete.
524251881Speter
525251881Speter   WARNING: context_run_wait() does NOT create a request, whereas this
526251881Speter   function DOES. Avoid a double-create.  */
527251881Spetersvn_error_t *
528251881Spetersvn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
529251881Speter                             apr_pool_t *scratch_pool);
530251881Speter
531251881Speter
532251881Speter/*
533251881Speter * Helper function to queue a request in the @a handler's connection.
534251881Speter */
535251881Spetervoid svn_ra_serf__request_create(svn_ra_serf__handler_t *handler);
536251881Speter
537251881Speter/* v2 of the XML parsing functions  */
538251881Speter
539251881Speter/* The XML parsing context.  */
540251881Spetertypedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t;
541251881Speter
542251881Speter
543251881Speter/* An opaque structure for the XML parse element/state.  */
544251881Spetertypedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t;
545251881Speter
546251881Speter/* Called just after the parser moves into ENTERED_STATE. The tag causing
547251881Speter   the transition is passed in TAG.
548251881Speter
549251881Speter   This callback is applied to a parsing context by using the
550251881Speter   svn_ra_serf__xml_context_customize() function.
551251881Speter
552251881Speter   NOTE: this callback, when set, will be invoked on *every* transition.
553251881Speter   The callback must examine ENTERED_STATE to determine if any action
554251881Speter   must be taken. The original state is not provided, but must be derived
555251881Speter   from ENTERED_STATE and/or the TAG causing the transition (if needed).  */
556251881Spetertypedef svn_error_t *
557251881Speter(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
558251881Speter                             void *baton,
559251881Speter                             int entered_state,
560251881Speter                             const svn_ra_serf__dav_props_t *tag,
561251881Speter                             apr_pool_t *scratch_pool);
562251881Speter
563251881Speter
564251881Speter/* Called just before the parser leaves LEAVING_STATE.
565251881Speter
566251881Speter   If cdata collection was enabled for this state, then CDATA will be
567251881Speter   non-NULL and contain the collected cdata.
568251881Speter
569251881Speter   If attribute collection was enabled for this state, then ATTRS will
570251881Speter   contain the attributes collected for this element only, along with
571251881Speter   any values stored via svn_ra_serf__xml_note().
572251881Speter
573251881Speter   Use svn_ra_serf__xml_gather_since() to gather up data from outer states.
574251881Speter
575251881Speter   ATTRS is char* -> char*.
576251881Speter
577251881Speter   Temporary allocations may be made in SCRATCH_POOL.  */
578251881Spetertypedef svn_error_t *
579251881Speter(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes,
580251881Speter                             void *baton,
581251881Speter                             int leaving_state,
582251881Speter                             const svn_string_t *cdata,
583251881Speter                             apr_hash_t *attrs,
584251881Speter                             apr_pool_t *scratch_pool);
585251881Speter
586251881Speter
587251881Speter/* Called for all states that are not using the builtin cdata collection.
588251881Speter   This callback is (only) appropriate for unbounded-size cdata content.
589251881Speter
590251881Speter   CURRENT_STATE may be used to decide what to do with the data.
591251881Speter
592251881Speter   Temporary allocations may be made in SCRATCH_POOL.  */
593251881Spetertypedef svn_error_t *
594251881Speter(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
595251881Speter                            void *baton,
596251881Speter                            int current_state,
597251881Speter                            const char *data,
598251881Speter                            apr_size_t len,
599251881Speter                            apr_pool_t *scratch_pool);
600251881Speter
601251881Speter
602289180Speter/* Magic state value for the initial state in a svn_ra_serf__xml_transition_t
603289180Speter   table */
604289180Speter#define XML_STATE_INITIAL 0
605289180Speter
606251881Speter/* State transition table.
607251881Speter
608251881Speter   When the XML Context is constructed, it is in state 0. User states are
609251881Speter   positive integers.
610251881Speter
611251881Speter   In a list of transitions, use { 0 } to indicate the end. Specifically,
612251881Speter   the code looks for NS == NULL.
613251881Speter
614289180Speter   The initial state for each transition table is XML_STATE_INITIAL.
615289180Speter
616251881Speter   ### more docco
617251881Speter*/
618251881Spetertypedef struct svn_ra_serf__xml_transition_t {
619251881Speter  /* This transition applies when in this state  */
620251881Speter  int from_state;
621251881Speter
622251881Speter  /* And when this tag is observed  */
623251881Speter  const char *ns;
624251881Speter  const char *name;
625251881Speter
626251881Speter  /* Moving to this state  */
627251881Speter  int to_state;
628251881Speter
629251881Speter  /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
630251881Speter     be TRUE in order to capture this cdata.  */
631251881Speter  svn_boolean_t collect_cdata;
632251881Speter
633251881Speter  /* Which attributes of NAME should be collected? Terminate with NULL.
634251881Speter     Maximum of 10 attributes may be collected. Note that attribute
635251881Speter     namespaces are ignored at this time.
636251881Speter
637251881Speter     Attribute names beginning with "?" are optional. Other names must
638251881Speter     exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised.  */
639251881Speter  const char *collect_attrs[11];
640251881Speter
641251881Speter  /* When NAME is closed, should the callback be invoked?  */
642251881Speter  svn_boolean_t custom_close;
643251881Speter
644251881Speter} svn_ra_serf__xml_transition_t;
645251881Speter
646289180Speter/* Constructor for svn_ra_serf__handler_t. Initializes a new handler
647289180Speter   with default settings for SESSION. */
648289180Spetersvn_ra_serf__handler_t *
649289180Spetersvn_ra_serf__create_handler(svn_ra_serf__session_t *session,
650289180Speter                            apr_pool_t *result_pool);
651251881Speter
652251881Speter/* Construct an XML parsing context, based on the TTABLE transition table.
653251881Speter   As content is parsed, the CLOSED_CB callback will be invoked according
654251881Speter   to the definition in the table.
655251881Speter
656251881Speter   If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
657251881Speter   event. The callback will need to use the ENTERED_STATE and TAG parameters
658251881Speter   to decide what it would like to do.
659251881Speter
660251881Speter   If CDATA_CB is not NULL, then it will be called for all cdata that is
661251881Speter   not be automatically collected (based on the transition table record's
662251881Speter   COLLECT_CDATA flag). It will be called in every state, so the callback
663251881Speter   must examine the CURRENT_STATE parameter to decide what to do.
664251881Speter
665251881Speter   The same BATON value will be passed to all three callbacks.
666251881Speter
667251881Speter   The context will be created within RESULT_POOL.  */
668251881Spetersvn_ra_serf__xml_context_t *
669251881Spetersvn_ra_serf__xml_context_create(
670251881Speter  const svn_ra_serf__xml_transition_t *ttable,
671251881Speter  svn_ra_serf__xml_opened_t opened_cb,
672251881Speter  svn_ra_serf__xml_closed_t closed_cb,
673251881Speter  svn_ra_serf__xml_cdata_t cdata_cb,
674251881Speter  void *baton,
675251881Speter  apr_pool_t *result_pool);
676251881Speter
677289180Speter/* Verifies if the parsing completed successfully and destroys
678289180Speter   all subpools. */
679289180Spetersvn_error_t *
680289180Spetersvn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx);
681251881Speter
682251881Speter/* Construct a handler with the response function/baton set up to parse
683251881Speter   a response body using the given XML context. The handler and its
684251881Speter   internal structures are allocated in RESULT_POOL.
685251881Speter
686289180Speter   As part of the handling the http status value is compared to 200, or
687289180Speter   if EXPECTED_STATUS is not NULL to all the values in EXPECTED_STATUS.
688289180Speter   EXPECTED_STATUS is expected to be a list of integers ending with a 0
689289180Speter   that lives at least as long as RESULT_POOL. If the status doesn't
690289180Speter   match the request has failed and will be parsed as en error response.
691289180Speter
692251881Speter   This also initializes HANDLER_POOL to the given RESULT_POOL.  */
693251881Spetersvn_ra_serf__handler_t *
694289180Spetersvn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session,
695289180Speter                                  svn_ra_serf__xml_context_t *xmlctx,
696289180Speter                                  const int *expected_status,
697251881Speter                                  apr_pool_t *result_pool);
698251881Speter
699251881Speter
700251881Speter/* Allocated within XES->STATE_POOL. Changes are not allowd (callers
701251881Speter   should make a deep copy if they need to make changes).
702251881Speter
703251881Speter   The resulting hash maps char* names to char* values.  */
704251881Speterapr_hash_t *
705251881Spetersvn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
706251881Speter                              int stop_state);
707251881Speter
708251881Speter
709251881Speter/* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
710251881Speter   The name and value will be copied into the target state's pool.
711251881Speter
712251881Speter   These values will be available to the CLOSED_CB for the target state,
713251881Speter   or part of the gathered state via xml_gather_since().
714251881Speter
715251881Speter   Typically, this function is used by a child state's close callback,
716251881Speter   or within an opening callback to store additional data.
717251881Speter
718251881Speter   Note: if the state is not found, then a programmer error has occurred,
719251881Speter   so the function will invoke SVN_ERR_MALFUNCTION().  */
720251881Spetervoid
721251881Spetersvn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
722251881Speter                      int state,
723251881Speter                      const char *name,
724251881Speter                      const char *value);
725251881Speter
726251881Speter
727251881Speter/* Returns XES->STATE_POOL for allocating structures that should live
728251881Speter   as long as the state identified by XES.
729251881Speter
730251881Speter   Note: a state pool is created upon demand, so only use this function
731251881Speter   when memory is required for a given state.  */
732251881Speterapr_pool_t *
733251881Spetersvn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
734251881Speter
735251881Speter/*
736251881Speter * Parses a server-side error message into a local Subversion error.
737251881Speter */
738251881Speterstruct svn_ra_serf__server_error_t {
739289180Speter  apr_pool_t *pool;
740251881Speter
741289180Speter  /* XML parser and namespace used to parse the remote response */
742289180Speter  svn_ra_serf__xml_context_t *xmlctx;
743251881Speter
744289180Speter  svn_ra_serf__response_handler_t response_handler;
745289180Speter  void *response_baton;
746251881Speter
747289180Speter  /* The partial errors to construct the final error from */
748289180Speter  apr_array_header_t *items;
749251881Speter
750289180Speter  /* The hooked handler */
751289180Speter  svn_ra_serf__handler_t *handler;
752251881Speter};
753251881Speter
754251881Speter/*
755251881Speter * Handler that discards the entire @a response body associated with a
756251881Speter * @a request.  Implements svn_ra_serf__response_handler_t.
757251881Speter *
758251881Speter * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an
759251881Speter * error is detected, it will be populated for later detection.
760251881Speter *
761251881Speter * All temporary allocations will be made in a @a pool.
762251881Speter */
763251881Spetersvn_error_t *
764251881Spetersvn_ra_serf__handle_discard_body(serf_request_t *request,
765251881Speter                                 serf_bucket_t *response,
766251881Speter                                 void *baton,
767251881Speter                                 apr_pool_t *pool);
768251881Speter
769251881Speter
770251881Speter/*
771251881Speter * Handler that retrieves the embedded XML multistatus response from the
772251881Speter * the @a RESPONSE body associated with a @a REQUEST.
773251881Speter *
774251881Speter * Implements svn_ra_serf__response_handler_t.
775251881Speter *
776251881Speter * The @a BATON should be of type svn_ra_serf__handler_t. When the request
777251881Speter * is complete, the handler's DONE flag will be set to TRUE.
778251881Speter *
779251881Speter * All temporary allocations will be made in a @a scratch_pool.
780251881Speter */
781251881Spetersvn_error_t *
782251881Spetersvn_ra_serf__handle_multistatus_only(serf_request_t *request,
783251881Speter                                     serf_bucket_t *response,
784251881Speter                                     void *baton,
785251881Speter                                     apr_pool_t *scratch_pool);
786251881Speter
787251881Speter
788251881Speter/* Handler that expects an empty body.
789251881Speter
790251881Speter   If a body IS present, and it is text/xml, then it will be parsed for
791251881Speter   a server-side error.
792251881Speter
793251881Speter   BATON should be the svn_ra_serf__handler_t running REQUEST.
794251881Speter
795251881Speter   Status line information will be in HANDLER->SLINE.
796251881Speter
797251881Speter   Any parsed errors will be left in HANDLER->SERVER_ERROR. That member
798251881Speter   may be NULL if no body was present, or a problem occurred trying to
799251881Speter   parse the body.
800251881Speter
801251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
802251881Spetersvn_error_t *
803251881Spetersvn_ra_serf__expect_empty_body(serf_request_t *request,
804251881Speter                               serf_bucket_t *response,
805251881Speter                               void *baton,
806251881Speter                               apr_pool_t *scratch_pool);
807251881Speter
808251881Speter
809251881Speter/*
810289180Speter * This function sets up error parsing for an existing request
811251881Speter */
812251881Spetersvn_error_t *
813289180Spetersvn_ra_serf__setup_error_parsing(svn_ra_serf__server_error_t **server_err,
814289180Speter                                 svn_ra_serf__handler_t *handler,
815289180Speter                                 svn_boolean_t expect_207_only,
816289180Speter                                 apr_pool_t *result_pool,
817289180Speter                                 apr_pool_t *scratch_pool);
818251881Speter
819289180Speter/*
820289180Speter * Forwards response data to the server error parser
821289180Speter */
822289180Spetersvn_error_t *
823289180Spetersvn_ra_serf__handle_server_error(svn_ra_serf__server_error_t *server_error,
824289180Speter                                 svn_ra_serf__handler_t *handler,
825289180Speter                                 serf_request_t *request,
826289180Speter                                 serf_bucket_t *response,
827289180Speter                                 apr_status_t *serf_status,
828289180Speter                                 apr_pool_t *scratch_pool);
829289180Speter
830289180Speter/*
831289180Speter * Creates the svn_error_t * instance from the error recorded in
832289180Speter * HANDLER->server_error
833289180Speter */
834289180Spetersvn_error_t *
835289180Spetersvn_ra_serf__server_error_create(svn_ra_serf__handler_t *handler,
836289180Speter                                 apr_pool_t *scratch_pool);
837289180Speter
838251881Speter/* serf_response_handler_t implementation that completely discards
839251881Speter * the response.
840251881Speter *
841251881Speter * All temporary allocations will be made in @a pool.
842251881Speter */
843251881Speterapr_status_t
844251881Spetersvn_ra_serf__response_discard_handler(serf_request_t *request,
845251881Speter                                      serf_bucket_t *response,
846251881Speter                                      void *baton,
847251881Speter                                      apr_pool_t *pool);
848251881Speter
849251881Speter
850251881Speter/*
851251881Speter * Add the appropriate serf buckets to @a agg_bucket represented by
852251881Speter * the XML * @a tag and @a value.
853251881Speter *
854251881Speter * The bucket will be allocated from @a bkt_alloc.
855251881Speter */
856251881Spetervoid
857251881Spetersvn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket,
858251881Speter                             const char *tag,
859251881Speter                             const char *value,
860251881Speter                             serf_bucket_alloc_t *bkt_alloc);
861251881Speter
862251881Speter/*
863251881Speter * Add the appropriate serf buckets to AGG_BUCKET with standard XML header:
864251881Speter *  <?xml version="1.0" encoding="utf-8"?>
865251881Speter *
866251881Speter * The bucket will be allocated from BKT_ALLOC.
867251881Speter */
868251881Spetervoid
869251881Spetersvn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket,
870251881Speter                                    serf_bucket_alloc_t *bkt_alloc);
871251881Speter
872251881Speter/*
873251881Speter * Add the appropriate serf buckets to AGG_BUCKET representing the XML
874251881Speter * open tag with name TAG.
875251881Speter *
876251881Speter * Take the tag's attributes from varargs, a NULL-terminated list of
877251881Speter * alternating <tt>char *</tt> key and <tt>char *</tt> val.  Attribute
878251881Speter * will be ignored if it's value is NULL.
879251881Speter *
880251881Speter * NOTE: Callers are responsible for XML-escaping attribute values as
881251881Speter * necessary.
882251881Speter *
883251881Speter * The bucket will be allocated from BKT_ALLOC.
884251881Speter */
885251881Spetervoid
886251881Spetersvn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket,
887251881Speter                                  serf_bucket_alloc_t *bkt_alloc,
888251881Speter                                  const char *tag,
889289180Speter                                  ...) SVN_NEEDS_SENTINEL_NULL;
890251881Speter
891251881Speter/*
892251881Speter * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close
893251881Speter * with name TAG.
894251881Speter *
895251881Speter * The bucket will be allocated from BKT_ALLOC.
896251881Speter */
897251881Spetervoid
898251881Spetersvn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket,
899251881Speter                                   serf_bucket_alloc_t *bkt_alloc,
900251881Speter                                   const char *tag);
901251881Speter
902289180Speter/* Add the appropriate serf buckets to AGG_BUCKET representing the XML
903289180Speter * open tag with name TAG, and then immediately closes the tag using the />
904289180Speter * notation
905289180Speter */
906289180Spetervoid
907289180Spetersvn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket,
908289180Speter                                   serf_bucket_alloc_t *bkt_alloc,
909289180Speter                                   const char *tag,
910289180Speter                                   ...) SVN_NEEDS_SENTINEL_NULL;
911289180Speter
912251881Speter/*
913251881Speter * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped
914251881Speter * version of DATA.
915251881Speter *
916251881Speter * The bucket will be allocated from BKT_ALLOC.
917251881Speter */
918251881Spetervoid
919251881Spetersvn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket,
920251881Speter                                   serf_bucket_alloc_t *bkt_alloc,
921251881Speter                                   const char *data, apr_size_t len);
922251881Speter
923289180Speter
924289180Speter/** PROPFIND-related functions **/
925289180Speter
926289180Speter/* Removes all non regular properties from PROPS */
927251881Spetervoid
928289180Spetersvn_ra_serf__keep_only_regular_props(apr_hash_t *props,
929289180Speter                                     apr_pool_t *scratch_pool);
930251881Speter
931251881Speter
932289180Speter/* Callback used via svn_ra_serf__deliver_props2 */
933289180Spetertypedef svn_error_t *
934289180Speter(*svn_ra_serf__prop_func_t)(void *baton,
935289180Speter                            const char *path,
936289180Speter                            const char *ns,
937289180Speter                            const char *name,
938289180Speter                            const svn_string_t *value,
939289180Speter                            apr_pool_t *scratch_pool);
940251881Speter
941251881Speter/*
942289180Speter * Implementation of svn_ra_serf__prop_func_t that just delivers svn compatible
943289180Speter * properties  in the apr_hash_t * that is used as baton.
944251881Speter */
945251881Spetersvn_error_t *
946289180Spetersvn_ra_serf__deliver_svn_props(void *baton,
947289180Speter                               const char *path,
948289180Speter                               const char *ns,
949289180Speter                               const char *name,
950289180Speter                               const svn_string_t *value,
951289180Speter                               apr_pool_t *scratch_pool);
952251881Speter
953251881Speter/*
954289180Speter * This function will create a handler for a PROPFIND request, which will deliver
955289180Speter * properties to PROP_FUNC() with PROP_BATON for the properties listed in LOOKUP_PROPS
956289180Speter * at URL for DEPTH ("0","1","infinity").
957251881Speter */
958251881Spetersvn_error_t *
959289180Spetersvn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **handler,
960289180Speter                                     svn_ra_serf__session_t *session,
961289180Speter                                     const char *path,
962289180Speter                                     svn_revnum_t rev,
963289180Speter                                     const char *depth,
964289180Speter                                     const svn_ra_serf__dav_props_t *find_props,
965289180Speter                                     svn_ra_serf__prop_func_t prop_func,
966289180Speter                                     void *prop_func_baton,
967289180Speter                                     apr_pool_t *result_pool);
968251881Speter
969251881Speter
970289180Speter/* Using SESSION, fetch the properties specified by WHICH_PROPS using CONN
971251881Speter   for URL at REVISION. The resulting properties are placed into a 2-level
972251881Speter   hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which
973251881Speter   is allocated in RESULT_POOL.
974251881Speter
975251881Speter   If REVISION is SVN_INVALID_REVNUM, then the properties are fetched
976251881Speter   from HEAD for URL.
977251881Speter
978251881Speter   This function performs the request synchronously.
979251881Speter
980251881Speter   Temporary allocations are made in SCRATCH_POOL.  */
981251881Spetersvn_error_t *
982251881Spetersvn_ra_serf__fetch_node_props(apr_hash_t **results,
983289180Speter                              svn_ra_serf__session_t *session,
984251881Speter                              const char *url,
985251881Speter                              svn_revnum_t revision,
986251881Speter                              const svn_ra_serf__dav_props_t *which_props,
987251881Speter                              apr_pool_t *result_pool,
988251881Speter                              apr_pool_t *scratch_pool);
989251881Speter
990251881Speter
991289180Speter/* Using SESSION, fetch a DAV: property from the resource identified by URL
992251881Speter   within REVISION. The PROPNAME may be one of:
993251881Speter
994251881Speter     "checked-in"
995251881Speter     "href"
996251881Speter
997251881Speter   The resulting value will be allocated in RESULT_POOL, and may be NULL
998251881Speter   if the property does not exist (note: "href" always exists).
999251881Speter
1000251881Speter   This function performs the request synchronously.
1001251881Speter
1002251881Speter   Temporary allocations are made in SCRATCH_POOL.  */
1003251881Spetersvn_error_t *
1004251881Spetersvn_ra_serf__fetch_dav_prop(const char **value,
1005289180Speter                            svn_ra_serf__session_t *session,
1006251881Speter                            const char *url,
1007251881Speter                            svn_revnum_t revision,
1008251881Speter                            const char *propname,
1009251881Speter                            apr_pool_t *result_pool,
1010251881Speter                            apr_pool_t *scratch_pool);
1011251881Speter
1012251881Speter/* Map a property name, as passed over the wire, into its corresponding
1013251881Speter   Subversion-internal name. The returned name will be a static value,
1014251881Speter   or allocated within RESULT_POOL.
1015251881Speter
1016251881Speter   If the property should be ignored (eg. some DAV properties), then NULL
1017251881Speter   will be returned.  */
1018251881Speterconst char *
1019251881Spetersvn_ra_serf__svnname_from_wirename(const char *ns,
1020251881Speter                                   const char *name,
1021251881Speter                                   apr_pool_t *result_pool);
1022251881Speter
1023251881Speter/** MERGE-related functions **/
1024251881Speter
1025298845Sdimvoid
1026298845Sdimsvn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
1027298845Sdim                                   const char *parent,
1028298845Sdim                                   serf_bucket_t *body,
1029298845Sdim                                   serf_bucket_alloc_t *alloc,
1030298845Sdim                                   apr_pool_t *pool);
1031298845Sdim
1032251881Speter/* Create an MERGE request aimed at the SESSION url, requesting the
1033251881Speter   merge of the resource identified by MERGE_RESOURCE_URL.
1034251881Speter   LOCK_TOKENS is a hash mapping paths to lock tokens owned by the
1035251881Speter   client.  If KEEP_LOCKS is set, instruct the server to not release
1036251881Speter   locks set on the paths included in this commit.  */
1037251881Spetersvn_error_t *
1038251881Spetersvn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
1039251881Speter                       svn_ra_serf__session_t *session,
1040251881Speter                       const char *merge_resource_url,
1041251881Speter                       apr_hash_t *lock_tokens,
1042251881Speter                       svn_boolean_t keep_locks,
1043251881Speter                       apr_pool_t *result_pool,
1044251881Speter                       apr_pool_t *scratch_pool);
1045251881Speter
1046251881Speter
1047251881Speter/** OPTIONS-related functions **/
1048251881Speter
1049253734Speter/* When running with a proxy, we may need to detect and correct for problems.
1050253734Speter   This probing function will send a simple OPTIONS request to detect problems
1051253734Speter   with the connection.  */
1052253734Spetersvn_error_t *
1053253734Spetersvn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
1054253734Speter                         apr_pool_t *scratch_pool);
1055253734Speter
1056253734Speter
1057251881Speter/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
1058251881Speter   current youngest revnum, returning it in *YOUNGEST.
1059251881Speter
1060251881Speter   (the revnum is headers of the OPTIONS response)
1061251881Speter
1062251881Speter   This function performs the request synchronously.
1063251881Speter
1064251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
1065251881Spetersvn_error_t *
1066251881Spetersvn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
1067289180Speter                                    svn_ra_serf__session_t *session,
1068251881Speter                                    apr_pool_t *scratch_pool);
1069251881Speter
1070251881Speter
1071251881Speter/* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the
1072251881Speter   activity collection set and return it in *ACTIVITY_URL, allocated
1073251881Speter   from RESULT_POOL.
1074251881Speter
1075251881Speter   (the activity-collection-set is in the body of the OPTIONS response)
1076251881Speter
1077251881Speter   This function performs the request synchronously.
1078251881Speter
1079251881Speter   All temporary allocations will be made in SCRATCH_POOL.  */
1080251881Spetersvn_error_t *
1081251881Spetersvn_ra_serf__v1_get_activity_collection(const char **activity_url,
1082289180Speter                                        svn_ra_serf__session_t *session,
1083251881Speter                                        apr_pool_t *result_pool,
1084251881Speter                                        apr_pool_t *scratch_pool);
1085251881Speter
1086251881Speter
1087251881Speter/* Set @a VCC_URL to the default VCC for our repository based on @a
1088251881Speter * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and
1089289180Speter * repository root URLs are cached in @a SESSION.
1090251881Speter *
1091289180Speter * All temporary allocations will be made in @a SCRATCH_POOL. */
1092251881Spetersvn_error_t *
1093251881Spetersvn_ra_serf__discover_vcc(const char **vcc_url,
1094251881Speter                          svn_ra_serf__session_t *session,
1095289180Speter                          apr_pool_t *scratch_pool);
1096251881Speter
1097251881Speter/* Set @a REPORT_TARGET to the URI of the resource at which generic
1098289180Speter * (path-agnostic) REPORTs should be aimed for @a SESSION.
1099251881Speter *
1100251881Speter * All temporary allocations will be made in @a POOL.
1101251881Speter */
1102251881Spetersvn_error_t *
1103251881Spetersvn_ra_serf__report_resource(const char **report_target,
1104251881Speter                             svn_ra_serf__session_t *session,
1105251881Speter                             apr_pool_t *pool);
1106251881Speter
1107251881Speter/* Set @a REL_PATH to a path (not URI-encoded) relative to the root of
1108251881Speter * the repository pointed to by @a SESSION, based on original path
1109251881Speter * (URI-encoded) @a ORIG_PATH.  Use @a CONN for any required network
1110251881Speter * communications if it is non-NULL; otherwise use the default
1111251881Speter * connection.  Use POOL for allocations.  */
1112251881Spetersvn_error_t *
1113251881Spetersvn_ra_serf__get_relative_path(const char **rel_path,
1114251881Speter                               const char *orig_path,
1115251881Speter                               svn_ra_serf__session_t *session,
1116251881Speter                               apr_pool_t *pool);
1117251881Speter
1118251881Speter
1119251881Speter/* Using the default connection in SESSION (conns[0]), get the youngest
1120251881Speter   revnum from the server, returning it in *YOUNGEST.
1121251881Speter
1122251881Speter   This function operates synchronously.
1123251881Speter
1124251881Speter   All temporary allocations are performed in SCRATCH_POOL.  */
1125251881Spetersvn_error_t *
1126251881Spetersvn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest,
1127251881Speter                                 svn_ra_serf__session_t *session,
1128251881Speter                                 apr_pool_t *scratch_pool);
1129251881Speter
1130251881Speter
1131251881Speter/* Generate a revision-stable URL.
1132251881Speter
1133251881Speter   The RA APIs all refer to user/public URLs that float along with the
1134251881Speter   youngest revision. In many cases, we do NOT want to work with that URL
1135251881Speter   since it can change from one moment to the next. Especially if we
1136251881Speter   attempt to operation against multiple floating URLs -- we could end up
1137251881Speter   referring to two separate revisions.
1138251881Speter
1139251881Speter   The DAV RA provider(s) solve this by generating a URL that is specific
1140251881Speter   to a revision by using a URL into a "baseline collection".
1141251881Speter
1142289180Speter   For a specified SESSION, generate a revision-stable URL for URL at
1143289180Speter   REVISION. If REVISION is    SVN_INVALID_REVNUM, then the stable URL will
1144289180Speter   refer to the youngest revision at the time this function was called.
1145251881Speter
1146251881Speter   If URL is NULL, then the session root will be used.
1147251881Speter
1148251881Speter   The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL.
1149251881Speter
1150251881Speter   If LATEST_REVNUM is not NULL, then the revision used will be placed into
1151251881Speter   *LATEST_REVNUM. That will be equal to youngest, or the given REVISION.
1152251881Speter
1153251881Speter   This function operates synchronously, if any communication to the server
1154251881Speter   is required. Communication is needed if REVISION is SVN_INVALID_REVNUM
1155251881Speter   (to get the current youngest revnum), or if the specified REVISION is not
1156251881Speter   (yet) in our cache of baseline collections.
1157251881Speter
1158251881Speter   All temporary allocations are performed in SCRATCH_POOL.  */
1159251881Spetersvn_error_t *
1160251881Spetersvn_ra_serf__get_stable_url(const char **stable_url,
1161251881Speter                            svn_revnum_t *latest_revnum,
1162251881Speter                            svn_ra_serf__session_t *session,
1163251881Speter                            const char *url,
1164251881Speter                            svn_revnum_t revision,
1165251881Speter                            apr_pool_t *result_pool,
1166251881Speter                            apr_pool_t *scratch_pool);
1167251881Speter
1168251881Speter
1169251881Speter/** RA functions **/
1170251881Speter
1171289180Speter/* Implements svn_ra__vtable_t.reparent(). */
1172289180Spetersvn_error_t *
1173289180Spetersvn_ra_serf__reparent(svn_ra_session_t *ra_session,
1174289180Speter                      const char *url,
1175289180Speter                      apr_pool_t *pool);
1176289180Speter
1177289180Speter/* Implements svn_ra__vtable_t.rev_prop(). */
1178289180Spetersvn_error_t *
1179289180Spetersvn_ra_serf__rev_prop(svn_ra_session_t *session,
1180289180Speter                      svn_revnum_t rev,
1181289180Speter                      const char *name,
1182289180Speter                      svn_string_t **value,
1183289180Speter                      apr_pool_t *pool);
1184289180Speter
1185251881Speter/* Implements svn_ra__vtable_t.get_log(). */
1186251881Spetersvn_error_t *
1187251881Spetersvn_ra_serf__get_log(svn_ra_session_t *session,
1188251881Speter                     const apr_array_header_t *paths,
1189251881Speter                     svn_revnum_t start,
1190251881Speter                     svn_revnum_t end,
1191251881Speter                     int limit,
1192251881Speter                     svn_boolean_t discover_changed_paths,
1193251881Speter                     svn_boolean_t strict_node_history,
1194251881Speter                     svn_boolean_t include_merged_revisions,
1195251881Speter                     const apr_array_header_t *revprops,
1196251881Speter                     svn_log_entry_receiver_t receiver,
1197251881Speter                     void *receiver_baton,
1198251881Speter                     apr_pool_t *pool);
1199251881Speter
1200289180Speter/* Implements svn_ra__vtable_t.check_path(). */
1201289180Spetersvn_error_t *
1202289180Spetersvn_ra_serf__check_path(svn_ra_session_t *ra_session,
1203289180Speter                        const char *rel_path,
1204289180Speter                        svn_revnum_t revision,
1205289180Speter                        svn_node_kind_t *kind,
1206289180Speter                        apr_pool_t *pool);
1207289180Speter
1208289180Speter/* Implements svn_ra__vtable_t.stat(). */
1209289180Spetersvn_error_t *
1210289180Spetersvn_ra_serf__stat(svn_ra_session_t *ra_session,
1211289180Speter                  const char *rel_path,
1212289180Speter                  svn_revnum_t revision,
1213289180Speter                  svn_dirent_t **dirent,
1214289180Speter                  apr_pool_t *pool);
1215289180Speter
1216251881Speter/* Implements svn_ra__vtable_t.get_locations(). */
1217251881Spetersvn_error_t *
1218251881Spetersvn_ra_serf__get_locations(svn_ra_session_t *session,
1219251881Speter                           apr_hash_t **locations,
1220251881Speter                           const char *path,
1221251881Speter                           svn_revnum_t peg_revision,
1222251881Speter                           const apr_array_header_t *location_revisions,
1223251881Speter                           apr_pool_t *pool);
1224251881Speter
1225251881Speter/* Implements svn_ra__vtable_t.get_location_segments(). */
1226251881Spetersvn_error_t *
1227251881Spetersvn_ra_serf__get_location_segments(svn_ra_session_t *session,
1228251881Speter                                   const char *path,
1229251881Speter                                   svn_revnum_t peg_revision,
1230251881Speter                                   svn_revnum_t start_rev,
1231251881Speter                                   svn_revnum_t end_rev,
1232251881Speter                                   svn_location_segment_receiver_t receiver,
1233251881Speter                                   void *receiver_baton,
1234251881Speter                                   apr_pool_t *pool);
1235251881Speter
1236251881Speter/* Implements svn_ra__vtable_t.do_diff(). */
1237251881Spetersvn_error_t *
1238251881Spetersvn_ra_serf__do_diff(svn_ra_session_t *session,
1239251881Speter                     const svn_ra_reporter3_t **reporter,
1240251881Speter                     void **report_baton,
1241251881Speter                     svn_revnum_t revision,
1242251881Speter                     const char *diff_target,
1243251881Speter                     svn_depth_t depth,
1244251881Speter                     svn_boolean_t ignore_ancestry,
1245251881Speter                     svn_boolean_t text_deltas,
1246251881Speter                     const char *versus_url,
1247251881Speter                     const svn_delta_editor_t *diff_editor,
1248251881Speter                     void *diff_baton,
1249251881Speter                     apr_pool_t *pool);
1250251881Speter
1251251881Speter/* Implements svn_ra__vtable_t.do_status(). */
1252251881Spetersvn_error_t *
1253251881Spetersvn_ra_serf__do_status(svn_ra_session_t *ra_session,
1254251881Speter                       const svn_ra_reporter3_t **reporter,
1255251881Speter                       void **report_baton,
1256251881Speter                       const char *status_target,
1257251881Speter                       svn_revnum_t revision,
1258251881Speter                       svn_depth_t depth,
1259251881Speter                       const svn_delta_editor_t *status_editor,
1260251881Speter                       void *status_baton,
1261251881Speter                       apr_pool_t *pool);
1262251881Speter
1263251881Speter/* Implements svn_ra__vtable_t.do_update(). */
1264251881Spetersvn_error_t *
1265251881Spetersvn_ra_serf__do_update(svn_ra_session_t *ra_session,
1266251881Speter                       const svn_ra_reporter3_t **reporter,
1267251881Speter                       void **report_baton,
1268251881Speter                       svn_revnum_t revision_to_update_to,
1269251881Speter                       const char *update_target,
1270251881Speter                       svn_depth_t depth,
1271251881Speter                       svn_boolean_t send_copyfrom_args,
1272251881Speter                       svn_boolean_t ignore_ancestry,
1273251881Speter                       const svn_delta_editor_t *update_editor,
1274251881Speter                       void *update_baton,
1275251881Speter                       apr_pool_t *result_pool,
1276251881Speter                       apr_pool_t *scratch_pool);
1277251881Speter
1278251881Speter/* Implements svn_ra__vtable_t.do_switch(). */
1279251881Spetersvn_error_t *
1280251881Spetersvn_ra_serf__do_switch(svn_ra_session_t *ra_session,
1281251881Speter                       const svn_ra_reporter3_t **reporter,
1282251881Speter                       void **report_baton,
1283251881Speter                       svn_revnum_t revision_to_switch_to,
1284251881Speter                       const char *switch_target,
1285251881Speter                       svn_depth_t depth,
1286251881Speter                       const char *switch_url,
1287251881Speter                       svn_boolean_t send_copyfrom_args,
1288251881Speter                       svn_boolean_t ignore_ancestry,
1289251881Speter                       const svn_delta_editor_t *switch_editor,
1290251881Speter                       void *switch_baton,
1291251881Speter                       apr_pool_t *result_pool,
1292251881Speter                       apr_pool_t *scratch_pool);
1293251881Speter
1294251881Speter/* Implements svn_ra__vtable_t.get_file_revs(). */
1295251881Spetersvn_error_t *
1296251881Spetersvn_ra_serf__get_file_revs(svn_ra_session_t *session,
1297251881Speter                           const char *path,
1298251881Speter                           svn_revnum_t start,
1299251881Speter                           svn_revnum_t end,
1300251881Speter                           svn_boolean_t include_merged_revisions,
1301251881Speter                           svn_file_rev_handler_t handler,
1302251881Speter                           void *handler_baton,
1303251881Speter                           apr_pool_t *pool);
1304251881Speter
1305251881Speter/* Implements svn_ra__vtable_t.get_dated_revision(). */
1306251881Spetersvn_error_t *
1307251881Spetersvn_ra_serf__get_dated_revision(svn_ra_session_t *session,
1308251881Speter                                svn_revnum_t *revision,
1309251881Speter                                apr_time_t tm,
1310251881Speter                                apr_pool_t *pool);
1311251881Speter
1312289180Speter/* Implements svn_ra__vtable_t.get_commit_editor().
1313289180Speter *
1314289180Speter * Note: Like other commit editors, the returned editor requires that the
1315289180Speter * @c copyfrom_path parameter passed to its @c add_file and @c add_directory
1316289180Speter * methods is a URL, not a relative path.
1317289180Speter */
1318251881Spetersvn_error_t *
1319251881Spetersvn_ra_serf__get_commit_editor(svn_ra_session_t *session,
1320251881Speter                               const svn_delta_editor_t **editor,
1321251881Speter                               void **edit_baton,
1322251881Speter                               apr_hash_t *revprop_table,
1323251881Speter                               svn_commit_callback2_t callback,
1324251881Speter                               void *callback_baton,
1325251881Speter                               apr_hash_t *lock_tokens,
1326251881Speter                               svn_boolean_t keep_locks,
1327251881Speter                               apr_pool_t *pool);
1328251881Speter
1329251881Speter/* Implements svn_ra__vtable_t.get_file(). */
1330251881Spetersvn_error_t *
1331251881Spetersvn_ra_serf__get_file(svn_ra_session_t *session,
1332251881Speter                      const char *path,
1333251881Speter                      svn_revnum_t revision,
1334251881Speter                      svn_stream_t *stream,
1335251881Speter                      svn_revnum_t *fetched_rev,
1336251881Speter                      apr_hash_t **props,
1337251881Speter                      apr_pool_t *pool);
1338251881Speter
1339289180Speter/* Implements svn_ra__vtable_t.get_dir(). */
1340289180Spetersvn_error_t *
1341289180Spetersvn_ra_serf__get_dir(svn_ra_session_t *ra_session,
1342289180Speter                     apr_hash_t **dirents,
1343289180Speter                     svn_revnum_t *fetched_rev,
1344289180Speter                     apr_hash_t **ret_props,
1345289180Speter                     const char *rel_path,
1346289180Speter                     svn_revnum_t revision,
1347289180Speter                     apr_uint32_t dirent_fields,
1348289180Speter                     apr_pool_t *result_pool);
1349289180Speter
1350251881Speter/* Implements svn_ra__vtable_t.change_rev_prop(). */
1351251881Spetersvn_error_t *
1352251881Spetersvn_ra_serf__change_rev_prop(svn_ra_session_t *session,
1353251881Speter                             svn_revnum_t rev,
1354251881Speter                             const char *name,
1355251881Speter                             const svn_string_t *const *old_value_p,
1356251881Speter                             const svn_string_t *value,
1357251881Speter                             apr_pool_t *pool);
1358251881Speter
1359251881Speter/* Implements svn_ra__vtable_t.replay(). */
1360251881Spetersvn_error_t *
1361251881Spetersvn_ra_serf__replay(svn_ra_session_t *ra_session,
1362251881Speter                    svn_revnum_t revision,
1363251881Speter                    svn_revnum_t low_water_mark,
1364251881Speter                    svn_boolean_t text_deltas,
1365251881Speter                    const svn_delta_editor_t *editor,
1366251881Speter                    void *edit_baton,
1367251881Speter                    apr_pool_t *pool);
1368251881Speter
1369251881Speter/* Implements svn_ra__vtable_t.replay_range(). */
1370251881Spetersvn_error_t *
1371251881Spetersvn_ra_serf__replay_range(svn_ra_session_t *ra_session,
1372251881Speter                          svn_revnum_t start_revision,
1373251881Speter                          svn_revnum_t end_revision,
1374251881Speter                          svn_revnum_t low_water_mark,
1375251881Speter                          svn_boolean_t send_deltas,
1376251881Speter                          svn_ra_replay_revstart_callback_t revstart_func,
1377251881Speter                          svn_ra_replay_revfinish_callback_t revfinish_func,
1378251881Speter                          void *replay_baton,
1379251881Speter                          apr_pool_t *pool);
1380251881Speter
1381251881Speter/* Implements svn_ra__vtable_t.lock(). */
1382251881Spetersvn_error_t *
1383251881Spetersvn_ra_serf__lock(svn_ra_session_t *ra_session,
1384251881Speter                  apr_hash_t *path_revs,
1385251881Speter                  const char *comment,
1386251881Speter                  svn_boolean_t force,
1387251881Speter                  svn_ra_lock_callback_t lock_func,
1388251881Speter                  void *lock_baton,
1389251881Speter                  apr_pool_t *pool);
1390251881Speter
1391251881Speter/* Implements svn_ra__vtable_t.unlock(). */
1392251881Spetersvn_error_t *
1393251881Spetersvn_ra_serf__unlock(svn_ra_session_t *ra_session,
1394251881Speter                    apr_hash_t *path_tokens,
1395251881Speter                    svn_boolean_t force,
1396251881Speter                    svn_ra_lock_callback_t lock_func,
1397251881Speter                    void *lock_baton,
1398251881Speter                    apr_pool_t *pool);
1399251881Speter
1400251881Speter/* Implements svn_ra__vtable_t.get_lock(). */
1401251881Spetersvn_error_t *
1402251881Spetersvn_ra_serf__get_lock(svn_ra_session_t *ra_session,
1403251881Speter                      svn_lock_t **lock,
1404251881Speter                      const char *path,
1405251881Speter                      apr_pool_t *pool);
1406251881Speter
1407251881Speter/* Implements svn_ra__vtable_t.get_locks(). */
1408251881Spetersvn_error_t *
1409251881Spetersvn_ra_serf__get_locks(svn_ra_session_t *ra_session,
1410251881Speter                       apr_hash_t **locks,
1411251881Speter                       const char *path,
1412251881Speter                       svn_depth_t depth,
1413251881Speter                       apr_pool_t *pool);
1414251881Speter
1415251881Speter/* Request a mergeinfo-report from the URL attached to SESSION,
1416251881Speter   and fill in the MERGEINFO hash with the results.
1417251881Speter
1418251881Speter   Implements svn_ra__vtable_t.get_mergeinfo().
1419251881Speter */
1420251881Spetersvn_error_t *
1421251881Spetersvn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
1422251881Speter                           apr_hash_t **mergeinfo,
1423251881Speter                           const apr_array_header_t *paths,
1424251881Speter                           svn_revnum_t revision,
1425251881Speter                           svn_mergeinfo_inheritance_t inherit,
1426251881Speter                           svn_boolean_t include_descendants,
1427251881Speter                           apr_pool_t *pool);
1428251881Speter
1429251881Speter/* Exchange capabilities with the server, by sending an OPTIONS
1430251881Speter * request announcing the client's capabilities, and by filling
1431251881Speter * SERF_SESS->capabilities with the server's capabilities as read from
1432251881Speter * the response headers.  Use POOL only for temporary allocation.
1433251881Speter *
1434251881Speter * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to
1435251881Speter * report a server-dictated redirect or relocation (HTTP 301 or 302
1436251881Speter * error codes), setting *CORRECTED_URL to the value of the corrected
1437251881Speter * repository URL.  Otherwise, such responses from the server will
1438251881Speter * generate an error.  (In either case, no capabilities are exchanged
1439251881Speter * if there is, in fact, such a response from the server.)
1440251881Speter */
1441251881Spetersvn_error_t *
1442251881Spetersvn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess,
1443251881Speter                                   const char **corrected_url,
1444289180Speter                                   apr_pool_t *result_pool,
1445289180Speter                                   apr_pool_t *scratch_pool);
1446251881Speter
1447251881Speter/* Implements svn_ra__vtable_t.has_capability(). */
1448251881Spetersvn_error_t *
1449251881Spetersvn_ra_serf__has_capability(svn_ra_session_t *ra_session,
1450251881Speter                            svn_boolean_t *has,
1451251881Speter                            const char *capability,
1452251881Speter                            apr_pool_t *pool);
1453251881Speter
1454251881Speter/* Implements svn_ra__vtable_t.get_deleted_rev(). */
1455251881Spetersvn_error_t *
1456251881Spetersvn_ra_serf__get_deleted_rev(svn_ra_session_t *session,
1457251881Speter                             const char *path,
1458251881Speter                             svn_revnum_t peg_revision,
1459251881Speter                             svn_revnum_t end_revision,
1460251881Speter                             svn_revnum_t *revision_deleted,
1461251881Speter                             apr_pool_t *pool);
1462251881Speter
1463251881Speter/* Implements the get_inherited_props RA layer function. */
1464251881Spetersvn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session,
1465251881Speter                                               apr_array_header_t **iprops,
1466251881Speter                                               const char *path,
1467251881Speter                                               svn_revnum_t revision,
1468251881Speter                                               apr_pool_t *result_pool,
1469251881Speter                                               apr_pool_t *scratch_pool);
1470251881Speter
1471251881Speter/* Implements svn_ra__vtable_t.get_repos_root(). */
1472251881Spetersvn_error_t *
1473251881Spetersvn_ra_serf__get_repos_root(svn_ra_session_t *ra_session,
1474251881Speter                            const char **url,
1475251881Speter                            apr_pool_t *pool);
1476251881Speter
1477251881Speter/* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */
1478251881Spetersvn_error_t *
1479251881Spetersvn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
1480251881Speter                                    svn_delta_shim_callbacks_t *callbacks);
1481251881Speter
1482251881Speter/*** Authentication handler declarations ***/
1483251881Speter
1484251881Speter/**
1485251881Speter * Callback function that loads the credentials for Basic and Digest
1486251881Speter * authentications, both for server and proxy authentication.
1487251881Speter */
1488251881Speterapr_status_t
1489251881Spetersvn_ra_serf__credentials_callback(char **username, char **password,
1490251881Speter                                  serf_request_t *request, void *baton,
1491251881Speter                                  int code, const char *authn_type,
1492251881Speter                                  const char *realm,
1493251881Speter                                  apr_pool_t *pool);
1494251881Speter
1495251881Speter
1496251881Speter/*** General utility functions ***/
1497251881Speter
1498251881Speter/**
1499251881Speter * Convert an HTTP STATUS_CODE resulting from a WebDAV request against
1500251881Speter * PATH to the relevant error code.  Use the response-supplied LOCATION
1501251881Speter * where it necessary.
1502289180Speter *
1503289180Speter * Returns SVN_NO_ERROR if sline doesn't specify an error condition
1504251881Speter */
1505251881Spetersvn_error_t *
1506253734Spetersvn_ra_serf__error_on_status(serf_status_line sline,
1507251881Speter                             const char *path,
1508251881Speter                             const char *location);
1509251881Speter
1510289180Speter/**
1511289180Speter * Convert an unexpected HTTP STATUS_CODE from a request to the relevant error
1512289180Speter * code. Unlike svn_ra_serf__error_on_status() this function creates an error
1513289180Speter * for any result
1514289180Speter */
1515289180Spetersvn_error_t *
1516289180Spetersvn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler);
1517289180Speter
1518289180Speter
1519251881Speter/* ###? */
1520251881Spetersvn_error_t *
1521251881Spetersvn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf,
1522251881Speter                                serf_bucket_t *bkt,
1523251881Speter                                apr_pool_t *result_pool,
1524251881Speter                                apr_pool_t *scratch_pool);
1525251881Speter
1526251881Speter/* ###? */
1527251881Speterserf_bucket_t *
1528251881Spetersvn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf,
1529251881Speter                              serf_bucket_alloc_t *allocator,
1530251881Speter                              apr_pool_t *result_pool,
1531251881Speter                              apr_pool_t *scratch_pool);
1532251881Speter
1533251881Speter/** Wrap STATUS from an serf function. If STATUS is not serf error code,
1534251881Speter  * this is equivalent to svn_error_wrap_apr().
1535251881Speter */
1536251881Spetersvn_error_t *
1537251881Spetersvn_ra_serf__wrap_err(apr_status_t status,
1538251881Speter                      const char *fmt,
1539251881Speter                      ...);
1540251881Speter
1541289180Speter/* Create a bucket that just returns DATA (with length LEN) and then returns
1542289180Speter   the APR_EAGAIN status */
1543289180Speterserf_bucket_t *
1544289180Spetersvn_ra_serf__create_bucket_with_eagain(const char *data,
1545289180Speter                                       apr_size_t len,
1546289180Speter                                       serf_bucket_alloc_t *allocator);
1547251881Speter
1548298845Sdim/* Parse a given URL_STR, fill in all supplied fields of URI
1549298845Sdim * structure.
1550298845Sdim *
1551298845Sdim * This function is a compatibility wrapper around apr_uri_parse().
1552298845Sdim * Different apr-util versions set apr_uri_t.path to either NULL or ""
1553298845Sdim * for root paths, and serf expects to see "/". This function always
1554298845Sdim * sets URI.path to "/" for these paths. */
1555298845Sdimsvn_error_t *
1556298845Sdimsvn_ra_serf__uri_parse(apr_uri_t *uri,
1557298845Sdim                       const char *url_str,
1558298845Sdim                       apr_pool_t *result_pool);
1559289180Speter
1560289180Speter
1561251881Speter#if defined(SVN_DEBUG)
1562251881Speter/* Wrapper macros to collect file and line information */
1563251881Speter#define svn_ra_serf__wrap_err \
1564251881Speter  (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err))
1565251881Speter
1566251881Speter#endif
1567251881Speter
1568251881Speter#ifdef __cplusplus
1569251881Speter}
1570251881Speter#endif /* __cplusplus */
1571251881Speter
1572251881Speter#endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */
1573