2 * ra_serf.h : Private declarations for the Serf-based DAV RA module.
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
24 #ifndef SVN_LIBSVN_RA_SERF_RA_SERF_H
25 #define SVN_LIBSVN_RA_SERF_RA_SERF_H
31 #include "svn_types.h"
32 #include "svn_string.h"
33 #include "svn_pools.h"
35 #include "svn_delta.h"
36 #include "svn_version.h"
38 #include "svn_dirent_uri.h"
40 #include "private/svn_dav_protocol.h"
41 #include "private/svn_subr_private.h"
42 #include "private/svn_editor.h"
48 #endif /* __cplusplus */
51 /* Enforce the minimum version of serf. */
52 #if !SERF_VERSION_AT_LEAST(1, 2, 1)
53 #error Please update your version of serf to at least 1.2.1.
56 /** Wait duration (in microseconds) used in calls to serf_context_run() */
57 #define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000
61 /* Forward declarations. */
62 typedef struct svn_ra_serf__session_t svn_ra_serf__session_t;
64 /* A serf connection and optionally associated SSL context. */
65 typedef struct svn_ra_serf__connection_t {
66 /* Our connection to a server. */
67 serf_connection_t *conn;
69 /* Bucket allocator for this connection. */
70 serf_bucket_alloc_t *bkt_alloc;
72 /* Collected cert failures in chain. */
73 int server_cert_failures;
75 /* What was the last HTTP status code we got on this connection? */
78 /* Optional SSL context for this connection. */
79 serf_ssl_context_t *ssl_context;
80 svn_auth_iterstate_t *ssl_client_auth_state;
81 svn_auth_iterstate_t *ssl_client_pw_auth_state;
83 svn_ra_serf__session_t *session;
85 } svn_ra_serf__connection_t;
87 /** Maximum value we'll allow for the http-max-connections config option.
89 * Note: minimum 2 connections are required for ra_serf to function
92 #define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8
95 * The master serf RA session.
97 * This is stored in the ra session ->priv field.
99 * ### Check ra_serf_dup_session when adding fields.
101 struct svn_ra_serf__session_t {
102 /* Pool for allocations during this session */
104 apr_hash_t *config; /* For duplicating */
106 /* The current context */
107 serf_context_t *context;
109 /* The maximum number of connections we'll use for parallelized
110 fetch operations (updates, etc.) */
111 apr_int64_t max_connections;
113 /* Are we using ssl */
114 svn_boolean_t using_ssl;
116 /* Tristate flag that indicates if we should use compression for
117 network transmissions. If svn_tristate_true or svn_tristate_false,
118 the compression should be enabled and disabled, respectively.
119 If svn_tristate_unknown, determine this automatically based
120 on network parameters. */
121 svn_tristate_t using_compression;
123 /* The user agent string */
124 const char *useragent;
126 /* The current connection */
127 svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT];
131 /* The URL that was passed into _open() */
132 apr_uri_t session_url;
133 const char *session_url_str;
135 /* The actual discovered root; may be NULL until we know it. */
136 apr_uri_t repos_root;
137 const char *repos_root_str;
139 /* The server is not Apache/mod_dav_svn (directly) and only supports
140 HTTP/1.0. Thus, we cannot send chunked requests. */
141 svn_boolean_t http10;
143 /* We are talking to the server via http/2. Responses of scheduled
144 requests may come in any order */
145 svn_boolean_t http20;
147 /* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */
148 svn_boolean_t using_chunked_requests;
150 /* Do we need to detect whether the connection supports chunked requests?
151 i.e. is there a (reverse) proxy that does not support them? */
152 svn_boolean_t detect_chunking;
154 /* Our Version-Controlled-Configuration; may be NULL until we know it. */
157 /* Authentication related properties. */
158 svn_auth_iterstate_t *auth_state;
161 /* Callback functions to get info from WC */
162 const svn_ra_callbacks2_t *wc_callbacks;
163 void *wc_callback_baton;
164 svn_auth_baton_t *auth_baton;
166 /* Callback function to send progress info to the client */
167 svn_ra_progress_notify_func_t progress_func;
168 void *progress_baton;
170 /* Callback function to handle cancellation */
171 svn_cancel_func_t cancel_func;
174 /* Ev2 shim callbacks */
175 svn_delta_shim_callbacks_t *shim_callbacks;
177 /* Error that we've received but not yet returned upstream. */
178 svn_error_t *pending_error;
180 /* List of authn types supported by the client.*/
183 /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values.
184 If a capability is not yet discovered, it is absent from the table.
185 The table itself is allocated in the svn_ra_serf__session_t's pool;
186 keys and values must have at least that lifetime. Most likely
187 the keys and values are constants anyway (and sufficiently
188 well-informed internal code may just compare against those
189 constants' addresses, therefore). */
190 apr_hash_t *capabilities;
192 /* Activity collection URL. (Cached from the initial OPTIONS
193 request when run against HTTPv1 servers.) */
194 const char *activity_collection_url;
196 /* Are we using a proxy? */
197 svn_boolean_t using_proxy;
199 const char *proxy_username;
200 const char *proxy_password;
201 int proxy_auth_attempts;
203 /* SSL server certificates */
204 svn_boolean_t trust_default_ca;
205 const char *ssl_authorities;
207 /* Repository UUID */
210 /* Connection timeout value */
211 apr_interval_time_t timeout;
214 svn_tristate_t supports_deadprop_count;
216 /*** HTTP v2 protocol stuff. ***
218 * We assume that if mod_dav_svn sends one of the special v2 OPTIONs
219 * response headers, it has sent all of them. Specifically, we'll
220 * be looking at the presence of the "me resource" as a flag that
221 * the server supports v2 of our HTTP protocol.
224 /* The "me resource". Typically used as a target for REPORTs that
225 are path-agnostic. If we have this, we can speak HTTP v2 to the
227 const char *me_resource;
229 /* Opaque URL "stubs". If the OPTIONS response returns these, then
230 we know we're using HTTP protocol v2. */
231 const char *rev_stub; /* for accessing revisions (i.e. revprops) */
232 const char *rev_root_stub; /* for accessing REV/PATH pairs */
233 const char *txn_stub; /* for accessing transactions (i.e. txnprops) */
234 const char *txn_root_stub; /* for accessing TXN/PATH pairs */
235 const char *vtxn_stub; /* for accessing transactions (i.e. txnprops) */
236 const char *vtxn_root_stub; /* for accessing TXN/PATH pairs */
238 /* Hash mapping const char * server-supported POST types to
239 disinteresting-but-non-null values. */
240 apr_hash_t *supported_posts;
242 /*** End HTTP v2 stuff ***/
244 svn_ra_serf__blncache_t *blncache;
246 /* Trisate flag that indicates user preference for using bulk updates
247 (svn_tristate_true) with all the properties and content in the
248 update-report response. If svn_tristate_false, request a skelta
249 update-report with inlined properties. If svn_tristate_unknown then use
250 server preference. */
251 svn_tristate_t bulk_updates;
253 /* Indicates if the server wants bulk update requests (Prefer) or only
254 accepts skelta requests (Off). If this value is On both options are
256 const char *server_allows_bulk;
258 /* Indicates if the server supports sending inlined props in update editor
259 * in skelta mode (send-all == 'false'). */
260 svn_boolean_t supports_inline_props;
262 /* Indicates whether the server supports issuing replay REPORTs
263 against rev resources (children of `rev_stub', elsestruct). */
264 svn_boolean_t supports_rev_rsrc_replay;
266 /* Indicates whether the server can understand svndiff version 1. */
267 svn_boolean_t supports_svndiff1;
269 /* Indicates whether the server can understand svndiff version 2. */
270 svn_boolean_t supports_svndiff2;
272 /* Indicates whether the server sends the result checksum in the response
273 * to a successful PUT request. */
274 svn_boolean_t supports_put_result_checksum;
276 apr_interval_time_t conn_latency;
279 #define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL)
282 * Structure which represents a DAV element with a NAMESPACE and NAME.
284 typedef struct svn_ra_serf__dav_props_t {
285 /* Element namespace */
289 } svn_ra_serf__dav_props_t;
291 /** DAV property sets **/
293 static const svn_ra_serf__dav_props_t base_props[] =
295 { "DAV:", "version-controlled-configuration" },
296 { "DAV:", "resourcetype" },
297 { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },
298 { SVN_DAV_PROP_NS_DAV, "repository-uuid" },
302 static const svn_ra_serf__dav_props_t checked_in_props[] =
304 { "DAV:", "checked-in" },
308 static const svn_ra_serf__dav_props_t baseline_props[] =
310 { "DAV:", "baseline-collection" },
311 { "DAV:", SVN_DAV__VERSION_NAME },
315 static const svn_ra_serf__dav_props_t all_props[] =
317 { "DAV:", "allprop" },
321 static const svn_ra_serf__dav_props_t check_path_props[] =
323 { "DAV:", "resourcetype" },
327 static const svn_ra_serf__dav_props_t type_and_checksum_props[] =
329 { "DAV:", "resourcetype" },
330 { SVN_DAV_PROP_NS_DAV, "sha1-checksum" },
334 /* WC props compatibility with ra_neon. */
335 #define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
337 /** Serf utility functions **/
340 svn_ra_serf__conn_setup(apr_socket_t *sock,
341 serf_bucket_t **read_bkt,
342 serf_bucket_t **write_bkt,
347 svn_ra_serf__conn_closed(serf_connection_t *conn,
353 /* Helper function to provide SSL client certificates.
355 * NOTE: This function sets the session's 'pending_error' member when
356 * returning an non-success status.
359 svn_ra_serf__handle_client_cert(void *data,
360 const char **cert_path);
362 /* Helper function to provide SSL client certificate passwords.
364 * NOTE: This function sets the session's 'pending_error' member when
365 * returning an non-success status.
368 svn_ra_serf__handle_client_cert_pw(void *data,
369 const char *cert_path,
370 const char **password);
374 * This function will run the serf context in SESS until *DONE is TRUE.
377 svn_ra_serf__context_run_wait(svn_boolean_t *done,
378 svn_ra_serf__session_t *sess,
379 apr_pool_t *scratch_pool);
381 /* Run the context once. Manage waittime_left to handle timing out when
382 nothing happens over the session->timout.
385 svn_ra_serf__context_run(svn_ra_serf__session_t *sess,
386 apr_interval_time_t *waittime_left,
387 apr_pool_t *scratch_pool);
391 /* Callback for response handlers */
392 typedef svn_error_t *
393 (*svn_ra_serf__response_handler_t)(serf_request_t *request,
394 serf_bucket_t *response,
396 apr_pool_t *scratch_pool);
398 /* Callback when the request is done */
399 typedef svn_error_t *
400 (*svn_ra_serf__response_done_delegate_t)(serf_request_t *request,
402 apr_pool_t *scratch_pool);
404 /* Callback for when a request body is needed. */
405 typedef svn_error_t *
406 (*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt,
408 serf_bucket_alloc_t *alloc,
409 apr_pool_t *request_pool,
410 apr_pool_t *scratch_pool);
412 /* Callback for when request headers are needed. */
413 typedef svn_error_t *
414 (*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers,
416 apr_pool_t *request_pool,
417 apr_pool_t *scratch_pool);
419 /* Callback for when a response has an error. */
420 typedef svn_error_t *
421 (*svn_ra_serf__response_error_t)(serf_request_t *request,
422 serf_bucket_t *response,
426 /* ### we should reorder the types in this file. */
427 typedef struct svn_ra_serf__server_error_t svn_ra_serf__server_error_t;
430 * Structure that can be passed to our default handler to guide the
431 * execution of the request through its lifecycle.
433 * Use svn_ra_serf__create_handler() to create instances of this struct.
435 typedef struct svn_ra_serf__handler_t {
436 /* The HTTP method string of the request */
439 /* The resource to the execute the method on. */
442 /* The content-type of the request body. */
443 const char *body_type;
445 /* If TRUE then default Accept-Encoding request header is not configured for
446 request. If FALSE then 'gzip' accept encoding will be used if compression
448 svn_boolean_t custom_accept_encoding;
450 /* If TRUE then default DAV: capabilities request headers is not configured
452 svn_boolean_t no_dav_headers;
454 /* If TRUE doesn't fail requests on HTTP error statuses like 405, 408, 500
455 (see util.c response_done()) */
456 svn_boolean_t no_fail_on_http_failure_status;
458 /* If TRUE doesn't fail requests on HTTP redirect statuses like 301, 307 */
459 svn_boolean_t no_fail_on_http_redirect_status;
461 /* Has the request/response been completed? */
463 svn_boolean_t scheduled; /* Is the request scheduled in a context */
465 /* If we captured an error from the server, then this will be non-NULL.
466 It will be allocated from HANDLER_POOL. */
467 svn_ra_serf__server_error_t *server_error;
469 /* The handler and baton pair for our handler. */
470 svn_ra_serf__response_handler_t response_handler;
471 void *response_baton;
473 /* When REPONSE_HANDLER is invoked, the following fields will be set
474 based on the response header. HANDLER_POOL must be non-NULL for these
475 values to be filled in. SLINE.REASON and LOCATION will be allocated
476 within HANDLER_POOL. */
477 serf_status_line sline; /* The parsed Status-Line */
478 const char *location; /* The Location: header, if any */
480 /* This function and baton pair allows handling the completion of request.
482 * The default handler is responsible for the HTTP failure processing.
484 * If no_fail_on_http_failure_status is not TRUE, then the callback will
485 * return recorded server errors or if there is none and the http status
486 * specifies an error returns an error for that.
488 * The default baton is the handler itself.
490 svn_ra_serf__response_done_delegate_t done_delegate;
491 void *done_delegate_baton;
493 /* The handler and baton pair to be executed when a non-recoverable error
494 * is detected. If it is NULL in the presence of an error, an abort() may
497 svn_ra_serf__response_error_t response_error;
498 void *response_error_baton;
500 /* This function and baton pair allows for custom request headers to
503 * It will be executed after the request has been set up but before it is
506 svn_ra_serf__request_header_delegate_t header_delegate;
507 void *header_delegate_baton;
509 /* This function and baton pair allows a body to be created right before
512 * It will be executed after the request has been set up but before it is
515 * May be NULL if there is no body to send.
518 svn_ra_serf__request_body_delegate_t body_delegate;
519 void *body_delegate_baton;
521 /* The connection and session to be used for this request. */
522 svn_ra_serf__connection_t *conn;
523 svn_ra_serf__session_t *session;
525 /* Internal flag to indicate we've parsed the headers. */
526 svn_boolean_t reading_body;
528 /* When this flag will be set, the core handler will discard any unread
529 portion of the response body. The registered response handler will
530 no longer be called. */
531 svn_boolean_t discard_body;
533 /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL,
534 then the requestor does not care about SLINE and LOCATION. */
535 apr_pool_t *handler_pool;
536 } svn_ra_serf__handler_t;
539 /* Run one request and process the response.
541 Similar to context_run_wait(), but this creates the request for HANDLER
542 and then waits for it to complete.
544 WARNING: context_run_wait() does NOT create a request, whereas this
545 function DOES. Avoid a double-create. */
547 svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
548 apr_pool_t *scratch_pool);
552 * Helper function to queue a request in the @a handler's connection.
554 void svn_ra_serf__request_create(svn_ra_serf__handler_t *handler);
556 /* v2 of the XML parsing functions */
558 /* The XML parsing context. */
559 typedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t;
562 /* An opaque structure for the XML parse element/state. */
563 typedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t;
565 /* Called just after the parser moves into ENTERED_STATE. The tag causing
566 the transition is passed in TAG.
568 This callback is applied to a parsing context by using the
569 svn_ra_serf__xml_context_customize() function.
571 NOTE: this callback, when set, will be invoked on *every* transition.
572 The callback must examine ENTERED_STATE to determine if any action
573 must be taken. The original state is not provided, but must be derived
574 from ENTERED_STATE and/or the TAG causing the transition (if needed). */
575 typedef svn_error_t *
576 (*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
579 const svn_ra_serf__dav_props_t *tag,
580 apr_pool_t *scratch_pool);
583 /* Called just before the parser leaves LEAVING_STATE.
585 If cdata collection was enabled for this state, then CDATA will be
586 non-NULL and contain the collected cdata.
588 If attribute collection was enabled for this state, then ATTRS will
589 contain the attributes collected for this element only, along with
590 any values stored via svn_ra_serf__xml_note().
592 Use svn_ra_serf__xml_gather_since() to gather up data from outer states.
594 ATTRS is char* -> char*.
596 Temporary allocations may be made in SCRATCH_POOL. */
597 typedef svn_error_t *
598 (*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes,
601 const svn_string_t *cdata,
603 apr_pool_t *scratch_pool);
606 /* Called for all states that are not using the builtin cdata collection.
607 This callback is (only) appropriate for unbounded-size cdata content.
609 CURRENT_STATE may be used to decide what to do with the data.
611 Temporary allocations may be made in SCRATCH_POOL. */
612 typedef svn_error_t *
613 (*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
618 apr_pool_t *scratch_pool);
621 /* Magic state value for the initial state in a svn_ra_serf__xml_transition_t
623 #define XML_STATE_INITIAL 0
625 /* State transition table.
627 When the XML Context is constructed, it is in state 0. User states are
630 In a list of transitions, use { 0 } to indicate the end. Specifically,
631 the code looks for NS == NULL.
633 The initial state for each transition table is XML_STATE_INITIAL.
637 typedef struct svn_ra_serf__xml_transition_t {
638 /* This transition applies when in this state */
641 /* And when this tag is observed */
645 /* Moving to this state */
648 /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
649 be TRUE in order to capture this cdata. */
650 svn_boolean_t collect_cdata;
652 /* Which attributes of NAME should be collected? Terminate with NULL.
653 Maximum of 10 attributes may be collected. Note that attribute
654 namespaces are ignored at this time.
656 Attribute names beginning with "?" are optional. Other names must
657 exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised. */
658 const char *collect_attrs[11];
660 /* When NAME is closed, should the callback be invoked? */
661 svn_boolean_t custom_close;
663 } svn_ra_serf__xml_transition_t;
665 /* Constructor for svn_ra_serf__handler_t. Initializes a new handler
666 with default settings for SESSION. */
667 svn_ra_serf__handler_t *
668 svn_ra_serf__create_handler(svn_ra_serf__session_t *session,
669 apr_pool_t *result_pool);
671 /* Construct an XML parsing context, based on the TTABLE transition table.
672 As content is parsed, the CLOSED_CB callback will be invoked according
673 to the definition in the table.
675 If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
676 event. The callback will need to use the ENTERED_STATE and TAG parameters
677 to decide what it would like to do.
679 If CDATA_CB is not NULL, then it will be called for all cdata that is
680 not be automatically collected (based on the transition table record's
681 COLLECT_CDATA flag). It will be called in every state, so the callback
682 must examine the CURRENT_STATE parameter to decide what to do.
684 The same BATON value will be passed to all three callbacks.
686 The context will be created within RESULT_POOL. */
687 svn_ra_serf__xml_context_t *
688 svn_ra_serf__xml_context_create(
689 const svn_ra_serf__xml_transition_t *ttable,
690 svn_ra_serf__xml_opened_t opened_cb,
691 svn_ra_serf__xml_closed_t closed_cb,
692 svn_ra_serf__xml_cdata_t cdata_cb,
694 apr_pool_t *result_pool);
696 /* Verifies if the parsing completed successfully and destroys
699 svn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx);
701 /* Construct a handler with the response function/baton set up to parse
702 a response body using the given XML context. The handler and its
703 internal structures are allocated in RESULT_POOL.
705 As part of the handling the http status value is compared to 200, or
706 if EXPECTED_STATUS is not NULL to all the values in EXPECTED_STATUS.
707 EXPECTED_STATUS is expected to be a list of integers ending with a 0
708 that lives at least as long as RESULT_POOL. If the status doesn't
709 match the request has failed and will be parsed as en error response.
711 This also initializes HANDLER_POOL to the given RESULT_POOL. */
712 svn_ra_serf__handler_t *
713 svn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session,
714 svn_ra_serf__xml_context_t *xmlctx,
715 const int *expected_status,
716 apr_pool_t *result_pool);
719 /* Allocated within XES->STATE_POOL. Changes are not allowd (callers
720 should make a deep copy if they need to make changes).
722 The resulting hash maps char* names to char* values. */
724 svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
728 /* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
729 The name and value will be copied into the target state's pool.
731 These values will be available to the CLOSED_CB for the target state,
732 or part of the gathered state via xml_gather_since().
734 Typically, this function is used by a child state's close callback,
735 or within an opening callback to store additional data.
737 Note: if the state is not found, then a programmer error has occurred,
738 so the function will invoke SVN_ERR_MALFUNCTION(). */
740 svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
746 /* Returns XES->STATE_POOL for allocating structures that should live
747 as long as the state identified by XES.
749 Note: a state pool is created upon demand, so only use this function
750 when memory is required for a given state. */
752 svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
755 * Parses a server-side error message into a local Subversion error.
757 struct svn_ra_serf__server_error_t {
760 /* XML parser and namespace used to parse the remote response */
761 svn_ra_serf__xml_context_t *xmlctx;
763 svn_ra_serf__response_handler_t response_handler;
764 void *response_baton;
766 /* The partial errors to construct the final error from */
767 apr_array_header_t *items;
769 /* The hooked handler */
770 svn_ra_serf__handler_t *handler;
774 * Handler that discards the entire @a response body associated with a
775 * @a request. Implements svn_ra_serf__response_handler_t.
777 * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an
778 * error is detected, it will be populated for later detection.
780 * All temporary allocations will be made in a @a pool.
783 svn_ra_serf__handle_discard_body(serf_request_t *request,
784 serf_bucket_t *response,
790 * Handler that retrieves the embedded XML multistatus response from the
791 * the @a RESPONSE body associated with a @a REQUEST.
793 * Implements svn_ra_serf__response_handler_t.
795 * The @a BATON should be of type svn_ra_serf__handler_t. When the request
796 * is complete, the handler's DONE flag will be set to TRUE.
798 * All temporary allocations will be made in a @a scratch_pool.
801 svn_ra_serf__handle_multistatus_only(serf_request_t *request,
802 serf_bucket_t *response,
804 apr_pool_t *scratch_pool);
807 /* Handler that expects an empty body.
809 If a body IS present, and it is text/xml, then it will be parsed for
812 BATON should be the svn_ra_serf__handler_t running REQUEST.
814 Status line information will be in HANDLER->SLINE.
816 Any parsed errors will be left in HANDLER->SERVER_ERROR. That member
817 may be NULL if no body was present, or a problem occurred trying to
820 All temporary allocations will be made in SCRATCH_POOL. */
822 svn_ra_serf__expect_empty_body(serf_request_t *request,
823 serf_bucket_t *response,
825 apr_pool_t *scratch_pool);
829 * This function sets up error parsing for an existing request
832 svn_ra_serf__setup_error_parsing(svn_ra_serf__server_error_t **server_err,
833 svn_ra_serf__handler_t *handler,
834 svn_boolean_t expect_207_only,
835 apr_pool_t *result_pool,
836 apr_pool_t *scratch_pool);
839 * Forwards response data to the server error parser
842 svn_ra_serf__handle_server_error(svn_ra_serf__server_error_t *server_error,
843 svn_ra_serf__handler_t *handler,
844 serf_request_t *request,
845 serf_bucket_t *response,
846 apr_status_t *serf_status,
847 apr_pool_t *scratch_pool);
850 * Creates the svn_error_t * instance from the error recorded in
851 * HANDLER->server_error
854 svn_ra_serf__server_error_create(svn_ra_serf__handler_t *handler,
855 apr_pool_t *scratch_pool);
857 /* serf_response_handler_t implementation that completely discards
860 * All temporary allocations will be made in @a pool.
863 svn_ra_serf__response_discard_handler(serf_request_t *request,
864 serf_bucket_t *response,
870 * Add the appropriate serf buckets to @a agg_bucket represented by
871 * the XML * @a tag and @a value.
873 * The bucket will be allocated from @a bkt_alloc.
876 svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket,
879 serf_bucket_alloc_t *bkt_alloc);
882 * Add the appropriate serf buckets to AGG_BUCKET with standard XML header:
883 * <?xml version="1.0" encoding="utf-8"?>
885 * The bucket will be allocated from BKT_ALLOC.
888 svn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket,
889 serf_bucket_alloc_t *bkt_alloc);
892 * Add the appropriate serf buckets to AGG_BUCKET representing the XML
893 * open tag with name TAG.
895 * Take the tag's attributes from varargs, a NULL-terminated list of
896 * alternating <tt>char *</tt> key and <tt>char *</tt> val. Attribute
897 * will be ignored if it's value is NULL.
899 * NOTE: Callers are responsible for XML-escaping attribute values as
902 * The bucket will be allocated from BKT_ALLOC.
905 svn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket,
906 serf_bucket_alloc_t *bkt_alloc,
908 ...) SVN_NEEDS_SENTINEL_NULL;
911 * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close
914 * The bucket will be allocated from BKT_ALLOC.
917 svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket,
918 serf_bucket_alloc_t *bkt_alloc,
921 /* Add the appropriate serf buckets to AGG_BUCKET representing the XML
922 * open tag with name TAG, and then immediately closes the tag using the />
926 svn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket,
927 serf_bucket_alloc_t *bkt_alloc,
929 ...) SVN_NEEDS_SENTINEL_NULL;
932 * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped
935 * The bucket will be allocated from BKT_ALLOC.
938 svn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket,
939 serf_bucket_alloc_t *bkt_alloc,
940 const char *data, apr_size_t len);
943 /** PROPFIND-related functions **/
945 /* Removes all non regular properties from PROPS */
947 svn_ra_serf__keep_only_regular_props(apr_hash_t *props,
948 apr_pool_t *scratch_pool);
951 /* Callback used via svn_ra_serf__deliver_props2 */
952 typedef svn_error_t *
953 (*svn_ra_serf__prop_func_t)(void *baton,
957 const svn_string_t *value,
958 apr_pool_t *scratch_pool);
961 * Implementation of svn_ra_serf__prop_func_t that just delivers svn compatible
962 * properties in the apr_hash_t * that is used as baton.
965 svn_ra_serf__deliver_svn_props(void *baton,
969 const svn_string_t *value,
970 apr_pool_t *scratch_pool);
973 * This function will create a handler for a PROPFIND request, which will deliver
974 * properties to PROP_FUNC() with PROP_BATON for the properties listed in LOOKUP_PROPS
975 * at URL for DEPTH ("0","1","infinity").
978 svn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **handler,
979 svn_ra_serf__session_t *session,
983 const svn_ra_serf__dav_props_t *find_props,
984 svn_ra_serf__prop_func_t prop_func,
985 void *prop_func_baton,
986 apr_pool_t *result_pool);
989 /* Using SESSION, fetch the properties specified by WHICH_PROPS using CONN
990 for URL at REVISION. The resulting properties are placed into a 2-level
991 hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which
992 is allocated in RESULT_POOL.
994 If REVISION is SVN_INVALID_REVNUM, then the properties are fetched
997 This function performs the request synchronously.
999 Temporary allocations are made in SCRATCH_POOL. */
1001 svn_ra_serf__fetch_node_props(apr_hash_t **results,
1002 svn_ra_serf__session_t *session,
1004 svn_revnum_t revision,
1005 const svn_ra_serf__dav_props_t *which_props,
1006 apr_pool_t *result_pool,
1007 apr_pool_t *scratch_pool);
1010 /* Using SESSION, fetch a DAV: property from the resource identified by URL
1011 within REVISION. The PROPNAME may be one of:
1016 The resulting value will be allocated in RESULT_POOL, and may be NULL
1017 if the property does not exist (note: "href" always exists).
1019 This function performs the request synchronously.
1021 Temporary allocations are made in SCRATCH_POOL. */
1023 svn_ra_serf__fetch_dav_prop(const char **value,
1024 svn_ra_serf__session_t *session,
1026 svn_revnum_t revision,
1027 const char *propname,
1028 apr_pool_t *result_pool,
1029 apr_pool_t *scratch_pool);
1031 /* Map a property name, as passed over the wire, into its corresponding
1032 Subversion-internal name. The returned name will be a static value,
1033 or allocated within RESULT_POOL.
1035 If the property should be ignored (eg. some DAV properties), then NULL
1036 will be returned. */
1038 svn_ra_serf__svnname_from_wirename(const char *ns,
1040 apr_pool_t *result_pool);
1042 /** MERGE-related functions **/
1045 svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens,
1047 serf_bucket_t *body,
1048 serf_bucket_alloc_t *alloc,
1051 /* Create an MERGE request aimed at the SESSION url, requesting the
1052 merge of the resource identified by MERGE_RESOURCE_URL.
1053 LOCK_TOKENS is a hash mapping paths to lock tokens owned by the
1054 client. If KEEP_LOCKS is set, instruct the server to not release
1055 locks set on the paths included in this commit. */
1057 svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
1058 svn_ra_serf__session_t *session,
1059 const char *merge_resource_url,
1060 apr_hash_t *lock_tokens,
1061 svn_boolean_t keep_locks,
1062 apr_pool_t *result_pool,
1063 apr_pool_t *scratch_pool);
1066 /** OPTIONS-related functions **/
1068 /* When running with a proxy, we may need to detect and correct for problems.
1069 This probing function will send a simple OPTIONS request to detect problems
1070 with the connection. */
1072 svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
1073 apr_pool_t *scratch_pool);
1076 /* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
1077 current youngest revnum, returning it in *YOUNGEST.
1079 (the revnum is headers of the OPTIONS response)
1081 This function performs the request synchronously.
1083 All temporary allocations will be made in SCRATCH_POOL. */
1085 svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
1086 svn_ra_serf__session_t *session,
1087 apr_pool_t *scratch_pool);
1090 /* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the
1091 activity collection set and return it in *ACTIVITY_URL, allocated
1094 (the activity-collection-set is in the body of the OPTIONS response)
1096 This function performs the request synchronously.
1098 All temporary allocations will be made in SCRATCH_POOL. */
1100 svn_ra_serf__v1_get_activity_collection(const char **activity_url,
1101 svn_ra_serf__session_t *session,
1102 apr_pool_t *result_pool,
1103 apr_pool_t *scratch_pool);
1106 /* Set @a VCC_URL to the default VCC for our repository based on @a
1107 * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and
1108 * repository root URLs are cached in @a SESSION.
1110 * All temporary allocations will be made in @a SCRATCH_POOL. */
1112 svn_ra_serf__discover_vcc(const char **vcc_url,
1113 svn_ra_serf__session_t *session,
1114 apr_pool_t *scratch_pool);
1116 /* Set @a REPORT_TARGET to the URI of the resource at which generic
1117 * (path-agnostic) REPORTs should be aimed for @a SESSION.
1119 * All temporary allocations will be made in @a POOL.
1122 svn_ra_serf__report_resource(const char **report_target,
1123 svn_ra_serf__session_t *session,
1126 /* Set @a REL_PATH to a path (not URI-encoded) relative to the root of
1127 * the repository pointed to by @a SESSION, based on original path
1128 * (URI-encoded) @a ORIG_PATH. Use @a CONN for any required network
1129 * communications if it is non-NULL; otherwise use the default
1130 * connection. Use POOL for allocations. */
1132 svn_ra_serf__get_relative_path(const char **rel_path,
1133 const char *orig_path,
1134 svn_ra_serf__session_t *session,
1138 /* Using the default connection in SESSION (conns[0]), get the youngest
1139 revnum from the server, returning it in *YOUNGEST.
1141 This function operates synchronously.
1143 All temporary allocations are performed in SCRATCH_POOL. */
1145 svn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest,
1146 svn_ra_serf__session_t *session,
1147 apr_pool_t *scratch_pool);
1150 /* Generate a revision-stable URL.
1152 The RA APIs all refer to user/public URLs that float along with the
1153 youngest revision. In many cases, we do NOT want to work with that URL
1154 since it can change from one moment to the next. Especially if we
1155 attempt to operation against multiple floating URLs -- we could end up
1156 referring to two separate revisions.
1158 The DAV RA provider(s) solve this by generating a URL that is specific
1159 to a revision by using a URL into a "baseline collection".
1161 For a specified SESSION, generate a revision-stable URL for URL at
1162 REVISION. If REVISION is SVN_INVALID_REVNUM, then the stable URL will
1163 refer to the youngest revision at the time this function was called.
1165 If URL is NULL, then the session root will be used.
1167 The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL.
1169 If LATEST_REVNUM is not NULL, then the revision used will be placed into
1170 *LATEST_REVNUM. That will be equal to youngest, or the given REVISION.
1172 This function operates synchronously, if any communication to the server
1173 is required. Communication is needed if REVISION is SVN_INVALID_REVNUM
1174 (to get the current youngest revnum), or if the specified REVISION is not
1175 (yet) in our cache of baseline collections.
1177 All temporary allocations are performed in SCRATCH_POOL. */
1179 svn_ra_serf__get_stable_url(const char **stable_url,
1180 svn_revnum_t *latest_revnum,
1181 svn_ra_serf__session_t *session,
1183 svn_revnum_t revision,
1184 apr_pool_t *result_pool,
1185 apr_pool_t *scratch_pool);
1188 /** RA functions **/
1190 /* Implements svn_ra__vtable_t.reparent(). */
1192 svn_ra_serf__reparent(svn_ra_session_t *ra_session,
1196 /* Implements svn_ra__vtable_t.rev_prop(). */
1198 svn_ra_serf__rev_prop(svn_ra_session_t *session,
1201 svn_string_t **value,
1204 /* Implements svn_ra__vtable_t.get_log(). */
1206 svn_ra_serf__get_log(svn_ra_session_t *session,
1207 const apr_array_header_t *paths,
1211 svn_boolean_t discover_changed_paths,
1212 svn_boolean_t strict_node_history,
1213 svn_boolean_t include_merged_revisions,
1214 const apr_array_header_t *revprops,
1215 svn_log_entry_receiver_t receiver,
1216 void *receiver_baton,
1219 /* Implements svn_ra__vtable_t.check_path(). */
1221 svn_ra_serf__check_path(svn_ra_session_t *ra_session,
1222 const char *rel_path,
1223 svn_revnum_t revision,
1224 svn_node_kind_t *kind,
1227 /* Implements svn_ra__vtable_t.stat(). */
1229 svn_ra_serf__stat(svn_ra_session_t *ra_session,
1230 const char *rel_path,
1231 svn_revnum_t revision,
1232 svn_dirent_t **dirent,
1235 /* Implements svn_ra__vtable_t.get_locations(). */
1237 svn_ra_serf__get_locations(svn_ra_session_t *session,
1238 apr_hash_t **locations,
1240 svn_revnum_t peg_revision,
1241 const apr_array_header_t *location_revisions,
1244 /* Implements svn_ra__vtable_t.get_location_segments(). */
1246 svn_ra_serf__get_location_segments(svn_ra_session_t *session,
1248 svn_revnum_t peg_revision,
1249 svn_revnum_t start_rev,
1250 svn_revnum_t end_rev,
1251 svn_location_segment_receiver_t receiver,
1252 void *receiver_baton,
1255 /* Implements svn_ra__vtable_t.do_diff(). */
1257 svn_ra_serf__do_diff(svn_ra_session_t *session,
1258 const svn_ra_reporter3_t **reporter,
1259 void **report_baton,
1260 svn_revnum_t revision,
1261 const char *diff_target,
1263 svn_boolean_t ignore_ancestry,
1264 svn_boolean_t text_deltas,
1265 const char *versus_url,
1266 const svn_delta_editor_t *diff_editor,
1270 /* Implements svn_ra__vtable_t.do_status(). */
1272 svn_ra_serf__do_status(svn_ra_session_t *ra_session,
1273 const svn_ra_reporter3_t **reporter,
1274 void **report_baton,
1275 const char *status_target,
1276 svn_revnum_t revision,
1278 const svn_delta_editor_t *status_editor,
1282 /* Implements svn_ra__vtable_t.do_update(). */
1284 svn_ra_serf__do_update(svn_ra_session_t *ra_session,
1285 const svn_ra_reporter3_t **reporter,
1286 void **report_baton,
1287 svn_revnum_t revision_to_update_to,
1288 const char *update_target,
1290 svn_boolean_t send_copyfrom_args,
1291 svn_boolean_t ignore_ancestry,
1292 const svn_delta_editor_t *update_editor,
1294 apr_pool_t *result_pool,
1295 apr_pool_t *scratch_pool);
1297 /* Implements svn_ra__vtable_t.do_switch(). */
1299 svn_ra_serf__do_switch(svn_ra_session_t *ra_session,
1300 const svn_ra_reporter3_t **reporter,
1301 void **report_baton,
1302 svn_revnum_t revision_to_switch_to,
1303 const char *switch_target,
1305 const char *switch_url,
1306 svn_boolean_t send_copyfrom_args,
1307 svn_boolean_t ignore_ancestry,
1308 const svn_delta_editor_t *switch_editor,
1310 apr_pool_t *result_pool,
1311 apr_pool_t *scratch_pool);
1313 /* Implements svn_ra__vtable_t.get_file_revs(). */
1315 svn_ra_serf__get_file_revs(svn_ra_session_t *session,
1319 svn_boolean_t include_merged_revisions,
1320 svn_file_rev_handler_t handler,
1321 void *handler_baton,
1324 /* Implements svn_ra__vtable_t.get_dated_revision(). */
1326 svn_ra_serf__get_dated_revision(svn_ra_session_t *session,
1327 svn_revnum_t *revision,
1331 /* Implements svn_ra__vtable_t.get_commit_editor().
1333 * Note: Like other commit editors, the returned editor requires that the
1334 * @c copyfrom_path parameter passed to its @c add_file and @c add_directory
1335 * methods is a URL, not a relative path.
1338 svn_ra_serf__get_commit_editor(svn_ra_session_t *session,
1339 const svn_delta_editor_t **editor,
1341 apr_hash_t *revprop_table,
1342 svn_commit_callback2_t callback,
1343 void *callback_baton,
1344 apr_hash_t *lock_tokens,
1345 svn_boolean_t keep_locks,
1348 /* Implements svn_ra__vtable_t.get_file(). */
1350 svn_ra_serf__get_file(svn_ra_session_t *session,
1352 svn_revnum_t revision,
1353 svn_stream_t *stream,
1354 svn_revnum_t *fetched_rev,
1358 /* Implements svn_ra__vtable_t.get_dir(). */
1360 svn_ra_serf__get_dir(svn_ra_session_t *ra_session,
1361 apr_hash_t **dirents,
1362 svn_revnum_t *fetched_rev,
1363 apr_hash_t **ret_props,
1364 const char *rel_path,
1365 svn_revnum_t revision,
1366 apr_uint32_t dirent_fields,
1367 apr_pool_t *result_pool);
1369 /* Implements svn_ra__vtable_t.change_rev_prop(). */
1371 svn_ra_serf__change_rev_prop(svn_ra_session_t *session,
1374 const svn_string_t *const *old_value_p,
1375 const svn_string_t *value,
1378 /* Implements svn_ra__vtable_t.replay(). */
1380 svn_ra_serf__replay(svn_ra_session_t *ra_session,
1381 svn_revnum_t revision,
1382 svn_revnum_t low_water_mark,
1383 svn_boolean_t text_deltas,
1384 const svn_delta_editor_t *editor,
1388 /* Implements svn_ra__vtable_t.replay_range(). */
1390 svn_ra_serf__replay_range(svn_ra_session_t *ra_session,
1391 svn_revnum_t start_revision,
1392 svn_revnum_t end_revision,
1393 svn_revnum_t low_water_mark,
1394 svn_boolean_t send_deltas,
1395 svn_ra_replay_revstart_callback_t revstart_func,
1396 svn_ra_replay_revfinish_callback_t revfinish_func,
1400 /* Implements svn_ra__vtable_t.lock(). */
1402 svn_ra_serf__lock(svn_ra_session_t *ra_session,
1403 apr_hash_t *path_revs,
1404 const char *comment,
1405 svn_boolean_t force,
1406 svn_ra_lock_callback_t lock_func,
1410 /* Implements svn_ra__vtable_t.unlock(). */
1412 svn_ra_serf__unlock(svn_ra_session_t *ra_session,
1413 apr_hash_t *path_tokens,
1414 svn_boolean_t force,
1415 svn_ra_lock_callback_t lock_func,
1419 /* Implements svn_ra__vtable_t.get_lock(). */
1421 svn_ra_serf__get_lock(svn_ra_session_t *ra_session,
1426 /* Implements svn_ra__vtable_t.get_locks(). */
1428 svn_ra_serf__get_locks(svn_ra_session_t *ra_session,
1434 /* Implements svn_ra__vtable_t.list(). */
1436 svn_ra_serf__list(svn_ra_session_t *ra_session,
1438 svn_revnum_t revision,
1439 const apr_array_header_t *patterns,
1441 apr_uint32_t dirent_fields,
1442 svn_ra_dirent_receiver_t receiver,
1443 void *receiver_baton,
1444 apr_pool_t *scratch_pool);
1446 /* Request a mergeinfo-report from the URL attached to SESSION,
1447 and fill in the MERGEINFO hash with the results.
1449 Implements svn_ra__vtable_t.get_mergeinfo().
1452 svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
1453 apr_hash_t **mergeinfo,
1454 const apr_array_header_t *paths,
1455 svn_revnum_t revision,
1456 svn_mergeinfo_inheritance_t inherit,
1457 svn_boolean_t include_descendants,
1460 /* Exchange capabilities with the server, by sending an OPTIONS
1461 * request announcing the client's capabilities, and by filling
1462 * SERF_SESS->capabilities with the server's capabilities as read from
1463 * the response headers. Use POOL only for temporary allocation.
1465 * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to
1466 * report a server-dictated redirect or relocation (HTTP 301 or 302
1467 * error codes), setting *CORRECTED_URL to the value of the corrected
1468 * repository URL. Otherwise, such responses from the server will
1469 * generate an error. (In either case, no capabilities are exchanged
1470 * if there is, in fact, such a response from the server.)
1473 svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess,
1474 const char **corrected_url,
1475 apr_pool_t *result_pool,
1476 apr_pool_t *scratch_pool);
1478 /* Implements svn_ra__vtable_t.has_capability(). */
1480 svn_ra_serf__has_capability(svn_ra_session_t *ra_session,
1482 const char *capability,
1485 /* Implements svn_ra__vtable_t.get_deleted_rev(). */
1487 svn_ra_serf__get_deleted_rev(svn_ra_session_t *session,
1489 svn_revnum_t peg_revision,
1490 svn_revnum_t end_revision,
1491 svn_revnum_t *revision_deleted,
1494 /* Implements the get_inherited_props RA layer function. */
1495 svn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session,
1496 apr_array_header_t **iprops,
1498 svn_revnum_t revision,
1499 apr_pool_t *result_pool,
1500 apr_pool_t *scratch_pool);
1502 /* Implements svn_ra__vtable_t.get_repos_root(). */
1504 svn_ra_serf__get_repos_root(svn_ra_session_t *ra_session,
1508 /* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */
1510 svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
1511 svn_delta_shim_callbacks_t *callbacks);
1513 /*** Authentication handler declarations ***/
1516 * Callback function that loads the credentials for Basic and Digest
1517 * authentications, both for server and proxy authentication.
1520 svn_ra_serf__credentials_callback(char **username, char **password,
1521 serf_request_t *request, void *baton,
1522 int code, const char *authn_type,
1527 /*** General utility functions ***/
1530 * Convert an HTTP STATUS_CODE resulting from a WebDAV request against
1531 * PATH to the relevant error code. Use the response-supplied LOCATION
1532 * where it necessary.
1534 * Returns SVN_NO_ERROR if sline doesn't specify an error condition
1537 svn_ra_serf__error_on_status(serf_status_line sline,
1539 const char *location);
1542 * Convert an unexpected HTTP STATUS_CODE from a request to the relevant error
1543 * code. Unlike svn_ra_serf__error_on_status() this function creates an error
1547 svn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler);
1549 /* Make sure handler is no longer scheduled on its connection. Resetting
1550 the connection if necessary */
1552 svn_ra_serf__unschedule_handler(svn_ra_serf__handler_t *handler);
1557 svn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf,
1559 apr_pool_t *result_pool,
1560 apr_pool_t *scratch_pool);
1564 svn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf,
1565 serf_bucket_alloc_t *allocator,
1566 apr_pool_t *result_pool,
1567 apr_pool_t *scratch_pool);
1569 /** Wrap STATUS from an serf function. If STATUS is not serf error code,
1570 * this is equivalent to svn_error_wrap_apr().
1573 svn_ra_serf__wrap_err(apr_status_t status,
1577 /* Create a bucket that just returns DATA (with length LEN) and then returns
1578 the APR_EAGAIN status */
1580 svn_ra_serf__create_bucket_with_eagain(const char *data,
1582 serf_bucket_alloc_t *allocator);
1584 /* Parse a given URL_STR, fill in all supplied fields of URI
1587 * This function is a compatibility wrapper around apr_uri_parse().
1588 * Different apr-util versions set apr_uri_t.path to either NULL or ""
1589 * for root paths, and serf expects to see "/". This function always
1590 * sets URI.path to "/" for these paths. */
1592 svn_ra_serf__uri_parse(apr_uri_t *uri,
1593 const char *url_str,
1594 apr_pool_t *result_pool);
1596 /* Setup the "Accept-Encoding" header value for requests that expect
1597 svndiff-encoded deltas, depending on the SESSION state. */
1599 svn_ra_serf__setup_svndiff_accept_encoding(serf_bucket_t *headers,
1600 svn_ra_serf__session_t *session);
1603 svn_ra_serf__is_low_latency_connection(svn_ra_serf__session_t *session);
1605 /* Return an APR array of svn_ra_serf__dav_props_t containing the
1606 * properties (names and namespaces) corresponding to the flegs set
1607 * in DIRENT_FIELDS. If SESSION does not support deadprops, only
1608 * the generic "DAV:allprop" will be returned. Allocate the result
1609 * in RESULT_POOL. */
1610 apr_array_header_t *
1611 svn_ra_serf__get_dirent_props(apr_uint32_t dirent_fields,
1612 svn_ra_serf__session_t *session,
1613 apr_pool_t *result_pool);
1615 /* Default limit for in-memory size of a request body. */
1616 #define SVN_RA_SERF__REQUEST_BODY_IN_MEM_SIZE 256 * 1024
1618 /* An opaque structure used to prepare a request body. */
1619 typedef struct svn_ra_serf__request_body_t svn_ra_serf__request_body_t;
1621 /* Constructor for svn_ra_serf__request_body_t. Creates a new writable
1622 buffer for the request body. Request bodies under IN_MEMORY_SIZE
1623 bytes will be held in memory, otherwise, the body content will be
1624 spilled to a temporary file. */
1625 svn_ra_serf__request_body_t *
1626 svn_ra_serf__request_body_create(apr_size_t in_memory_size,
1627 apr_pool_t *result_pool);
1629 /* Get the writable stream associated with BODY. */
1631 svn_ra_serf__request_body_get_stream(svn_ra_serf__request_body_t *body);
1633 /* Get a svn_ra_serf__request_body_delegate_t and baton for BODY. */
1635 svn_ra_serf__request_body_get_delegate(svn_ra_serf__request_body_delegate_t *del,
1637 svn_ra_serf__request_body_t *body);
1639 /* Release intermediate resources associated with BODY. These resources
1640 (such as open file handles) will be automatically released when the
1641 pool used to construct BODY is cleared or destroyed, but this optional
1642 function allows doing that explicitly. */
1644 svn_ra_serf__request_body_cleanup(svn_ra_serf__request_body_t *body,
1645 apr_pool_t *scratch_pool);
1647 /* Callback used in svn_ra_serf__create_stream_bucket(). ERR will be
1648 will be cleared and becomes invalid after the callback returns,
1649 use svn_error_dup() to preserve it. */
1651 (*svn_ra_serf__stream_bucket_errfunc_t)(void *baton, svn_error_t *err);
1653 /* Create a bucket that wraps a generic readable STREAM. This function
1654 takes ownership of the passed-in stream, and will close it. */
1656 svn_ra_serf__create_stream_bucket(svn_stream_t *stream,
1657 serf_bucket_alloc_t *allocator,
1658 svn_ra_serf__stream_bucket_errfunc_t errfunc,
1659 void *errfunc_baton);
1661 #if defined(SVN_DEBUG)
1662 /* Wrapper macros to collect file and line information */
1663 #define svn_ra_serf__wrap_err \
1664 (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err))
1670 #endif /* __cplusplus */
1672 #endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */