ra_serf.h revision 251881
1/* 2 * ra_serf.h : Private declarations for the Serf-based DAV RA module. 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24#ifndef SVN_LIBSVN_RA_SERF_RA_SERF_H 25#define SVN_LIBSVN_RA_SERF_RA_SERF_H 26 27 28#include <serf.h> 29#include <expat.h> /* for XML_Parser */ 30#include <apr_uri.h> 31 32#include "svn_types.h" 33#include "svn_string.h" 34#include "svn_pools.h" 35#include "svn_ra.h" 36#include "svn_delta.h" 37#include "svn_version.h" 38#include "svn_dav.h" 39#include "svn_dirent_uri.h" 40 41#include "private/svn_dav_protocol.h" 42#include "private/svn_subr_private.h" 43#include "private/svn_editor.h" 44 45#include "blncache.h" 46 47#ifdef __cplusplus 48extern "C" { 49#endif /* __cplusplus */ 50 51 52/* Enforce the minimum version of serf. */ 53#if !SERF_VERSION_AT_LEAST(1, 2, 1) 54#error Please update your version of serf to at least 1.2.1. 55#endif 56 57/** Use this to silence compiler warnings about unused parameters. */ 58#define UNUSED_CTX(x) ((void)(x)) 59 60/** Our User-Agent string. */ 61#define USER_AGENT "SVN/" SVN_VER_NUMBER " (" SVN_BUILD_TARGET ")" \ 62 " serf/" \ 63 APR_STRINGIFY(SERF_MAJOR_VERSION) "." \ 64 APR_STRINGIFY(SERF_MINOR_VERSION) "." \ 65 APR_STRINGIFY(SERF_PATCH_VERSION) 66 67/** Wait duration (in microseconds) used in calls to serf_context_run() */ 68#define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000 69 70 71 72/* Forward declarations. */ 73typedef struct svn_ra_serf__session_t svn_ra_serf__session_t; 74 75/* A serf connection and optionally associated SSL context. */ 76typedef struct svn_ra_serf__connection_t { 77 /* Our connection to a server. */ 78 serf_connection_t *conn; 79 80 /* Bucket allocator for this connection. */ 81 serf_bucket_alloc_t *bkt_alloc; 82 83 /* Collected cert failures in chain. */ 84 int server_cert_failures; 85 86 /* What was the last HTTP status code we got on this connection? */ 87 int last_status_code; 88 89 /* Optional SSL context for this connection. */ 90 serf_ssl_context_t *ssl_context; 91 svn_auth_iterstate_t *ssl_client_auth_state; 92 svn_auth_iterstate_t *ssl_client_pw_auth_state; 93 94 svn_ra_serf__session_t *session; 95 96} svn_ra_serf__connection_t; 97 98/** Maximum value we'll allow for the http-max-connections config option. 99 * 100 * Note: minimum 2 connections are required for ra_serf to function 101 * correctly! 102 */ 103#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8 104 105/* 106 * The master serf RA session. 107 * 108 * This is stored in the ra session ->priv field. 109 */ 110struct svn_ra_serf__session_t { 111 /* Pool for allocations during this session */ 112 apr_pool_t *pool; 113 114 /* The current context */ 115 serf_context_t *context; 116 117 /* The maximum number of connections we'll use for parallelized 118 fetch operations (updates, etc.) */ 119 apr_int64_t max_connections; 120 121 /* Are we using ssl */ 122 svn_boolean_t using_ssl; 123 124 /* Should we ask for compressed responses? */ 125 svn_boolean_t using_compression; 126 127 /* The user agent string */ 128 const char *useragent; 129 130 /* The current connection */ 131 svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT]; 132 int num_conns; 133 int cur_conn; 134 135 /* The URL that was passed into _open() */ 136 apr_uri_t session_url; 137 const char *session_url_str; 138 139 /* The actual discovered root; may be NULL until we know it. */ 140 apr_uri_t repos_root; 141 const char *repos_root_str; 142 143 /* The server is not Apache/mod_dav_svn (directly) and only supports 144 HTTP/1.0. Thus, we cannot send chunked requests. */ 145 svn_boolean_t http10; 146 147 /* Our Version-Controlled-Configuration; may be NULL until we know it. */ 148 const char *vcc_url; 149 150 /* Authentication related properties. */ 151 svn_auth_iterstate_t *auth_state; 152 int auth_attempts; 153 154 /* Callback functions to get info from WC */ 155 const svn_ra_callbacks2_t *wc_callbacks; 156 void *wc_callback_baton; 157 158 /* Callback function to send progress info to the client */ 159 svn_ra_progress_notify_func_t progress_func; 160 void *progress_baton; 161 162 /* Callback function to handle cancellation */ 163 svn_cancel_func_t cancel_func; 164 void *cancel_baton; 165 166 /* Ev2 shim callbacks */ 167 svn_delta_shim_callbacks_t *shim_callbacks; 168 169 /* Error that we've received but not yet returned upstream. */ 170 svn_error_t *pending_error; 171 172 /* List of authn types supported by the client.*/ 173 int authn_types; 174 175 /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values. 176 If a capability is not yet discovered, it is absent from the table. 177 The table itself is allocated in the svn_ra_serf__session_t's pool; 178 keys and values must have at least that lifetime. Most likely 179 the keys and values are constants anyway (and sufficiently 180 well-informed internal code may just compare against those 181 constants' addresses, therefore). */ 182 apr_hash_t *capabilities; 183 184 /* Activity collection URL. (Cached from the initial OPTIONS 185 request when run against HTTPv1 servers.) */ 186 const char *activity_collection_url; 187 188 /* Are we using a proxy? */ 189 int using_proxy; 190 191 const char *proxy_username; 192 const char *proxy_password; 193 int proxy_auth_attempts; 194 195 /* SSL server certificates */ 196 svn_boolean_t trust_default_ca; 197 const char *ssl_authorities; 198 199 /* Repository UUID */ 200 const char *uuid; 201 202 /* Connection timeout value */ 203 apr_interval_time_t timeout; 204 205 /* HTTPv1 flags */ 206 svn_tristate_t supports_deadprop_count; 207 208 /*** HTTP v2 protocol stuff. *** 209 * 210 * We assume that if mod_dav_svn sends one of the special v2 OPTIONs 211 * response headers, it has sent all of them. Specifically, we'll 212 * be looking at the presence of the "me resource" as a flag that 213 * the server supports v2 of our HTTP protocol. 214 */ 215 216 /* The "me resource". Typically used as a target for REPORTs that 217 are path-agnostic. If we have this, we can speak HTTP v2 to the 218 server. */ 219 const char *me_resource; 220 221 /* Opaque URL "stubs". If the OPTIONS response returns these, then 222 we know we're using HTTP protocol v2. */ 223 const char *rev_stub; /* for accessing revisions (i.e. revprops) */ 224 const char *rev_root_stub; /* for accessing REV/PATH pairs */ 225 const char *txn_stub; /* for accessing transactions (i.e. txnprops) */ 226 const char *txn_root_stub; /* for accessing TXN/PATH pairs */ 227 const char *vtxn_stub; /* for accessing transactions (i.e. txnprops) */ 228 const char *vtxn_root_stub; /* for accessing TXN/PATH pairs */ 229 230 /* Hash mapping const char * server-supported POST types to 231 disinteresting-but-non-null values. */ 232 apr_hash_t *supported_posts; 233 234 /*** End HTTP v2 stuff ***/ 235 236 svn_ra_serf__blncache_t *blncache; 237 238 /* Trisate flag that indicates user preference for using bulk updates 239 (svn_tristate_true) with all the properties and content in the 240 update-report response. If svn_tristate_false, request a skelta 241 update-report with inlined properties. If svn_tristate_unknown then use 242 server preference. */ 243 svn_tristate_t bulk_updates; 244 245 /* Indicates if the server wants bulk update requests (Prefer) or only 246 accepts skelta requests (Off). If this value is On both options are 247 allowed. */ 248 const char *server_allows_bulk; 249 250 /* Indicates if the server supports sending inlined props in update editor 251 * in skelta mode (send-all == 'false'). */ 252 svn_boolean_t supports_inline_props; 253 254 /* Indicates whether the server supports issuing replay REPORTs 255 against rev resources (children of `rev_stub', elsestruct). */ 256 svn_boolean_t supports_rev_rsrc_replay; 257}; 258 259#define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL) 260 261/* 262 * Structure which represents a DAV element with a NAMESPACE and NAME. 263 */ 264typedef struct svn_ra_serf__dav_props_t { 265 /* Element namespace */ 266 const char *namespace; 267 /* Element name */ 268 const char *name; 269} svn_ra_serf__dav_props_t; 270 271/* 272 * Structure which represents an XML namespace. 273 */ 274typedef struct ns_t { 275 /* The assigned name. */ 276 const char *namespace; 277 /* The full URL for this namespace. */ 278 const char *url; 279 /* The next namespace in our list. */ 280 struct ns_t *next; 281} svn_ra_serf__ns_t; 282 283/* 284 * An incredibly simple list. 285 */ 286typedef struct ra_serf_list_t { 287 void *data; 288 struct ra_serf_list_t *next; 289} svn_ra_serf__list_t; 290 291/** DAV property sets **/ 292 293static const svn_ra_serf__dav_props_t base_props[] = 294{ 295 { "DAV:", "version-controlled-configuration" }, 296 { "DAV:", "resourcetype" }, 297 { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" }, 298 { SVN_DAV_PROP_NS_DAV, "repository-uuid" }, 299 { NULL } 300}; 301 302static const svn_ra_serf__dav_props_t checked_in_props[] = 303{ 304 { "DAV:", "checked-in" }, 305 { NULL } 306}; 307 308static const svn_ra_serf__dav_props_t baseline_props[] = 309{ 310 { "DAV:", "baseline-collection" }, 311 { "DAV:", SVN_DAV__VERSION_NAME }, 312 { NULL } 313}; 314 315static const svn_ra_serf__dav_props_t all_props[] = 316{ 317 { "DAV:", "allprop" }, 318 { NULL } 319}; 320 321static const svn_ra_serf__dav_props_t check_path_props[] = 322{ 323 { "DAV:", "resourcetype" }, 324 { NULL } 325}; 326 327static const svn_ra_serf__dav_props_t type_and_checksum_props[] = 328{ 329 { "DAV:", "resourcetype" }, 330 { SVN_DAV_PROP_NS_DAV, "sha1-checksum" }, 331 { NULL } 332}; 333 334/* WC props compatibility with ra_neon. */ 335#define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url" 336 337/** Serf utility functions **/ 338 339apr_status_t 340svn_ra_serf__conn_setup(apr_socket_t *sock, 341 serf_bucket_t **read_bkt, 342 serf_bucket_t **write_bkt, 343 void *baton, 344 apr_pool_t *pool); 345 346void 347svn_ra_serf__conn_closed(serf_connection_t *conn, 348 void *closed_baton, 349 apr_status_t why, 350 apr_pool_t *pool); 351 352 353/* Helper function to provide SSL client certificates. 354 * 355 * NOTE: This function sets the session's 'pending_error' member when 356 * returning an non-success status. 357 */ 358apr_status_t 359svn_ra_serf__handle_client_cert(void *data, 360 const char **cert_path); 361 362/* Helper function to provide SSL client certificate passwords. 363 * 364 * NOTE: This function sets the session's 'pending_error' member when 365 * returning an non-success status. 366 */ 367apr_status_t 368svn_ra_serf__handle_client_cert_pw(void *data, 369 const char *cert_path, 370 const char **password); 371 372 373/* 374 * This function will run the serf context in SESS until *DONE is TRUE. 375 */ 376svn_error_t * 377svn_ra_serf__context_run_wait(svn_boolean_t *done, 378 svn_ra_serf__session_t *sess, 379 apr_pool_t *scratch_pool); 380 381/* Callback for response handlers */ 382typedef svn_error_t * 383(*svn_ra_serf__response_handler_t)(serf_request_t *request, 384 serf_bucket_t *response, 385 void *handler_baton, 386 apr_pool_t *scratch_pool); 387 388/* Callback for when a request body is needed. */ 389/* ### should pass a scratch_pool */ 390typedef svn_error_t * 391(*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt, 392 void *baton, 393 serf_bucket_alloc_t *alloc, 394 apr_pool_t *request_pool); 395 396/* Callback for when request headers are needed. */ 397/* ### should pass a scratch_pool */ 398typedef svn_error_t * 399(*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers, 400 void *baton, 401 apr_pool_t *request_pool); 402 403/* Callback for when a response has an error. */ 404typedef svn_error_t * 405(*svn_ra_serf__response_error_t)(serf_request_t *request, 406 serf_bucket_t *response, 407 int status_code, 408 void *baton); 409 410/* ### we should reorder the types in this file. */ 411typedef struct svn_ra_serf__server_error_t svn_ra_serf__server_error_t; 412 413/* 414 * Structure that can be passed to our default handler to guide the 415 * execution of the request through its lifecycle. 416 */ 417typedef struct svn_ra_serf__handler_t { 418 /* The HTTP method string of the request */ 419 const char *method; 420 421 /* The resource to the execute the method on. */ 422 const char *path; 423 424 /* The content-type of the request body. */ 425 const char *body_type; 426 427 /* If TRUE then default Accept-Encoding request header is not configured for 428 request. If FALSE then 'gzip' accept encoding will be used if compression 429 enabled. */ 430 svn_boolean_t custom_accept_encoding; 431 432 /* Has the request/response been completed? */ 433 svn_boolean_t done; 434 435 /* If we captured an error from the server, then this will be non-NULL. 436 It will be allocated from HANDLER_POOL. */ 437 svn_ra_serf__server_error_t *server_error; 438 439 /* The handler and baton pair for our handler. */ 440 svn_ra_serf__response_handler_t response_handler; 441 void *response_baton; 442 443 /* When REPONSE_HANDLER is invoked, the following fields will be set 444 based on the response header. HANDLER_POOL must be non-NULL for these 445 values to be filled in. SLINE.REASON and LOCATION will be allocated 446 within HANDLER_POOL. */ 447 serf_status_line sline; /* The parsed Status-Line */ 448 const char *location; /* The Location: header, if any */ 449 450 /* The handler and baton pair to be executed when a non-recoverable error 451 * is detected. If it is NULL in the presence of an error, an abort() may 452 * be triggered. 453 */ 454 svn_ra_serf__response_error_t response_error; 455 void *response_error_baton; 456 457 /* This function and baton pair allows for custom request headers to 458 * be set. 459 * 460 * It will be executed after the request has been set up but before it is 461 * delivered. 462 */ 463 svn_ra_serf__request_header_delegate_t header_delegate; 464 void *header_delegate_baton; 465 466 /* This function and baton pair allows a body to be created right before 467 * delivery. 468 * 469 * It will be executed after the request has been set up but before it is 470 * delivered. 471 * 472 * May be NULL if there is no body to send. 473 * 474 */ 475 svn_ra_serf__request_body_delegate_t body_delegate; 476 void *body_delegate_baton; 477 478 /* The connection and session to be used for this request. */ 479 svn_ra_serf__connection_t *conn; 480 svn_ra_serf__session_t *session; 481 482 /* Internal flag to indicate we've parsed the headers. */ 483 svn_boolean_t reading_body; 484 485 /* When this flag will be set, the core handler will discard any unread 486 portion of the response body. The registered response handler will 487 no longer be called. */ 488 svn_boolean_t discard_body; 489 490 /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL, 491 then the requestor does not care about SLINE and LOCATION. */ 492 apr_pool_t *handler_pool; 493 494} svn_ra_serf__handler_t; 495 496 497/* Run one request and process the response. 498 499 Similar to context_run_wait(), but this creates the request for HANDLER 500 and then waits for it to complete. 501 502 WARNING: context_run_wait() does NOT create a request, whereas this 503 function DOES. Avoid a double-create. */ 504svn_error_t * 505svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler, 506 apr_pool_t *scratch_pool); 507 508 509/* 510 * Helper function to queue a request in the @a handler's connection. 511 */ 512void svn_ra_serf__request_create(svn_ra_serf__handler_t *handler); 513 514/* XML helper callbacks. */ 515 516typedef struct svn_ra_serf__xml_state_t { 517 /* A numeric value that represents the current state in parsing. 518 * 519 * Value 0 is reserved for use as the default state. 520 */ 521 int current_state; 522 523 /* Private pointer set by the parsing code. */ 524 void *private; 525 526 /* Allocations should be made in this pool to match the lifetime of the 527 * state. 528 */ 529 apr_pool_t *pool; 530 531 /* The currently-declared namespace for this state. */ 532 svn_ra_serf__ns_t *ns_list; 533 534 /* Our previous states. */ 535 struct svn_ra_serf__xml_state_t *prev; 536} svn_ra_serf__xml_state_t; 537 538/* Forward declaration of the XML parser structure. */ 539typedef struct svn_ra_serf__xml_parser_t svn_ra_serf__xml_parser_t; 540 541/* Callback invoked with @a baton by our XML @a parser when an element with 542 * the @a name containing @a attrs is opened. 543 */ 544typedef svn_error_t * 545(*svn_ra_serf__xml_start_element_t)(svn_ra_serf__xml_parser_t *parser, 546 svn_ra_serf__dav_props_t name, 547 const char **attrs, 548 apr_pool_t *scratch_pool); 549 550/* Callback invoked with @a baton by our XML @a parser when an element with 551 * the @a name is closed. 552 */ 553typedef svn_error_t * 554(*svn_ra_serf__xml_end_element_t)(svn_ra_serf__xml_parser_t *parser, 555 svn_ra_serf__dav_props_t name, 556 apr_pool_t *scratch_pool); 557 558/* Callback invoked with @a baton by our XML @a parser when a CDATA portion 559 * of @a data with size @a len is encountered. 560 * 561 * This may be invoked multiple times for the same tag. 562 */ 563typedef svn_error_t * 564(*svn_ra_serf__xml_cdata_chunk_handler_t)(svn_ra_serf__xml_parser_t *parser, 565 const char *data, 566 apr_size_t len, 567 apr_pool_t *scratch_pool); 568 569/* 570 * Helper structure associated with handle_xml_parser handler that will 571 * specify how an XML response will be processed. 572 */ 573struct svn_ra_serf__xml_parser_t { 574 /* Temporary allocations should be made in this pool. */ 575 apr_pool_t *pool; 576 577 /* What kind of response are we parsing? If set, this should typically 578 define the report name. */ 579 const char *response_type; 580 581 /* Caller-specific data passed to the start, end, cdata callbacks. */ 582 void *user_data; 583 584 /* Callback invoked when a tag is opened. */ 585 svn_ra_serf__xml_start_element_t start; 586 587 /* Callback invoked when a tag is closed. */ 588 svn_ra_serf__xml_end_element_t end; 589 590 /* Callback invoked when a cdata chunk is received. */ 591 svn_ra_serf__xml_cdata_chunk_handler_t cdata; 592 593 /* Our associated expat-based XML parser. */ 594 XML_Parser xmlp; 595 596 /* Our current state. */ 597 svn_ra_serf__xml_state_t *state; 598 599 /* Our previously used states (will be reused). */ 600 svn_ra_serf__xml_state_t *free_state; 601 602 /* If non-NULL, this value will be set to TRUE when the response is 603 * completed. 604 */ 605 svn_boolean_t *done; 606 607 /* If non-NULL, when this parser completes, it will add done_item to 608 * the list. 609 */ 610 svn_ra_serf__list_t **done_list; 611 612 /* A pointer to the item that will be inserted into the list upon 613 * completeion. 614 */ 615 svn_ra_serf__list_t *done_item; 616 617 /* If this flag is TRUE, errors during parsing will be ignored. 618 * 619 * This is mainly used when we are processing an error XML response to 620 * avoid infinite loops. 621 */ 622 svn_boolean_t ignore_errors; 623 624 /* If an error occurred, this value will be non-NULL. */ 625 svn_error_t *error; 626 627 /* Deciding whether to pause, or not, is performed within the parsing 628 callbacks. If a callback decides to set this flag, then the loop 629 driving the parse (generally, a series of calls to serf_context_run()) 630 is going to need to coordinate the un-pausing of the parser by 631 processing pending content. Thus, deciding to pause the parser is a 632 coordinate effort rather than merely setting this flag. 633 634 When an XML parsing callback sets this flag, note that additional 635 elements may be parsed (as the current buffer is consumed). At some 636 point, the flag will be recognized and arriving network content will 637 be stashed away in the PENDING structure (see below). 638 639 At some point, the controlling loop should clear this value. The 640 underlying network processing will note the change and begin passing 641 content into the XML callbacks. 642 643 Note that the controlling loop should also process pending content 644 since the arriving network content will typically finish first. */ 645 svn_boolean_t paused; 646 647 /* While the XML parser is paused, content arriving from the server 648 must be saved locally. We cannot stop reading, or the server may 649 decide to drop the connection. The content will be stored in memory 650 up to a certain limit, and will then be spilled over to disk. 651 652 See libsvn_ra_serf/util.c */ 653 struct svn_ra_serf__pending_t *pending; 654 655 /* Response restart support */ 656 const void *headers_baton; /* Last pointer to headers */ 657 apr_off_t skip_size; /* Number of bytes to skip */ 658 apr_off_t read_size; /* Number of bytes read from response */ 659}; 660 661 662/* v2 of the XML parsing functions */ 663 664/* The XML parsing context. */ 665typedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t; 666 667 668/* An opaque structure for the XML parse element/state. */ 669typedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t; 670 671/* Called just after the parser moves into ENTERED_STATE. The tag causing 672 the transition is passed in TAG. 673 674 This callback is applied to a parsing context by using the 675 svn_ra_serf__xml_context_customize() function. 676 677 NOTE: this callback, when set, will be invoked on *every* transition. 678 The callback must examine ENTERED_STATE to determine if any action 679 must be taken. The original state is not provided, but must be derived 680 from ENTERED_STATE and/or the TAG causing the transition (if needed). */ 681typedef svn_error_t * 682(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes, 683 void *baton, 684 int entered_state, 685 const svn_ra_serf__dav_props_t *tag, 686 apr_pool_t *scratch_pool); 687 688 689/* Called just before the parser leaves LEAVING_STATE. 690 691 If cdata collection was enabled for this state, then CDATA will be 692 non-NULL and contain the collected cdata. 693 694 If attribute collection was enabled for this state, then ATTRS will 695 contain the attributes collected for this element only, along with 696 any values stored via svn_ra_serf__xml_note(). 697 698 Use svn_ra_serf__xml_gather_since() to gather up data from outer states. 699 700 ATTRS is char* -> char*. 701 702 Temporary allocations may be made in SCRATCH_POOL. */ 703typedef svn_error_t * 704(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes, 705 void *baton, 706 int leaving_state, 707 const svn_string_t *cdata, 708 apr_hash_t *attrs, 709 apr_pool_t *scratch_pool); 710 711 712/* Called for all states that are not using the builtin cdata collection. 713 This callback is (only) appropriate for unbounded-size cdata content. 714 715 CURRENT_STATE may be used to decide what to do with the data. 716 717 Temporary allocations may be made in SCRATCH_POOL. */ 718typedef svn_error_t * 719(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes, 720 void *baton, 721 int current_state, 722 const char *data, 723 apr_size_t len, 724 apr_pool_t *scratch_pool); 725 726 727/* State transition table. 728 729 When the XML Context is constructed, it is in state 0. User states are 730 positive integers. 731 732 In a list of transitions, use { 0 } to indicate the end. Specifically, 733 the code looks for NS == NULL. 734 735 ### more docco 736*/ 737typedef struct svn_ra_serf__xml_transition_t { 738 /* This transition applies when in this state */ 739 int from_state; 740 741 /* And when this tag is observed */ 742 const char *ns; 743 const char *name; 744 745 /* Moving to this state */ 746 int to_state; 747 748 /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should 749 be TRUE in order to capture this cdata. */ 750 svn_boolean_t collect_cdata; 751 752 /* Which attributes of NAME should be collected? Terminate with NULL. 753 Maximum of 10 attributes may be collected. Note that attribute 754 namespaces are ignored at this time. 755 756 Attribute names beginning with "?" are optional. Other names must 757 exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised. */ 758 const char *collect_attrs[11]; 759 760 /* When NAME is closed, should the callback be invoked? */ 761 svn_boolean_t custom_close; 762 763} svn_ra_serf__xml_transition_t; 764 765 766/* Construct an XML parsing context, based on the TTABLE transition table. 767 As content is parsed, the CLOSED_CB callback will be invoked according 768 to the definition in the table. 769 770 If OPENED_CB is not NULL, then it will be invoked for *every* tag-open 771 event. The callback will need to use the ENTERED_STATE and TAG parameters 772 to decide what it would like to do. 773 774 If CDATA_CB is not NULL, then it will be called for all cdata that is 775 not be automatically collected (based on the transition table record's 776 COLLECT_CDATA flag). It will be called in every state, so the callback 777 must examine the CURRENT_STATE parameter to decide what to do. 778 779 The same BATON value will be passed to all three callbacks. 780 781 The context will be created within RESULT_POOL. */ 782svn_ra_serf__xml_context_t * 783svn_ra_serf__xml_context_create( 784 const svn_ra_serf__xml_transition_t *ttable, 785 svn_ra_serf__xml_opened_t opened_cb, 786 svn_ra_serf__xml_closed_t closed_cb, 787 svn_ra_serf__xml_cdata_t cdata_cb, 788 void *baton, 789 apr_pool_t *result_pool); 790 791/* Destroy all subpools for this structure. */ 792void 793svn_ra_serf__xml_context_destroy( 794 svn_ra_serf__xml_context_t *xmlctx); 795 796/* Construct a handler with the response function/baton set up to parse 797 a response body using the given XML context. The handler and its 798 internal structures are allocated in RESULT_POOL. 799 800 This also initializes HANDLER_POOL to the given RESULT_POOL. */ 801svn_ra_serf__handler_t * 802svn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx, 803 apr_pool_t *result_pool); 804 805 806/* Allocated within XES->STATE_POOL. Changes are not allowd (callers 807 should make a deep copy if they need to make changes). 808 809 The resulting hash maps char* names to char* values. */ 810apr_hash_t * 811svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes, 812 int stop_state); 813 814 815/* Attach the NAME/VALUE pair onto this/parent state identified by STATE. 816 The name and value will be copied into the target state's pool. 817 818 These values will be available to the CLOSED_CB for the target state, 819 or part of the gathered state via xml_gather_since(). 820 821 Typically, this function is used by a child state's close callback, 822 or within an opening callback to store additional data. 823 824 Note: if the state is not found, then a programmer error has occurred, 825 so the function will invoke SVN_ERR_MALFUNCTION(). */ 826void 827svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes, 828 int state, 829 const char *name, 830 const char *value); 831 832 833/* Returns XES->STATE_POOL for allocating structures that should live 834 as long as the state identified by XES. 835 836 Note: a state pool is created upon demand, so only use this function 837 when memory is required for a given state. */ 838apr_pool_t * 839svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes); 840 841 842/* Any XML parser may be used. When an opening tag is seen, call this 843 function to feed the information into XMLCTX. */ 844svn_error_t * 845svn_ra_serf__xml_cb_start(svn_ra_serf__xml_context_t *xmlctx, 846 const char *raw_name, 847 const char *const *attrs); 848 849 850/* When a close tag is seen, call this function to feed the information 851 into XMLCTX. */ 852svn_error_t * 853svn_ra_serf__xml_cb_end(svn_ra_serf__xml_context_t *xmlctx, 854 const char *raw_name); 855 856 857/* When cdata is parsed by the wrapping XML parser, call this function to 858 feed the cdata into the XMLCTX. */ 859svn_error_t * 860svn_ra_serf__xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx, 861 const char *data, 862 apr_size_t len); 863 864 865/* 866 * Parses a server-side error message into a local Subversion error. 867 */ 868struct svn_ra_serf__server_error_t { 869 /* Our local representation of the error. */ 870 svn_error_t *error; 871 872 /* Are we done with the response? */ 873 svn_boolean_t done; 874 875 /* Have we seen an error tag? */ 876 svn_boolean_t in_error; 877 878 /* Have we seen a HTTP "412 Precondition Failed" error? */ 879 svn_boolean_t contains_precondition_error; 880 881 /* Should we be collecting the XML cdata? */ 882 svn_boolean_t collect_cdata; 883 884 /* Collected cdata. NULL if cdata not needed. */ 885 svn_stringbuf_t *cdata; 886 887 /* XML parser and namespace used to parse the remote response */ 888 svn_ra_serf__xml_parser_t parser; 889}; 890 891 892/* 893 * Handler that discards the entire @a response body associated with a 894 * @a request. Implements svn_ra_serf__response_handler_t. 895 * 896 * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an 897 * error is detected, it will be populated for later detection. 898 * 899 * All temporary allocations will be made in a @a pool. 900 */ 901svn_error_t * 902svn_ra_serf__handle_discard_body(serf_request_t *request, 903 serf_bucket_t *response, 904 void *baton, 905 apr_pool_t *pool); 906 907 908/* 909 * Handler that retrieves the embedded XML multistatus response from the 910 * the @a RESPONSE body associated with a @a REQUEST. 911 * 912 * Implements svn_ra_serf__response_handler_t. 913 * 914 * The @a BATON should be of type svn_ra_serf__handler_t. When the request 915 * is complete, the handler's DONE flag will be set to TRUE. 916 * 917 * All temporary allocations will be made in a @a scratch_pool. 918 */ 919svn_error_t * 920svn_ra_serf__handle_multistatus_only(serf_request_t *request, 921 serf_bucket_t *response, 922 void *baton, 923 apr_pool_t *scratch_pool); 924 925 926/* Handler that expects an empty body. 927 928 If a body IS present, and it is text/xml, then it will be parsed for 929 a server-side error. 930 931 BATON should be the svn_ra_serf__handler_t running REQUEST. 932 933 Status line information will be in HANDLER->SLINE. 934 935 Any parsed errors will be left in HANDLER->SERVER_ERROR. That member 936 may be NULL if no body was present, or a problem occurred trying to 937 parse the body. 938 939 All temporary allocations will be made in SCRATCH_POOL. */ 940svn_error_t * 941svn_ra_serf__expect_empty_body(serf_request_t *request, 942 serf_bucket_t *response, 943 void *baton, 944 apr_pool_t *scratch_pool); 945 946 947/* 948 * This function will feed the RESPONSE body into XMLP. When parsing is 949 * completed (i.e. an EOF is received), *DONE is set to TRUE. 950 * Implements svn_ra_serf__response_handler_t. 951 * 952 * If an error occurs during processing RESP_ERR is invoked with the 953 * RESP_ERR_BATON. 954 * 955 * Temporary allocations are made in POOL. 956 */ 957svn_error_t * 958svn_ra_serf__handle_xml_parser(serf_request_t *request, 959 serf_bucket_t *response, 960 void *handler_baton, 961 apr_pool_t *pool); 962 963/* serf_response_handler_t implementation that completely discards 964 * the response. 965 * 966 * All temporary allocations will be made in @a pool. 967 */ 968apr_status_t 969svn_ra_serf__response_discard_handler(serf_request_t *request, 970 serf_bucket_t *response, 971 void *baton, 972 apr_pool_t *pool); 973 974 975/** XML helper functions. **/ 976 977/* 978 * Advance the internal XML @a parser to the @a state. 979 */ 980void 981svn_ra_serf__xml_push_state(svn_ra_serf__xml_parser_t *parser, 982 int state); 983 984/* 985 * Return to the previous internal XML @a parser state. 986 */ 987void 988svn_ra_serf__xml_pop_state(svn_ra_serf__xml_parser_t *parser); 989 990 991svn_error_t * 992svn_ra_serf__process_pending(svn_ra_serf__xml_parser_t *parser, 993 svn_boolean_t *network_eof, 994 apr_pool_t *scratch_pool); 995 996 997/* 998 * Add the appropriate serf buckets to @a agg_bucket represented by 999 * the XML * @a tag and @a value. 1000 * 1001 * The bucket will be allocated from @a bkt_alloc. 1002 */ 1003void 1004svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket, 1005 const char *tag, 1006 const char *value, 1007 serf_bucket_alloc_t *bkt_alloc); 1008 1009/* 1010 * Add the appropriate serf buckets to AGG_BUCKET with standard XML header: 1011 * <?xml version="1.0" encoding="utf-8"?> 1012 * 1013 * The bucket will be allocated from BKT_ALLOC. 1014 */ 1015void 1016svn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket, 1017 serf_bucket_alloc_t *bkt_alloc); 1018 1019/* 1020 * Add the appropriate serf buckets to AGG_BUCKET representing the XML 1021 * open tag with name TAG. 1022 * 1023 * Take the tag's attributes from varargs, a NULL-terminated list of 1024 * alternating <tt>char *</tt> key and <tt>char *</tt> val. Attribute 1025 * will be ignored if it's value is NULL. 1026 * 1027 * NOTE: Callers are responsible for XML-escaping attribute values as 1028 * necessary. 1029 * 1030 * The bucket will be allocated from BKT_ALLOC. 1031 */ 1032void 1033svn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket, 1034 serf_bucket_alloc_t *bkt_alloc, 1035 const char *tag, 1036 ...); 1037 1038/* 1039 * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close 1040 * with name TAG. 1041 * 1042 * The bucket will be allocated from BKT_ALLOC. 1043 */ 1044void 1045svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket, 1046 serf_bucket_alloc_t *bkt_alloc, 1047 const char *tag); 1048 1049/* 1050 * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped 1051 * version of DATA. 1052 * 1053 * The bucket will be allocated from BKT_ALLOC. 1054 */ 1055void 1056svn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket, 1057 serf_bucket_alloc_t *bkt_alloc, 1058 const char *data, apr_size_t len); 1059/* 1060 * Look up the @a attrs array for namespace definitions and add each one 1061 * to the @a ns_list of namespaces. 1062 * 1063 * New namespaces will be allocated in RESULT_POOL. 1064 */ 1065void 1066svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list, 1067 const char *const *attrs, 1068 apr_pool_t *result_pool); 1069 1070/* 1071 * Look up @a name in the @a ns_list list for previously declared namespace 1072 * definitions. 1073 * 1074 * Return (in @a *returned_prop_name) a #svn_ra_serf__dav_props_t tuple 1075 * representing the expanded name. 1076 */ 1077void 1078svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name, 1079 const svn_ra_serf__ns_t *ns_list, 1080 const char *name); 1081 1082 1083/** PROPFIND-related functions **/ 1084 1085/* 1086 * This function will deliver a PROP_CTX PROPFIND request in the SESS 1087 * serf context for the properties listed in LOOKUP_PROPS at URL for 1088 * DEPTH ("0","1","infinity"). 1089 * 1090 * This function will not block waiting for the response. Callers are 1091 * expected to call svn_ra_serf__wait_for_props(). 1092 */ 1093svn_error_t * 1094svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler, 1095 apr_hash_t *prop_vals, 1096 svn_ra_serf__session_t *sess, 1097 svn_ra_serf__connection_t *conn, 1098 const char *url, 1099 svn_revnum_t rev, 1100 const char *depth, 1101 const svn_ra_serf__dav_props_t *lookup_props, 1102 svn_ra_serf__list_t **done_list, 1103 apr_pool_t *pool); 1104 1105/* 1106 * This helper function will block until PROPFIND_HANDLER indicates that is 1107 * done or another error is returned. 1108 */ 1109svn_error_t * 1110svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler, 1111 apr_pool_t *scratch_pool); 1112 1113/* This is a blocking version of deliver_props. 1114 1115 The properties are fetched and placed into RESULTS, allocated in 1116 RESULT_POOL. 1117 1118 ### more docco about the other params. 1119 1120 Temporary allocations are made in SCRATCH_POOL. 1121*/ 1122svn_error_t * 1123svn_ra_serf__retrieve_props(apr_hash_t **results, 1124 svn_ra_serf__session_t *sess, 1125 svn_ra_serf__connection_t *conn, 1126 const char *url, 1127 svn_revnum_t rev, 1128 const char *depth, 1129 const svn_ra_serf__dav_props_t *props, 1130 apr_pool_t *result_pool, 1131 apr_pool_t *scratch_pool); 1132 1133 1134/* Using CONN, fetch the properties specified by WHICH_PROPS using CONN 1135 for URL at REVISION. The resulting properties are placed into a 2-level 1136 hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which 1137 is allocated in RESULT_POOL. 1138 1139 If REVISION is SVN_INVALID_REVNUM, then the properties are fetched 1140 from HEAD for URL. 1141 1142 This function performs the request synchronously. 1143 1144 Temporary allocations are made in SCRATCH_POOL. */ 1145svn_error_t * 1146svn_ra_serf__fetch_node_props(apr_hash_t **results, 1147 svn_ra_serf__connection_t *conn, 1148 const char *url, 1149 svn_revnum_t revision, 1150 const svn_ra_serf__dav_props_t *which_props, 1151 apr_pool_t *result_pool, 1152 apr_pool_t *scratch_pool); 1153 1154 1155/* Using CONN, fetch a DAV: property from the resource identified by URL 1156 within REVISION. The PROPNAME may be one of: 1157 1158 "checked-in" 1159 "href" 1160 1161 The resulting value will be allocated in RESULT_POOL, and may be NULL 1162 if the property does not exist (note: "href" always exists). 1163 1164 This function performs the request synchronously. 1165 1166 Temporary allocations are made in SCRATCH_POOL. */ 1167svn_error_t * 1168svn_ra_serf__fetch_dav_prop(const char **value, 1169 svn_ra_serf__connection_t *conn, 1170 const char *url, 1171 svn_revnum_t revision, 1172 const char *propname, 1173 apr_pool_t *result_pool, 1174 apr_pool_t *scratch_pool); 1175 1176 1177/* Set PROPS for PATH at REV revision with a NS:NAME VAL. 1178 * 1179 * The POOL governs allocation. 1180 */ 1181void 1182svn_ra_serf__set_ver_prop(apr_hash_t *props, 1183 const char *path, svn_revnum_t rev, 1184 const char *ns, const char *name, 1185 const svn_string_t *val, apr_pool_t *pool); 1186#define svn_ra_serf__set_rev_prop svn_ra_serf__set_ver_prop 1187 1188/** Property walker functions **/ 1189 1190typedef svn_error_t * 1191(*svn_ra_serf__walker_visitor_t)(void *baton, 1192 const char *ns, 1193 const char *name, 1194 const svn_string_t *val, 1195 apr_pool_t *pool); 1196 1197svn_error_t * 1198svn_ra_serf__walk_all_props(apr_hash_t *props, 1199 const char *name, 1200 svn_revnum_t rev, 1201 svn_ra_serf__walker_visitor_t walker, 1202 void *baton, 1203 apr_pool_t *pool); 1204 1205 1206/* Like walk_all_props(), but a 2-level hash. */ 1207svn_error_t * 1208svn_ra_serf__walk_node_props(apr_hash_t *props, 1209 svn_ra_serf__walker_visitor_t walker, 1210 void *baton, 1211 apr_pool_t *scratch_pool); 1212 1213 1214typedef svn_error_t * 1215(*svn_ra_serf__path_rev_walker_t)(void *baton, 1216 const char *path, apr_ssize_t path_len, 1217 const char *ns, apr_ssize_t ns_len, 1218 const char *name, apr_ssize_t name_len, 1219 const svn_string_t *val, 1220 apr_pool_t *pool); 1221svn_error_t * 1222svn_ra_serf__walk_all_paths(apr_hash_t *props, 1223 svn_revnum_t rev, 1224 svn_ra_serf__path_rev_walker_t walker, 1225 void *baton, 1226 apr_pool_t *pool); 1227 1228 1229/* Map a property name, as passed over the wire, into its corresponding 1230 Subversion-internal name. The returned name will be a static value, 1231 or allocated within RESULT_POOL. 1232 1233 If the property should be ignored (eg. some DAV properties), then NULL 1234 will be returned. */ 1235const char * 1236svn_ra_serf__svnname_from_wirename(const char *ns, 1237 const char *name, 1238 apr_pool_t *result_pool); 1239 1240 1241/* Select the basic revision properties from the set of "all" properties. 1242 Return these in *REVPROPS, allocated from RESULT_POOL. */ 1243svn_error_t * 1244svn_ra_serf__select_revprops(apr_hash_t **revprops, 1245 const char *name, 1246 svn_revnum_t rev, 1247 apr_hash_t *all_revprops, 1248 apr_pool_t *result_pool, 1249 apr_pool_t *scratch_pool); 1250 1251 1252/* PROPS is nested hash tables mapping NS -> NAME -> VALUE. 1253 This function takes the NS:NAME:VALUE hashes and flattens them into a set of 1254 names to VALUE. The names are composed of NS:NAME, with specific 1255 rewrite from wire names (DAV) to SVN names. This mapping is managed 1256 by the svn_ra_serf__set_baton_props() function. 1257 1258 FLAT_PROPS is allocated in RESULT_POOL. 1259 ### right now, we do a shallow copy from PROPS to FLAT_PROPS. therefore, 1260 ### the names and values in PROPS must be in the proper pool. 1261 1262 Temporary allocations are made in SCRATCH_POOL. */ 1263svn_error_t * 1264svn_ra_serf__flatten_props(apr_hash_t **flat_props, 1265 apr_hash_t *props, 1266 apr_pool_t *result_pool, 1267 apr_pool_t *scratch_pool); 1268 1269 1270/* Return the property value for PATH at REV revision with a NS:NAME. 1271 * PROPS is a four-level nested hash: (svn_revnum_t => char *path => 1272 * char *ns => char *name => svn_string_t *). */ 1273const svn_string_t * 1274svn_ra_serf__get_ver_prop_string(apr_hash_t *props, 1275 const char *path, svn_revnum_t rev, 1276 const char *ns, const char *name); 1277 1278/* Same as svn_ra_serf__get_ver_prop_string(), but returns a C string. */ 1279const char * 1280svn_ra_serf__get_ver_prop(apr_hash_t *props, 1281 const char *path, svn_revnum_t rev, 1282 const char *ns, const char *name); 1283 1284/* Same as svn_ra_serf__get_ver_prop_string(), but for the unknown revision. */ 1285const svn_string_t * 1286svn_ra_serf__get_prop_string(apr_hash_t *props, 1287 const char *path, 1288 const char *ns, 1289 const char *name); 1290 1291/* Same as svn_ra_serf__get_ver_prop(), but for the unknown revision. */ 1292const char * 1293svn_ra_serf__get_prop(apr_hash_t *props, 1294 const char *path, 1295 const char *ns, 1296 const char *name); 1297 1298/* Same as svn_ra_serf__set_rev_prop(), but for the unknown revision. */ 1299void 1300svn_ra_serf__set_prop(apr_hash_t *props, const char *path, 1301 const char *ns, const char *name, 1302 const svn_string_t *val, apr_pool_t *pool); 1303 1304svn_error_t * 1305svn_ra_serf__get_resource_type(svn_node_kind_t *kind, 1306 apr_hash_t *props); 1307 1308 1309/** MERGE-related functions **/ 1310 1311void 1312svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens, 1313 const char *parent, 1314 serf_bucket_t *body, 1315 serf_bucket_alloc_t *alloc, 1316 apr_pool_t *pool); 1317 1318/* Create an MERGE request aimed at the SESSION url, requesting the 1319 merge of the resource identified by MERGE_RESOURCE_URL. 1320 LOCK_TOKENS is a hash mapping paths to lock tokens owned by the 1321 client. If KEEP_LOCKS is set, instruct the server to not release 1322 locks set on the paths included in this commit. */ 1323svn_error_t * 1324svn_ra_serf__run_merge(const svn_commit_info_t **commit_info, 1325 int *response_code, 1326 svn_ra_serf__session_t *session, 1327 svn_ra_serf__connection_t *conn, 1328 const char *merge_resource_url, 1329 apr_hash_t *lock_tokens, 1330 svn_boolean_t keep_locks, 1331 apr_pool_t *result_pool, 1332 apr_pool_t *scratch_pool); 1333 1334 1335/** OPTIONS-related functions **/ 1336 1337/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the 1338 current youngest revnum, returning it in *YOUNGEST. 1339 1340 (the revnum is headers of the OPTIONS response) 1341 1342 This function performs the request synchronously. 1343 1344 All temporary allocations will be made in SCRATCH_POOL. */ 1345svn_error_t * 1346svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest, 1347 svn_ra_serf__connection_t *conn, 1348 apr_pool_t *scratch_pool); 1349 1350 1351/* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the 1352 activity collection set and return it in *ACTIVITY_URL, allocated 1353 from RESULT_POOL. 1354 1355 (the activity-collection-set is in the body of the OPTIONS response) 1356 1357 This function performs the request synchronously. 1358 1359 All temporary allocations will be made in SCRATCH_POOL. */ 1360svn_error_t * 1361svn_ra_serf__v1_get_activity_collection(const char **activity_url, 1362 svn_ra_serf__connection_t *conn, 1363 apr_pool_t *result_pool, 1364 apr_pool_t *scratch_pool); 1365 1366 1367/* Set @a VCC_URL to the default VCC for our repository based on @a 1368 * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and 1369 * repository root URLs are cached in @a SESSION. Use @a CONN for any 1370 * required network communications if it is non-NULL; otherwise use the 1371 * default connection. 1372 * 1373 * All temporary allocations will be made in @a POOL. */ 1374svn_error_t * 1375svn_ra_serf__discover_vcc(const char **vcc_url, 1376 svn_ra_serf__session_t *session, 1377 svn_ra_serf__connection_t *conn, 1378 apr_pool_t *pool); 1379 1380/* Set @a REPORT_TARGET to the URI of the resource at which generic 1381 * (path-agnostic) REPORTs should be aimed for @a SESSION. Use @a 1382 * CONN for any required network communications if it is non-NULL; 1383 * otherwise use the default connection. 1384 * 1385 * All temporary allocations will be made in @a POOL. 1386 */ 1387svn_error_t * 1388svn_ra_serf__report_resource(const char **report_target, 1389 svn_ra_serf__session_t *session, 1390 svn_ra_serf__connection_t *conn, 1391 apr_pool_t *pool); 1392 1393/* Set @a REL_PATH to a path (not URI-encoded) relative to the root of 1394 * the repository pointed to by @a SESSION, based on original path 1395 * (URI-encoded) @a ORIG_PATH. Use @a CONN for any required network 1396 * communications if it is non-NULL; otherwise use the default 1397 * connection. Use POOL for allocations. */ 1398svn_error_t * 1399svn_ra_serf__get_relative_path(const char **rel_path, 1400 const char *orig_path, 1401 svn_ra_serf__session_t *session, 1402 svn_ra_serf__connection_t *conn, 1403 apr_pool_t *pool); 1404 1405 1406/* Using the default connection in SESSION (conns[0]), get the youngest 1407 revnum from the server, returning it in *YOUNGEST. 1408 1409 This function operates synchronously. 1410 1411 All temporary allocations are performed in SCRATCH_POOL. */ 1412svn_error_t * 1413svn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest, 1414 svn_ra_serf__session_t *session, 1415 apr_pool_t *scratch_pool); 1416 1417 1418/* Generate a revision-stable URL. 1419 1420 The RA APIs all refer to user/public URLs that float along with the 1421 youngest revision. In many cases, we do NOT want to work with that URL 1422 since it can change from one moment to the next. Especially if we 1423 attempt to operation against multiple floating URLs -- we could end up 1424 referring to two separate revisions. 1425 1426 The DAV RA provider(s) solve this by generating a URL that is specific 1427 to a revision by using a URL into a "baseline collection". 1428 1429 For a specified SESSION, with an optional CONN (if NULL, then the 1430 session's default connection will be used; specifically SESSION->conns[0]), 1431 generate a revision-stable URL for URL at REVISION. If REVISION is 1432 SVN_INVALID_REVNUM, then the stable URL will refer to the youngest 1433 revision at the time this function was called. 1434 1435 If URL is NULL, then the session root will be used. 1436 1437 The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL. 1438 1439 If LATEST_REVNUM is not NULL, then the revision used will be placed into 1440 *LATEST_REVNUM. That will be equal to youngest, or the given REVISION. 1441 1442 This function operates synchronously, if any communication to the server 1443 is required. Communication is needed if REVISION is SVN_INVALID_REVNUM 1444 (to get the current youngest revnum), or if the specified REVISION is not 1445 (yet) in our cache of baseline collections. 1446 1447 All temporary allocations are performed in SCRATCH_POOL. */ 1448svn_error_t * 1449svn_ra_serf__get_stable_url(const char **stable_url, 1450 svn_revnum_t *latest_revnum, 1451 svn_ra_serf__session_t *session, 1452 svn_ra_serf__connection_t *conn, 1453 const char *url, 1454 svn_revnum_t revision, 1455 apr_pool_t *result_pool, 1456 apr_pool_t *scratch_pool); 1457 1458 1459/** RA functions **/ 1460 1461/* Implements svn_ra__vtable_t.get_log(). */ 1462svn_error_t * 1463svn_ra_serf__get_log(svn_ra_session_t *session, 1464 const apr_array_header_t *paths, 1465 svn_revnum_t start, 1466 svn_revnum_t end, 1467 int limit, 1468 svn_boolean_t discover_changed_paths, 1469 svn_boolean_t strict_node_history, 1470 svn_boolean_t include_merged_revisions, 1471 const apr_array_header_t *revprops, 1472 svn_log_entry_receiver_t receiver, 1473 void *receiver_baton, 1474 apr_pool_t *pool); 1475 1476/* Implements svn_ra__vtable_t.get_locations(). */ 1477svn_error_t * 1478svn_ra_serf__get_locations(svn_ra_session_t *session, 1479 apr_hash_t **locations, 1480 const char *path, 1481 svn_revnum_t peg_revision, 1482 const apr_array_header_t *location_revisions, 1483 apr_pool_t *pool); 1484 1485/* Implements svn_ra__vtable_t.get_location_segments(). */ 1486svn_error_t * 1487svn_ra_serf__get_location_segments(svn_ra_session_t *session, 1488 const char *path, 1489 svn_revnum_t peg_revision, 1490 svn_revnum_t start_rev, 1491 svn_revnum_t end_rev, 1492 svn_location_segment_receiver_t receiver, 1493 void *receiver_baton, 1494 apr_pool_t *pool); 1495 1496/* Implements svn_ra__vtable_t.do_diff(). */ 1497svn_error_t * 1498svn_ra_serf__do_diff(svn_ra_session_t *session, 1499 const svn_ra_reporter3_t **reporter, 1500 void **report_baton, 1501 svn_revnum_t revision, 1502 const char *diff_target, 1503 svn_depth_t depth, 1504 svn_boolean_t ignore_ancestry, 1505 svn_boolean_t text_deltas, 1506 const char *versus_url, 1507 const svn_delta_editor_t *diff_editor, 1508 void *diff_baton, 1509 apr_pool_t *pool); 1510 1511/* Implements svn_ra__vtable_t.do_status(). */ 1512svn_error_t * 1513svn_ra_serf__do_status(svn_ra_session_t *ra_session, 1514 const svn_ra_reporter3_t **reporter, 1515 void **report_baton, 1516 const char *status_target, 1517 svn_revnum_t revision, 1518 svn_depth_t depth, 1519 const svn_delta_editor_t *status_editor, 1520 void *status_baton, 1521 apr_pool_t *pool); 1522 1523/* Implements svn_ra__vtable_t.do_update(). */ 1524svn_error_t * 1525svn_ra_serf__do_update(svn_ra_session_t *ra_session, 1526 const svn_ra_reporter3_t **reporter, 1527 void **report_baton, 1528 svn_revnum_t revision_to_update_to, 1529 const char *update_target, 1530 svn_depth_t depth, 1531 svn_boolean_t send_copyfrom_args, 1532 svn_boolean_t ignore_ancestry, 1533 const svn_delta_editor_t *update_editor, 1534 void *update_baton, 1535 apr_pool_t *result_pool, 1536 apr_pool_t *scratch_pool); 1537 1538/* Implements svn_ra__vtable_t.do_switch(). */ 1539svn_error_t * 1540svn_ra_serf__do_switch(svn_ra_session_t *ra_session, 1541 const svn_ra_reporter3_t **reporter, 1542 void **report_baton, 1543 svn_revnum_t revision_to_switch_to, 1544 const char *switch_target, 1545 svn_depth_t depth, 1546 const char *switch_url, 1547 svn_boolean_t send_copyfrom_args, 1548 svn_boolean_t ignore_ancestry, 1549 const svn_delta_editor_t *switch_editor, 1550 void *switch_baton, 1551 apr_pool_t *result_pool, 1552 apr_pool_t *scratch_pool); 1553 1554/* Implements svn_ra__vtable_t.get_file_revs(). */ 1555svn_error_t * 1556svn_ra_serf__get_file_revs(svn_ra_session_t *session, 1557 const char *path, 1558 svn_revnum_t start, 1559 svn_revnum_t end, 1560 svn_boolean_t include_merged_revisions, 1561 svn_file_rev_handler_t handler, 1562 void *handler_baton, 1563 apr_pool_t *pool); 1564 1565/* Implements svn_ra__vtable_t.get_dated_revision(). */ 1566svn_error_t * 1567svn_ra_serf__get_dated_revision(svn_ra_session_t *session, 1568 svn_revnum_t *revision, 1569 apr_time_t tm, 1570 apr_pool_t *pool); 1571 1572/* Implements svn_ra__vtable_t.get_commit_editor(). */ 1573svn_error_t * 1574svn_ra_serf__get_commit_editor(svn_ra_session_t *session, 1575 const svn_delta_editor_t **editor, 1576 void **edit_baton, 1577 apr_hash_t *revprop_table, 1578 svn_commit_callback2_t callback, 1579 void *callback_baton, 1580 apr_hash_t *lock_tokens, 1581 svn_boolean_t keep_locks, 1582 apr_pool_t *pool); 1583 1584/* Implements svn_ra__vtable_t.get_file(). */ 1585svn_error_t * 1586svn_ra_serf__get_file(svn_ra_session_t *session, 1587 const char *path, 1588 svn_revnum_t revision, 1589 svn_stream_t *stream, 1590 svn_revnum_t *fetched_rev, 1591 apr_hash_t **props, 1592 apr_pool_t *pool); 1593 1594/* Implements svn_ra__vtable_t.change_rev_prop(). */ 1595svn_error_t * 1596svn_ra_serf__change_rev_prop(svn_ra_session_t *session, 1597 svn_revnum_t rev, 1598 const char *name, 1599 const svn_string_t *const *old_value_p, 1600 const svn_string_t *value, 1601 apr_pool_t *pool); 1602 1603/* Implements svn_ra__vtable_t.replay(). */ 1604svn_error_t * 1605svn_ra_serf__replay(svn_ra_session_t *ra_session, 1606 svn_revnum_t revision, 1607 svn_revnum_t low_water_mark, 1608 svn_boolean_t text_deltas, 1609 const svn_delta_editor_t *editor, 1610 void *edit_baton, 1611 apr_pool_t *pool); 1612 1613/* Implements svn_ra__vtable_t.replay_range(). */ 1614svn_error_t * 1615svn_ra_serf__replay_range(svn_ra_session_t *ra_session, 1616 svn_revnum_t start_revision, 1617 svn_revnum_t end_revision, 1618 svn_revnum_t low_water_mark, 1619 svn_boolean_t send_deltas, 1620 svn_ra_replay_revstart_callback_t revstart_func, 1621 svn_ra_replay_revfinish_callback_t revfinish_func, 1622 void *replay_baton, 1623 apr_pool_t *pool); 1624 1625/* Implements svn_ra__vtable_t.lock(). */ 1626svn_error_t * 1627svn_ra_serf__lock(svn_ra_session_t *ra_session, 1628 apr_hash_t *path_revs, 1629 const char *comment, 1630 svn_boolean_t force, 1631 svn_ra_lock_callback_t lock_func, 1632 void *lock_baton, 1633 apr_pool_t *pool); 1634 1635/* Implements svn_ra__vtable_t.unlock(). */ 1636svn_error_t * 1637svn_ra_serf__unlock(svn_ra_session_t *ra_session, 1638 apr_hash_t *path_tokens, 1639 svn_boolean_t force, 1640 svn_ra_lock_callback_t lock_func, 1641 void *lock_baton, 1642 apr_pool_t *pool); 1643 1644/* Implements svn_ra__vtable_t.get_lock(). */ 1645svn_error_t * 1646svn_ra_serf__get_lock(svn_ra_session_t *ra_session, 1647 svn_lock_t **lock, 1648 const char *path, 1649 apr_pool_t *pool); 1650 1651/* Implements svn_ra__vtable_t.get_locks(). */ 1652svn_error_t * 1653svn_ra_serf__get_locks(svn_ra_session_t *ra_session, 1654 apr_hash_t **locks, 1655 const char *path, 1656 svn_depth_t depth, 1657 apr_pool_t *pool); 1658 1659/* Request a mergeinfo-report from the URL attached to SESSION, 1660 and fill in the MERGEINFO hash with the results. 1661 1662 Implements svn_ra__vtable_t.get_mergeinfo(). 1663 */ 1664svn_error_t * 1665svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session, 1666 apr_hash_t **mergeinfo, 1667 const apr_array_header_t *paths, 1668 svn_revnum_t revision, 1669 svn_mergeinfo_inheritance_t inherit, 1670 svn_boolean_t include_descendants, 1671 apr_pool_t *pool); 1672 1673/* Exchange capabilities with the server, by sending an OPTIONS 1674 * request announcing the client's capabilities, and by filling 1675 * SERF_SESS->capabilities with the server's capabilities as read from 1676 * the response headers. Use POOL only for temporary allocation. 1677 * 1678 * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to 1679 * report a server-dictated redirect or relocation (HTTP 301 or 302 1680 * error codes), setting *CORRECTED_URL to the value of the corrected 1681 * repository URL. Otherwise, such responses from the server will 1682 * generate an error. (In either case, no capabilities are exchanged 1683 * if there is, in fact, such a response from the server.) 1684 */ 1685svn_error_t * 1686svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess, 1687 const char **corrected_url, 1688 apr_pool_t *pool); 1689 1690/* Implements svn_ra__vtable_t.has_capability(). */ 1691svn_error_t * 1692svn_ra_serf__has_capability(svn_ra_session_t *ra_session, 1693 svn_boolean_t *has, 1694 const char *capability, 1695 apr_pool_t *pool); 1696 1697/* Implements svn_ra__vtable_t.get_deleted_rev(). */ 1698svn_error_t * 1699svn_ra_serf__get_deleted_rev(svn_ra_session_t *session, 1700 const char *path, 1701 svn_revnum_t peg_revision, 1702 svn_revnum_t end_revision, 1703 svn_revnum_t *revision_deleted, 1704 apr_pool_t *pool); 1705 1706/* Implements the get_inherited_props RA layer function. */ 1707svn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session, 1708 apr_array_header_t **iprops, 1709 const char *path, 1710 svn_revnum_t revision, 1711 apr_pool_t *result_pool, 1712 apr_pool_t *scratch_pool); 1713 1714/* Implements svn_ra__vtable_t.get_repos_root(). */ 1715svn_error_t * 1716svn_ra_serf__get_repos_root(svn_ra_session_t *ra_session, 1717 const char **url, 1718 apr_pool_t *pool); 1719 1720/* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */ 1721svn_error_t * 1722svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session, 1723 svn_delta_shim_callbacks_t *callbacks); 1724 1725/*** Authentication handler declarations ***/ 1726 1727/** 1728 * Callback function that loads the credentials for Basic and Digest 1729 * authentications, both for server and proxy authentication. 1730 */ 1731apr_status_t 1732svn_ra_serf__credentials_callback(char **username, char **password, 1733 serf_request_t *request, void *baton, 1734 int code, const char *authn_type, 1735 const char *realm, 1736 apr_pool_t *pool); 1737 1738 1739/*** General utility functions ***/ 1740 1741/** 1742 * Convert an HTTP STATUS_CODE resulting from a WebDAV request against 1743 * PATH to the relevant error code. Use the response-supplied LOCATION 1744 * where it necessary. 1745 */ 1746svn_error_t * 1747svn_ra_serf__error_on_status(int status_code, 1748 const char *path, 1749 const char *location); 1750 1751/* ###? */ 1752svn_error_t * 1753svn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf, 1754 serf_bucket_t *bkt, 1755 apr_pool_t *result_pool, 1756 apr_pool_t *scratch_pool); 1757 1758/* ###? */ 1759serf_bucket_t * 1760svn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf, 1761 serf_bucket_alloc_t *allocator, 1762 apr_pool_t *result_pool, 1763 apr_pool_t *scratch_pool); 1764 1765/** Wrap STATUS from an serf function. If STATUS is not serf error code, 1766 * this is equivalent to svn_error_wrap_apr(). 1767 */ 1768svn_error_t * 1769svn_ra_serf__wrap_err(apr_status_t status, 1770 const char *fmt, 1771 ...); 1772 1773 1774#if defined(SVN_DEBUG) 1775/* Wrapper macros to collect file and line information */ 1776#define svn_ra_serf__wrap_err \ 1777 (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err)) 1778 1779#endif 1780 1781#ifdef __cplusplus 1782} 1783#endif /* __cplusplus */ 1784 1785#endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */ 1786