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