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