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/** Wait duration (in microseconds) used in calls to serf_context_run() */ 61#define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000 62 63 64 65/* Forward declarations. */ 66typedef struct svn_ra_serf__session_t svn_ra_serf__session_t; 67 68/* A serf connection and optionally associated SSL context. */ 69typedef struct svn_ra_serf__connection_t { 70 /* Our connection to a server. */ 71 serf_connection_t *conn; 72 73 /* Bucket allocator for this connection. */ 74 serf_bucket_alloc_t *bkt_alloc; 75 76 /* Collected cert failures in chain. */ 77 int server_cert_failures; 78 79 /* What was the last HTTP status code we got on this connection? */ 80 int last_status_code; 81 82 /* Optional SSL context for this connection. */ 83 serf_ssl_context_t *ssl_context; 84 svn_auth_iterstate_t *ssl_client_auth_state; 85 svn_auth_iterstate_t *ssl_client_pw_auth_state; 86 87 svn_ra_serf__session_t *session; 88 89} svn_ra_serf__connection_t; 90 91/** Maximum value we'll allow for the http-max-connections config option. 92 * 93 * Note: minimum 2 connections are required for ra_serf to function 94 * correctly! 95 */ 96#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8 97 98/* 99 * The master serf RA session. 100 * 101 * This is stored in the ra session ->priv field. 102 */ 103struct svn_ra_serf__session_t { 104 /* Pool for allocations during this session */ 105 apr_pool_t *pool; 106 107 /* The current context */ 108 serf_context_t *context; 109 110 /* The maximum number of connections we'll use for parallelized 111 fetch operations (updates, etc.) */ 112 apr_int64_t max_connections; 113 114 /* Are we using ssl */ 115 svn_boolean_t using_ssl; 116 117 /* Should we ask for compressed responses? */ 118 svn_boolean_t using_compression; 119 120 /* The user agent string */ 121 const char *useragent; 122 123 /* The current connection */ 124 svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT]; 125 int num_conns; 126 int cur_conn; 127 128 /* The URL that was passed into _open() */ 129 apr_uri_t session_url; 130 const char *session_url_str; 131 132 /* The actual discovered root; may be NULL until we know it. */ 133 apr_uri_t repos_root; 134 const char *repos_root_str; 135 136 /* The server is not Apache/mod_dav_svn (directly) and only supports 137 HTTP/1.0. Thus, we cannot send chunked requests. */ 138 svn_boolean_t http10; 139 140 /* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */ 141 svn_boolean_t using_chunked_requests; 142 143 /* Do we need to detect whether the connection supports chunked requests? 144 i.e. is there a (reverse) proxy that does not support them? */ 145 svn_boolean_t detect_chunking; 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 svn_boolean_t 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 656 657/* v2 of the XML parsing functions */ 658 659/* The XML parsing context. */ 660typedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t; 661 662 663/* An opaque structure for the XML parse element/state. */ 664typedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t; 665 666/* Called just after the parser moves into ENTERED_STATE. The tag causing 667 the transition is passed in TAG. 668 669 This callback is applied to a parsing context by using the 670 svn_ra_serf__xml_context_customize() function. 671 672 NOTE: this callback, when set, will be invoked on *every* transition. 673 The callback must examine ENTERED_STATE to determine if any action 674 must be taken. The original state is not provided, but must be derived 675 from ENTERED_STATE and/or the TAG causing the transition (if needed). */ 676typedef svn_error_t * 677(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes, 678 void *baton, 679 int entered_state, 680 const svn_ra_serf__dav_props_t *tag, 681 apr_pool_t *scratch_pool); 682 683 684/* Called just before the parser leaves LEAVING_STATE. 685 686 If cdata collection was enabled for this state, then CDATA will be 687 non-NULL and contain the collected cdata. 688 689 If attribute collection was enabled for this state, then ATTRS will 690 contain the attributes collected for this element only, along with 691 any values stored via svn_ra_serf__xml_note(). 692 693 Use svn_ra_serf__xml_gather_since() to gather up data from outer states. 694 695 ATTRS is char* -> char*. 696 697 Temporary allocations may be made in SCRATCH_POOL. */ 698typedef svn_error_t * 699(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes, 700 void *baton, 701 int leaving_state, 702 const svn_string_t *cdata, 703 apr_hash_t *attrs, 704 apr_pool_t *scratch_pool); 705 706 707/* Called for all states that are not using the builtin cdata collection. 708 This callback is (only) appropriate for unbounded-size cdata content. 709 710 CURRENT_STATE may be used to decide what to do with the data. 711 712 Temporary allocations may be made in SCRATCH_POOL. */ 713typedef svn_error_t * 714(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes, 715 void *baton, 716 int current_state, 717 const char *data, 718 apr_size_t len, 719 apr_pool_t *scratch_pool); 720 721 722/* State transition table. 723 724 When the XML Context is constructed, it is in state 0. User states are 725 positive integers. 726 727 In a list of transitions, use { 0 } to indicate the end. Specifically, 728 the code looks for NS == NULL. 729 730 ### more docco 731*/ 732typedef struct svn_ra_serf__xml_transition_t { 733 /* This transition applies when in this state */ 734 int from_state; 735 736 /* And when this tag is observed */ 737 const char *ns; 738 const char *name; 739 740 /* Moving to this state */ 741 int to_state; 742 743 /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should 744 be TRUE in order to capture this cdata. */ 745 svn_boolean_t collect_cdata; 746 747 /* Which attributes of NAME should be collected? Terminate with NULL. 748 Maximum of 10 attributes may be collected. Note that attribute 749 namespaces are ignored at this time. 750 751 Attribute names beginning with "?" are optional. Other names must 752 exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised. */ 753 const char *collect_attrs[11]; 754 755 /* When NAME is closed, should the callback be invoked? */ 756 svn_boolean_t custom_close; 757 758} svn_ra_serf__xml_transition_t; 759 760 761/* Construct an XML parsing context, based on the TTABLE transition table. 762 As content is parsed, the CLOSED_CB callback will be invoked according 763 to the definition in the table. 764 765 If OPENED_CB is not NULL, then it will be invoked for *every* tag-open 766 event. The callback will need to use the ENTERED_STATE and TAG parameters 767 to decide what it would like to do. 768 769 If CDATA_CB is not NULL, then it will be called for all cdata that is 770 not be automatically collected (based on the transition table record's 771 COLLECT_CDATA flag). It will be called in every state, so the callback 772 must examine the CURRENT_STATE parameter to decide what to do. 773 774 The same BATON value will be passed to all three callbacks. 775 776 The context will be created within RESULT_POOL. */ 777svn_ra_serf__xml_context_t * 778svn_ra_serf__xml_context_create( 779 const svn_ra_serf__xml_transition_t *ttable, 780 svn_ra_serf__xml_opened_t opened_cb, 781 svn_ra_serf__xml_closed_t closed_cb, 782 svn_ra_serf__xml_cdata_t cdata_cb, 783 void *baton, 784 apr_pool_t *result_pool); 785 786/* Destroy all subpools for this structure. */ 787void 788svn_ra_serf__xml_context_destroy( 789 svn_ra_serf__xml_context_t *xmlctx); 790 791/* Construct a handler with the response function/baton set up to parse 792 a response body using the given XML context. The handler and its 793 internal structures are allocated in RESULT_POOL. 794 795 This also initializes HANDLER_POOL to the given RESULT_POOL. */ 796svn_ra_serf__handler_t * 797svn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx, 798 apr_pool_t *result_pool); 799 800 801/* Allocated within XES->STATE_POOL. Changes are not allowd (callers 802 should make a deep copy if they need to make changes). 803 804 The resulting hash maps char* names to char* values. */ 805apr_hash_t * 806svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes, 807 int stop_state); 808 809 810/* Attach the NAME/VALUE pair onto this/parent state identified by STATE. 811 The name and value will be copied into the target state's pool. 812 813 These values will be available to the CLOSED_CB for the target state, 814 or part of the gathered state via xml_gather_since(). 815 816 Typically, this function is used by a child state's close callback, 817 or within an opening callback to store additional data. 818 819 Note: if the state is not found, then a programmer error has occurred, 820 so the function will invoke SVN_ERR_MALFUNCTION(). */ 821void 822svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes, 823 int state, 824 const char *name, 825 const char *value); 826 827 828/* Returns XES->STATE_POOL for allocating structures that should live 829 as long as the state identified by XES. 830 831 Note: a state pool is created upon demand, so only use this function 832 when memory is required for a given state. */ 833apr_pool_t * 834svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes); 835 836 837/* Any XML parser may be used. When an opening tag is seen, call this 838 function to feed the information into XMLCTX. */ 839svn_error_t * 840svn_ra_serf__xml_cb_start(svn_ra_serf__xml_context_t *xmlctx, 841 const char *raw_name, 842 const char *const *attrs); 843 844 845/* When a close tag is seen, call this function to feed the information 846 into XMLCTX. */ 847svn_error_t * 848svn_ra_serf__xml_cb_end(svn_ra_serf__xml_context_t *xmlctx, 849 const char *raw_name); 850 851 852/* When cdata is parsed by the wrapping XML parser, call this function to 853 feed the cdata into the XMLCTX. */ 854svn_error_t * 855svn_ra_serf__xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx, 856 const char *data, 857 apr_size_t len); 858 859 860/* 861 * Parses a server-side error message into a local Subversion error. 862 */ 863struct svn_ra_serf__server_error_t { 864 /* Our local representation of the error. */ 865 svn_error_t *error; 866 867 /* Are we done with the response? */ 868 svn_boolean_t done; 869 870 /* Have we seen an error tag? */ 871 svn_boolean_t in_error; 872 873 /* Have we seen a HTTP "412 Precondition Failed" error? */ 874 svn_boolean_t contains_precondition_error; 875 876 /* Should we be collecting the XML cdata? */ 877 svn_boolean_t collect_cdata; 878 879 /* Collected cdata. NULL if cdata not needed. */ 880 svn_stringbuf_t *cdata; 881 882 /* XML parser and namespace used to parse the remote response */ 883 svn_ra_serf__xml_parser_t parser; 884}; 885 886 887/* 888 * Handler that discards the entire @a response body associated with a 889 * @a request. Implements svn_ra_serf__response_handler_t. 890 * 891 * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an 892 * error is detected, it will be populated for later detection. 893 * 894 * All temporary allocations will be made in a @a pool. 895 */ 896svn_error_t * 897svn_ra_serf__handle_discard_body(serf_request_t *request, 898 serf_bucket_t *response, 899 void *baton, 900 apr_pool_t *pool); 901 902 903/* 904 * Handler that retrieves the embedded XML multistatus response from the 905 * the @a RESPONSE body associated with a @a REQUEST. 906 * 907 * Implements svn_ra_serf__response_handler_t. 908 * 909 * The @a BATON should be of type svn_ra_serf__handler_t. When the request 910 * is complete, the handler's DONE flag will be set to TRUE. 911 * 912 * All temporary allocations will be made in a @a scratch_pool. 913 */ 914svn_error_t * 915svn_ra_serf__handle_multistatus_only(serf_request_t *request, 916 serf_bucket_t *response, 917 void *baton, 918 apr_pool_t *scratch_pool); 919 920 921/* Handler that expects an empty body. 922 923 If a body IS present, and it is text/xml, then it will be parsed for 924 a server-side error. 925 926 BATON should be the svn_ra_serf__handler_t running REQUEST. 927 928 Status line information will be in HANDLER->SLINE. 929 930 Any parsed errors will be left in HANDLER->SERVER_ERROR. That member 931 may be NULL if no body was present, or a problem occurred trying to 932 parse the body. 933 934 All temporary allocations will be made in SCRATCH_POOL. */ 935svn_error_t * 936svn_ra_serf__expect_empty_body(serf_request_t *request, 937 serf_bucket_t *response, 938 void *baton, 939 apr_pool_t *scratch_pool); 940 941 942/* 943 * This function will feed the RESPONSE body into XMLP. When parsing is 944 * completed (i.e. an EOF is received), *DONE is set to TRUE. 945 * Implements svn_ra_serf__response_handler_t. 946 * 947 * If an error occurs during processing RESP_ERR is invoked with the 948 * RESP_ERR_BATON. 949 * 950 * Temporary allocations are made in POOL. 951 */ 952svn_error_t * 953svn_ra_serf__handle_xml_parser(serf_request_t *request, 954 serf_bucket_t *response, 955 void *handler_baton, 956 apr_pool_t *pool); 957 958/* serf_response_handler_t implementation that completely discards 959 * the response. 960 * 961 * All temporary allocations will be made in @a pool. 962 */ 963apr_status_t 964svn_ra_serf__response_discard_handler(serf_request_t *request, 965 serf_bucket_t *response, 966 void *baton, 967 apr_pool_t *pool); 968 969 970/** XML helper functions. **/ 971 972/* 973 * Advance the internal XML @a parser to the @a state. 974 */ 975void 976svn_ra_serf__xml_push_state(svn_ra_serf__xml_parser_t *parser, 977 int state); 978 979/* 980 * Return to the previous internal XML @a parser state. 981 */ 982void 983svn_ra_serf__xml_pop_state(svn_ra_serf__xml_parser_t *parser); 984 985 986svn_error_t * 987svn_ra_serf__process_pending(svn_ra_serf__xml_parser_t *parser, 988 svn_boolean_t *network_eof, 989 apr_pool_t *scratch_pool); 990 991 992/* 993 * Add the appropriate serf buckets to @a agg_bucket represented by 994 * the XML * @a tag and @a value. 995 * 996 * The bucket will be allocated from @a bkt_alloc. 997 */ 998void 999svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket, 1000 const char *tag, 1001 const char *value, 1002 serf_bucket_alloc_t *bkt_alloc); 1003 1004/* 1005 * Add the appropriate serf buckets to AGG_BUCKET with standard XML header: 1006 * <?xml version="1.0" encoding="utf-8"?> 1007 * 1008 * The bucket will be allocated from BKT_ALLOC. 1009 */ 1010void 1011svn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket, 1012 serf_bucket_alloc_t *bkt_alloc); 1013 1014/* 1015 * Add the appropriate serf buckets to AGG_BUCKET representing the XML 1016 * open tag with name TAG. 1017 * 1018 * Take the tag's attributes from varargs, a NULL-terminated list of 1019 * alternating <tt>char *</tt> key and <tt>char *</tt> val. Attribute 1020 * will be ignored if it's value is NULL. 1021 * 1022 * NOTE: Callers are responsible for XML-escaping attribute values as 1023 * necessary. 1024 * 1025 * The bucket will be allocated from BKT_ALLOC. 1026 */ 1027void 1028svn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket, 1029 serf_bucket_alloc_t *bkt_alloc, 1030 const char *tag, 1031 ...); 1032 1033/* 1034 * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close 1035 * with name TAG. 1036 * 1037 * The bucket will be allocated from BKT_ALLOC. 1038 */ 1039void 1040svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket, 1041 serf_bucket_alloc_t *bkt_alloc, 1042 const char *tag); 1043 1044/* 1045 * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped 1046 * version of DATA. 1047 * 1048 * The bucket will be allocated from BKT_ALLOC. 1049 */ 1050void 1051svn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket, 1052 serf_bucket_alloc_t *bkt_alloc, 1053 const char *data, apr_size_t len); 1054/* 1055 * Look up the @a attrs array for namespace definitions and add each one 1056 * to the @a ns_list of namespaces. 1057 * 1058 * New namespaces will be allocated in RESULT_POOL. 1059 */ 1060void 1061svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list, 1062 const char *const *attrs, 1063 apr_pool_t *result_pool); 1064 1065/* 1066 * Look up @a name in the @a ns_list list for previously declared namespace 1067 * definitions. 1068 * 1069 * Return (in @a *returned_prop_name) a #svn_ra_serf__dav_props_t tuple 1070 * representing the expanded name. 1071 */ 1072void 1073svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name, 1074 const svn_ra_serf__ns_t *ns_list, 1075 const char *name); 1076 1077 1078/** PROPFIND-related functions **/ 1079 1080/* 1081 * This function will deliver a PROP_CTX PROPFIND request in the SESS 1082 * serf context for the properties listed in LOOKUP_PROPS at URL for 1083 * DEPTH ("0","1","infinity"). 1084 * 1085 * This function will not block waiting for the response. Callers are 1086 * expected to call svn_ra_serf__wait_for_props(). 1087 */ 1088svn_error_t * 1089svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler, 1090 apr_hash_t *prop_vals, 1091 svn_ra_serf__session_t *sess, 1092 svn_ra_serf__connection_t *conn, 1093 const char *url, 1094 svn_revnum_t rev, 1095 const char *depth, 1096 const svn_ra_serf__dav_props_t *lookup_props, 1097 svn_ra_serf__list_t **done_list, 1098 apr_pool_t *pool); 1099 1100/* 1101 * This helper function will block until PROPFIND_HANDLER indicates that is 1102 * done or another error is returned. 1103 */ 1104svn_error_t * 1105svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler, 1106 apr_pool_t *scratch_pool); 1107 1108/* This is a blocking version of deliver_props. 1109 1110 The properties are fetched and placed into RESULTS, allocated in 1111 RESULT_POOL. 1112 1113 ### more docco about the other params. 1114 1115 Temporary allocations are made in SCRATCH_POOL. 1116*/ 1117svn_error_t * 1118svn_ra_serf__retrieve_props(apr_hash_t **results, 1119 svn_ra_serf__session_t *sess, 1120 svn_ra_serf__connection_t *conn, 1121 const char *url, 1122 svn_revnum_t rev, 1123 const char *depth, 1124 const svn_ra_serf__dav_props_t *props, 1125 apr_pool_t *result_pool, 1126 apr_pool_t *scratch_pool); 1127 1128 1129/* Using CONN, fetch the properties specified by WHICH_PROPS using CONN 1130 for URL at REVISION. The resulting properties are placed into a 2-level 1131 hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which 1132 is allocated in RESULT_POOL. 1133 1134 If REVISION is SVN_INVALID_REVNUM, then the properties are fetched 1135 from HEAD for URL. 1136 1137 This function performs the request synchronously. 1138 1139 Temporary allocations are made in SCRATCH_POOL. */ 1140svn_error_t * 1141svn_ra_serf__fetch_node_props(apr_hash_t **results, 1142 svn_ra_serf__connection_t *conn, 1143 const char *url, 1144 svn_revnum_t revision, 1145 const svn_ra_serf__dav_props_t *which_props, 1146 apr_pool_t *result_pool, 1147 apr_pool_t *scratch_pool); 1148 1149 1150/* Using CONN, fetch a DAV: property from the resource identified by URL 1151 within REVISION. The PROPNAME may be one of: 1152 1153 "checked-in" 1154 "href" 1155 1156 The resulting value will be allocated in RESULT_POOL, and may be NULL 1157 if the property does not exist (note: "href" always exists). 1158 1159 This function performs the request synchronously. 1160 1161 Temporary allocations are made in SCRATCH_POOL. */ 1162svn_error_t * 1163svn_ra_serf__fetch_dav_prop(const char **value, 1164 svn_ra_serf__connection_t *conn, 1165 const char *url, 1166 svn_revnum_t revision, 1167 const char *propname, 1168 apr_pool_t *result_pool, 1169 apr_pool_t *scratch_pool); 1170 1171 1172/* Set PROPS for PATH at REV revision with a NS:NAME VAL. 1173 * 1174 * The POOL governs allocation. 1175 */ 1176void 1177svn_ra_serf__set_ver_prop(apr_hash_t *props, 1178 const char *path, svn_revnum_t rev, 1179 const char *ns, const char *name, 1180 const svn_string_t *val, apr_pool_t *pool); 1181#define svn_ra_serf__set_rev_prop svn_ra_serf__set_ver_prop 1182 1183/** Property walker functions **/ 1184 1185typedef svn_error_t * 1186(*svn_ra_serf__walker_visitor_t)(void *baton, 1187 const char *ns, 1188 const char *name, 1189 const svn_string_t *val, 1190 apr_pool_t *pool); 1191 1192svn_error_t * 1193svn_ra_serf__walk_all_props(apr_hash_t *props, 1194 const char *name, 1195 svn_revnum_t rev, 1196 svn_ra_serf__walker_visitor_t walker, 1197 void *baton, 1198 apr_pool_t *pool); 1199 1200 1201/* Like walk_all_props(), but a 2-level hash. */ 1202svn_error_t * 1203svn_ra_serf__walk_node_props(apr_hash_t *props, 1204 svn_ra_serf__walker_visitor_t walker, 1205 void *baton, 1206 apr_pool_t *scratch_pool); 1207 1208 1209typedef svn_error_t * 1210(*svn_ra_serf__path_rev_walker_t)(void *baton, 1211 const char *path, apr_ssize_t path_len, 1212 const char *ns, apr_ssize_t ns_len, 1213 const char *name, apr_ssize_t name_len, 1214 const svn_string_t *val, 1215 apr_pool_t *pool); 1216svn_error_t * 1217svn_ra_serf__walk_all_paths(apr_hash_t *props, 1218 svn_revnum_t rev, 1219 svn_ra_serf__path_rev_walker_t walker, 1220 void *baton, 1221 apr_pool_t *pool); 1222 1223 1224/* Map a property name, as passed over the wire, into its corresponding 1225 Subversion-internal name. The returned name will be a static value, 1226 or allocated within RESULT_POOL. 1227 1228 If the property should be ignored (eg. some DAV properties), then NULL 1229 will be returned. */ 1230const char * 1231svn_ra_serf__svnname_from_wirename(const char *ns, 1232 const char *name, 1233 apr_pool_t *result_pool); 1234 1235 1236/* Select the basic revision properties from the set of "all" properties. 1237 Return these in *REVPROPS, allocated from RESULT_POOL. */ 1238svn_error_t * 1239svn_ra_serf__select_revprops(apr_hash_t **revprops, 1240 const char *name, 1241 svn_revnum_t rev, 1242 apr_hash_t *all_revprops, 1243 apr_pool_t *result_pool, 1244 apr_pool_t *scratch_pool); 1245 1246 1247/* PROPS is nested hash tables mapping NS -> NAME -> VALUE. 1248 This function takes the NS:NAME:VALUE hashes and flattens them into a set of 1249 names to VALUE. The names are composed of NS:NAME, with specific 1250 rewrite from wire names (DAV) to SVN names. This mapping is managed 1251 by the svn_ra_serf__set_baton_props() function. 1252 1253 FLAT_PROPS is allocated in RESULT_POOL. 1254 ### right now, we do a shallow copy from PROPS to FLAT_PROPS. therefore, 1255 ### the names and values in PROPS must be in the proper pool. 1256 1257 Temporary allocations are made in SCRATCH_POOL. */ 1258svn_error_t * 1259svn_ra_serf__flatten_props(apr_hash_t **flat_props, 1260 apr_hash_t *props, 1261 apr_pool_t *result_pool, 1262 apr_pool_t *scratch_pool); 1263 1264 1265/* Return the property value for PATH at REV revision with a NS:NAME. 1266 * PROPS is a four-level nested hash: (svn_revnum_t => char *path => 1267 * char *ns => char *name => svn_string_t *). */ 1268const svn_string_t * 1269svn_ra_serf__get_ver_prop_string(apr_hash_t *props, 1270 const char *path, svn_revnum_t rev, 1271 const char *ns, const char *name); 1272 1273/* Same as svn_ra_serf__get_ver_prop_string(), but returns a C string. */ 1274const char * 1275svn_ra_serf__get_ver_prop(apr_hash_t *props, 1276 const char *path, svn_revnum_t rev, 1277 const char *ns, const char *name); 1278 1279/* Same as svn_ra_serf__get_ver_prop_string(), but for the unknown revision. */ 1280const svn_string_t * 1281svn_ra_serf__get_prop_string(apr_hash_t *props, 1282 const char *path, 1283 const char *ns, 1284 const char *name); 1285 1286/* Same as svn_ra_serf__get_ver_prop(), but for the unknown revision. */ 1287const char * 1288svn_ra_serf__get_prop(apr_hash_t *props, 1289 const char *path, 1290 const char *ns, 1291 const char *name); 1292 1293/* Same as svn_ra_serf__set_rev_prop(), but for the unknown revision. */ 1294void 1295svn_ra_serf__set_prop(apr_hash_t *props, const char *path, 1296 const char *ns, const char *name, 1297 const svn_string_t *val, apr_pool_t *pool); 1298 1299svn_error_t * 1300svn_ra_serf__get_resource_type(svn_node_kind_t *kind, 1301 apr_hash_t *props); 1302 1303 1304/** MERGE-related functions **/ 1305 1306void 1307svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens, 1308 const char *parent, 1309 serf_bucket_t *body, 1310 serf_bucket_alloc_t *alloc, 1311 apr_pool_t *pool); 1312 1313/* Create an MERGE request aimed at the SESSION url, requesting the 1314 merge of the resource identified by MERGE_RESOURCE_URL. 1315 LOCK_TOKENS is a hash mapping paths to lock tokens owned by the 1316 client. If KEEP_LOCKS is set, instruct the server to not release 1317 locks set on the paths included in this commit. */ 1318svn_error_t * 1319svn_ra_serf__run_merge(const svn_commit_info_t **commit_info, 1320 int *response_code, 1321 svn_ra_serf__session_t *session, 1322 svn_ra_serf__connection_t *conn, 1323 const char *merge_resource_url, 1324 apr_hash_t *lock_tokens, 1325 svn_boolean_t keep_locks, 1326 apr_pool_t *result_pool, 1327 apr_pool_t *scratch_pool); 1328 1329 1330/** OPTIONS-related functions **/ 1331 1332/* When running with a proxy, we may need to detect and correct for problems. 1333 This probing function will send a simple OPTIONS request to detect problems 1334 with the connection. */ 1335svn_error_t * 1336svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess, 1337 apr_pool_t *scratch_pool); 1338 1339 1340/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the 1341 current youngest revnum, returning it in *YOUNGEST. 1342 1343 (the revnum is headers of the OPTIONS response) 1344 1345 This function performs the request synchronously. 1346 1347 All temporary allocations will be made in SCRATCH_POOL. */ 1348svn_error_t * 1349svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest, 1350 svn_ra_serf__connection_t *conn, 1351 apr_pool_t *scratch_pool); 1352 1353 1354/* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the 1355 activity collection set and return it in *ACTIVITY_URL, allocated 1356 from RESULT_POOL. 1357 1358 (the activity-collection-set is in the body of the OPTIONS response) 1359 1360 This function performs the request synchronously. 1361 1362 All temporary allocations will be made in SCRATCH_POOL. */ 1363svn_error_t * 1364svn_ra_serf__v1_get_activity_collection(const char **activity_url, 1365 svn_ra_serf__connection_t *conn, 1366 apr_pool_t *result_pool, 1367 apr_pool_t *scratch_pool); 1368 1369 1370/* Set @a VCC_URL to the default VCC for our repository based on @a 1371 * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and 1372 * repository root URLs are cached in @a SESSION. Use @a CONN for any 1373 * required network communications if it is non-NULL; otherwise use the 1374 * default connection. 1375 * 1376 * All temporary allocations will be made in @a POOL. */ 1377svn_error_t * 1378svn_ra_serf__discover_vcc(const char **vcc_url, 1379 svn_ra_serf__session_t *session, 1380 svn_ra_serf__connection_t *conn, 1381 apr_pool_t *pool); 1382 1383/* Set @a REPORT_TARGET to the URI of the resource at which generic 1384 * (path-agnostic) REPORTs should be aimed for @a SESSION. Use @a 1385 * CONN for any required network communications if it is non-NULL; 1386 * otherwise use the default connection. 1387 * 1388 * All temporary allocations will be made in @a POOL. 1389 */ 1390svn_error_t * 1391svn_ra_serf__report_resource(const char **report_target, 1392 svn_ra_serf__session_t *session, 1393 svn_ra_serf__connection_t *conn, 1394 apr_pool_t *pool); 1395 1396/* Set @a REL_PATH to a path (not URI-encoded) relative to the root of 1397 * the repository pointed to by @a SESSION, based on original path 1398 * (URI-encoded) @a ORIG_PATH. Use @a CONN for any required network 1399 * communications if it is non-NULL; otherwise use the default 1400 * connection. Use POOL for allocations. */ 1401svn_error_t * 1402svn_ra_serf__get_relative_path(const char **rel_path, 1403 const char *orig_path, 1404 svn_ra_serf__session_t *session, 1405 svn_ra_serf__connection_t *conn, 1406 apr_pool_t *pool); 1407 1408 1409/* Using the default connection in SESSION (conns[0]), get the youngest 1410 revnum from the server, returning it in *YOUNGEST. 1411 1412 This function operates synchronously. 1413 1414 All temporary allocations are performed in SCRATCH_POOL. */ 1415svn_error_t * 1416svn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest, 1417 svn_ra_serf__session_t *session, 1418 apr_pool_t *scratch_pool); 1419 1420 1421/* Generate a revision-stable URL. 1422 1423 The RA APIs all refer to user/public URLs that float along with the 1424 youngest revision. In many cases, we do NOT want to work with that URL 1425 since it can change from one moment to the next. Especially if we 1426 attempt to operation against multiple floating URLs -- we could end up 1427 referring to two separate revisions. 1428 1429 The DAV RA provider(s) solve this by generating a URL that is specific 1430 to a revision by using a URL into a "baseline collection". 1431 1432 For a specified SESSION, with an optional CONN (if NULL, then the 1433 session's default connection will be used; specifically SESSION->conns[0]), 1434 generate a revision-stable URL for URL at REVISION. If REVISION is 1435 SVN_INVALID_REVNUM, then the stable URL will refer to the youngest 1436 revision at the time this function was called. 1437 1438 If URL is NULL, then the session root will be used. 1439 1440 The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL. 1441 1442 If LATEST_REVNUM is not NULL, then the revision used will be placed into 1443 *LATEST_REVNUM. That will be equal to youngest, or the given REVISION. 1444 1445 This function operates synchronously, if any communication to the server 1446 is required. Communication is needed if REVISION is SVN_INVALID_REVNUM 1447 (to get the current youngest revnum), or if the specified REVISION is not 1448 (yet) in our cache of baseline collections. 1449 1450 All temporary allocations are performed in SCRATCH_POOL. */ 1451svn_error_t * 1452svn_ra_serf__get_stable_url(const char **stable_url, 1453 svn_revnum_t *latest_revnum, 1454 svn_ra_serf__session_t *session, 1455 svn_ra_serf__connection_t *conn, 1456 const char *url, 1457 svn_revnum_t revision, 1458 apr_pool_t *result_pool, 1459 apr_pool_t *scratch_pool); 1460 1461 1462/** RA functions **/ 1463 1464/* Implements svn_ra__vtable_t.get_log(). */ 1465svn_error_t * 1466svn_ra_serf__get_log(svn_ra_session_t *session, 1467 const apr_array_header_t *paths, 1468 svn_revnum_t start, 1469 svn_revnum_t end, 1470 int limit, 1471 svn_boolean_t discover_changed_paths, 1472 svn_boolean_t strict_node_history, 1473 svn_boolean_t include_merged_revisions, 1474 const apr_array_header_t *revprops, 1475 svn_log_entry_receiver_t receiver, 1476 void *receiver_baton, 1477 apr_pool_t *pool); 1478 1479/* Implements svn_ra__vtable_t.get_locations(). */ 1480svn_error_t * 1481svn_ra_serf__get_locations(svn_ra_session_t *session, 1482 apr_hash_t **locations, 1483 const char *path, 1484 svn_revnum_t peg_revision, 1485 const apr_array_header_t *location_revisions, 1486 apr_pool_t *pool); 1487 1488/* Implements svn_ra__vtable_t.get_location_segments(). */ 1489svn_error_t * 1490svn_ra_serf__get_location_segments(svn_ra_session_t *session, 1491 const char *path, 1492 svn_revnum_t peg_revision, 1493 svn_revnum_t start_rev, 1494 svn_revnum_t end_rev, 1495 svn_location_segment_receiver_t receiver, 1496 void *receiver_baton, 1497 apr_pool_t *pool); 1498 1499/* Implements svn_ra__vtable_t.do_diff(). */ 1500svn_error_t * 1501svn_ra_serf__do_diff(svn_ra_session_t *session, 1502 const svn_ra_reporter3_t **reporter, 1503 void **report_baton, 1504 svn_revnum_t revision, 1505 const char *diff_target, 1506 svn_depth_t depth, 1507 svn_boolean_t ignore_ancestry, 1508 svn_boolean_t text_deltas, 1509 const char *versus_url, 1510 const svn_delta_editor_t *diff_editor, 1511 void *diff_baton, 1512 apr_pool_t *pool); 1513 1514/* Implements svn_ra__vtable_t.do_status(). */ 1515svn_error_t * 1516svn_ra_serf__do_status(svn_ra_session_t *ra_session, 1517 const svn_ra_reporter3_t **reporter, 1518 void **report_baton, 1519 const char *status_target, 1520 svn_revnum_t revision, 1521 svn_depth_t depth, 1522 const svn_delta_editor_t *status_editor, 1523 void *status_baton, 1524 apr_pool_t *pool); 1525 1526/* Implements svn_ra__vtable_t.do_update(). */ 1527svn_error_t * 1528svn_ra_serf__do_update(svn_ra_session_t *ra_session, 1529 const svn_ra_reporter3_t **reporter, 1530 void **report_baton, 1531 svn_revnum_t revision_to_update_to, 1532 const char *update_target, 1533 svn_depth_t depth, 1534 svn_boolean_t send_copyfrom_args, 1535 svn_boolean_t ignore_ancestry, 1536 const svn_delta_editor_t *update_editor, 1537 void *update_baton, 1538 apr_pool_t *result_pool, 1539 apr_pool_t *scratch_pool); 1540 1541/* Implements svn_ra__vtable_t.do_switch(). */ 1542svn_error_t * 1543svn_ra_serf__do_switch(svn_ra_session_t *ra_session, 1544 const svn_ra_reporter3_t **reporter, 1545 void **report_baton, 1546 svn_revnum_t revision_to_switch_to, 1547 const char *switch_target, 1548 svn_depth_t depth, 1549 const char *switch_url, 1550 svn_boolean_t send_copyfrom_args, 1551 svn_boolean_t ignore_ancestry, 1552 const svn_delta_editor_t *switch_editor, 1553 void *switch_baton, 1554 apr_pool_t *result_pool, 1555 apr_pool_t *scratch_pool); 1556 1557/* Implements svn_ra__vtable_t.get_file_revs(). */ 1558svn_error_t * 1559svn_ra_serf__get_file_revs(svn_ra_session_t *session, 1560 const char *path, 1561 svn_revnum_t start, 1562 svn_revnum_t end, 1563 svn_boolean_t include_merged_revisions, 1564 svn_file_rev_handler_t handler, 1565 void *handler_baton, 1566 apr_pool_t *pool); 1567 1568/* Implements svn_ra__vtable_t.get_dated_revision(). */ 1569svn_error_t * 1570svn_ra_serf__get_dated_revision(svn_ra_session_t *session, 1571 svn_revnum_t *revision, 1572 apr_time_t tm, 1573 apr_pool_t *pool); 1574 1575/* Implements svn_ra__vtable_t.get_commit_editor(). */ 1576svn_error_t * 1577svn_ra_serf__get_commit_editor(svn_ra_session_t *session, 1578 const svn_delta_editor_t **editor, 1579 void **edit_baton, 1580 apr_hash_t *revprop_table, 1581 svn_commit_callback2_t callback, 1582 void *callback_baton, 1583 apr_hash_t *lock_tokens, 1584 svn_boolean_t keep_locks, 1585 apr_pool_t *pool); 1586 1587/* Implements svn_ra__vtable_t.get_file(). */ 1588svn_error_t * 1589svn_ra_serf__get_file(svn_ra_session_t *session, 1590 const char *path, 1591 svn_revnum_t revision, 1592 svn_stream_t *stream, 1593 svn_revnum_t *fetched_rev, 1594 apr_hash_t **props, 1595 apr_pool_t *pool); 1596 1597/* Implements svn_ra__vtable_t.change_rev_prop(). */ 1598svn_error_t * 1599svn_ra_serf__change_rev_prop(svn_ra_session_t *session, 1600 svn_revnum_t rev, 1601 const char *name, 1602 const svn_string_t *const *old_value_p, 1603 const svn_string_t *value, 1604 apr_pool_t *pool); 1605 1606/* Implements svn_ra__vtable_t.replay(). */ 1607svn_error_t * 1608svn_ra_serf__replay(svn_ra_session_t *ra_session, 1609 svn_revnum_t revision, 1610 svn_revnum_t low_water_mark, 1611 svn_boolean_t text_deltas, 1612 const svn_delta_editor_t *editor, 1613 void *edit_baton, 1614 apr_pool_t *pool); 1615 1616/* Implements svn_ra__vtable_t.replay_range(). */ 1617svn_error_t * 1618svn_ra_serf__replay_range(svn_ra_session_t *ra_session, 1619 svn_revnum_t start_revision, 1620 svn_revnum_t end_revision, 1621 svn_revnum_t low_water_mark, 1622 svn_boolean_t send_deltas, 1623 svn_ra_replay_revstart_callback_t revstart_func, 1624 svn_ra_replay_revfinish_callback_t revfinish_func, 1625 void *replay_baton, 1626 apr_pool_t *pool); 1627 1628/* Implements svn_ra__vtable_t.lock(). */ 1629svn_error_t * 1630svn_ra_serf__lock(svn_ra_session_t *ra_session, 1631 apr_hash_t *path_revs, 1632 const char *comment, 1633 svn_boolean_t force, 1634 svn_ra_lock_callback_t lock_func, 1635 void *lock_baton, 1636 apr_pool_t *pool); 1637 1638/* Implements svn_ra__vtable_t.unlock(). */ 1639svn_error_t * 1640svn_ra_serf__unlock(svn_ra_session_t *ra_session, 1641 apr_hash_t *path_tokens, 1642 svn_boolean_t force, 1643 svn_ra_lock_callback_t lock_func, 1644 void *lock_baton, 1645 apr_pool_t *pool); 1646 1647/* Implements svn_ra__vtable_t.get_lock(). */ 1648svn_error_t * 1649svn_ra_serf__get_lock(svn_ra_session_t *ra_session, 1650 svn_lock_t **lock, 1651 const char *path, 1652 apr_pool_t *pool); 1653 1654/* Implements svn_ra__vtable_t.get_locks(). */ 1655svn_error_t * 1656svn_ra_serf__get_locks(svn_ra_session_t *ra_session, 1657 apr_hash_t **locks, 1658 const char *path, 1659 svn_depth_t depth, 1660 apr_pool_t *pool); 1661 1662/* Request a mergeinfo-report from the URL attached to SESSION, 1663 and fill in the MERGEINFO hash with the results. 1664 1665 Implements svn_ra__vtable_t.get_mergeinfo(). 1666 */ 1667svn_error_t * 1668svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session, 1669 apr_hash_t **mergeinfo, 1670 const apr_array_header_t *paths, 1671 svn_revnum_t revision, 1672 svn_mergeinfo_inheritance_t inherit, 1673 svn_boolean_t include_descendants, 1674 apr_pool_t *pool); 1675 1676/* Exchange capabilities with the server, by sending an OPTIONS 1677 * request announcing the client's capabilities, and by filling 1678 * SERF_SESS->capabilities with the server's capabilities as read from 1679 * the response headers. Use POOL only for temporary allocation. 1680 * 1681 * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to 1682 * report a server-dictated redirect or relocation (HTTP 301 or 302 1683 * error codes), setting *CORRECTED_URL to the value of the corrected 1684 * repository URL. Otherwise, such responses from the server will 1685 * generate an error. (In either case, no capabilities are exchanged 1686 * if there is, in fact, such a response from the server.) 1687 */ 1688svn_error_t * 1689svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess, 1690 const char **corrected_url, 1691 apr_pool_t *pool); 1692 1693/* Implements svn_ra__vtable_t.has_capability(). */ 1694svn_error_t * 1695svn_ra_serf__has_capability(svn_ra_session_t *ra_session, 1696 svn_boolean_t *has, 1697 const char *capability, 1698 apr_pool_t *pool); 1699 1700/* Implements svn_ra__vtable_t.get_deleted_rev(). */ 1701svn_error_t * 1702svn_ra_serf__get_deleted_rev(svn_ra_session_t *session, 1703 const char *path, 1704 svn_revnum_t peg_revision, 1705 svn_revnum_t end_revision, 1706 svn_revnum_t *revision_deleted, 1707 apr_pool_t *pool); 1708 1709/* Implements the get_inherited_props RA layer function. */ 1710svn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session, 1711 apr_array_header_t **iprops, 1712 const char *path, 1713 svn_revnum_t revision, 1714 apr_pool_t *result_pool, 1715 apr_pool_t *scratch_pool); 1716 1717/* Implements svn_ra__vtable_t.get_repos_root(). */ 1718svn_error_t * 1719svn_ra_serf__get_repos_root(svn_ra_session_t *ra_session, 1720 const char **url, 1721 apr_pool_t *pool); 1722 1723/* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */ 1724svn_error_t * 1725svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session, 1726 svn_delta_shim_callbacks_t *callbacks); 1727 1728/*** Authentication handler declarations ***/ 1729 1730/** 1731 * Callback function that loads the credentials for Basic and Digest 1732 * authentications, both for server and proxy authentication. 1733 */ 1734apr_status_t 1735svn_ra_serf__credentials_callback(char **username, char **password, 1736 serf_request_t *request, void *baton, 1737 int code, const char *authn_type, 1738 const char *realm, 1739 apr_pool_t *pool); 1740 1741 1742/*** General utility functions ***/ 1743 1744/** 1745 * Convert an HTTP STATUS_CODE resulting from a WebDAV request against 1746 * PATH to the relevant error code. Use the response-supplied LOCATION 1747 * where it necessary. 1748 */ 1749svn_error_t * 1750svn_ra_serf__error_on_status(serf_status_line sline, 1751 const char *path, 1752 const char *location); 1753 1754/* ###? */ 1755svn_error_t * 1756svn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf, 1757 serf_bucket_t *bkt, 1758 apr_pool_t *result_pool, 1759 apr_pool_t *scratch_pool); 1760 1761/* ###? */ 1762serf_bucket_t * 1763svn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf, 1764 serf_bucket_alloc_t *allocator, 1765 apr_pool_t *result_pool, 1766 apr_pool_t *scratch_pool); 1767 1768/** Wrap STATUS from an serf function. If STATUS is not serf error code, 1769 * this is equivalent to svn_error_wrap_apr(). 1770 */ 1771svn_error_t * 1772svn_ra_serf__wrap_err(apr_status_t status, 1773 const char *fmt, 1774 ...); 1775 1776 1777#if defined(SVN_DEBUG) 1778/* Wrapper macros to collect file and line information */ 1779#define svn_ra_serf__wrap_err \ 1780 (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err)) 1781 1782#endif 1783 1784#ifdef __cplusplus 1785} 1786#endif /* __cplusplus */ 1787 1788#endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */ 1789