ra_serf.h revision 299742
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/** Wait duration (in microseconds) used in calls to serf_context_run() */ 58#define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000 59 60 61 62/* Forward declarations. */ 63typedef struct svn_ra_serf__session_t svn_ra_serf__session_t; 64 65/* A serf connection and optionally associated SSL context. */ 66typedef struct svn_ra_serf__connection_t { 67 /* Our connection to a server. */ 68 serf_connection_t *conn; 69 70 /* Bucket allocator for this connection. */ 71 serf_bucket_alloc_t *bkt_alloc; 72 73 /* Collected cert failures in chain. */ 74 int server_cert_failures; 75 76 /* What was the last HTTP status code we got on this connection? */ 77 int last_status_code; 78 79 /* Optional SSL context for this connection. */ 80 serf_ssl_context_t *ssl_context; 81 svn_auth_iterstate_t *ssl_client_auth_state; 82 svn_auth_iterstate_t *ssl_client_pw_auth_state; 83 84 svn_ra_serf__session_t *session; 85 86} svn_ra_serf__connection_t; 87 88/** Maximum value we'll allow for the http-max-connections config option. 89 * 90 * Note: minimum 2 connections are required for ra_serf to function 91 * correctly! 92 */ 93#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8 94 95/* 96 * The master serf RA session. 97 * 98 * This is stored in the ra session ->priv field. 99 * 100 * ### Check ra_serf_dup_session when adding fields. 101 */ 102struct svn_ra_serf__session_t { 103 /* Pool for allocations during this session */ 104 apr_pool_t *pool; 105 apr_hash_t *config; /* For duplicating */ 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 svn_auth_baton_t *auth_baton; 158 159 /* Callback function to send progress info to the client */ 160 svn_ra_progress_notify_func_t progress_func; 161 void *progress_baton; 162 163 /* Callback function to handle cancellation */ 164 svn_cancel_func_t cancel_func; 165 void *cancel_baton; 166 167 /* Ev2 shim callbacks */ 168 svn_delta_shim_callbacks_t *shim_callbacks; 169 170 /* Error that we've received but not yet returned upstream. */ 171 svn_error_t *pending_error; 172 173 /* List of authn types supported by the client.*/ 174 int authn_types; 175 176 /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values. 177 If a capability is not yet discovered, it is absent from the table. 178 The table itself is allocated in the svn_ra_serf__session_t's pool; 179 keys and values must have at least that lifetime. Most likely 180 the keys and values are constants anyway (and sufficiently 181 well-informed internal code may just compare against those 182 constants' addresses, therefore). */ 183 apr_hash_t *capabilities; 184 185 /* Activity collection URL. (Cached from the initial OPTIONS 186 request when run against HTTPv1 servers.) */ 187 const char *activity_collection_url; 188 189 /* Are we using a proxy? */ 190 svn_boolean_t using_proxy; 191 192 const char *proxy_username; 193 const char *proxy_password; 194 int proxy_auth_attempts; 195 196 /* SSL server certificates */ 197 svn_boolean_t trust_default_ca; 198 const char *ssl_authorities; 199 200 /* Repository UUID */ 201 const char *uuid; 202 203 /* Connection timeout value */ 204 apr_interval_time_t timeout; 205 206 /* HTTPv1 flags */ 207 svn_tristate_t supports_deadprop_count; 208 209 /*** HTTP v2 protocol stuff. *** 210 * 211 * We assume that if mod_dav_svn sends one of the special v2 OPTIONs 212 * response headers, it has sent all of them. Specifically, we'll 213 * be looking at the presence of the "me resource" as a flag that 214 * the server supports v2 of our HTTP protocol. 215 */ 216 217 /* The "me resource". Typically used as a target for REPORTs that 218 are path-agnostic. If we have this, we can speak HTTP v2 to the 219 server. */ 220 const char *me_resource; 221 222 /* Opaque URL "stubs". If the OPTIONS response returns these, then 223 we know we're using HTTP protocol v2. */ 224 const char *rev_stub; /* for accessing revisions (i.e. revprops) */ 225 const char *rev_root_stub; /* for accessing REV/PATH pairs */ 226 const char *txn_stub; /* for accessing transactions (i.e. txnprops) */ 227 const char *txn_root_stub; /* for accessing TXN/PATH pairs */ 228 const char *vtxn_stub; /* for accessing transactions (i.e. txnprops) */ 229 const char *vtxn_root_stub; /* for accessing TXN/PATH pairs */ 230 231 /* Hash mapping const char * server-supported POST types to 232 disinteresting-but-non-null values. */ 233 apr_hash_t *supported_posts; 234 235 /*** End HTTP v2 stuff ***/ 236 237 svn_ra_serf__blncache_t *blncache; 238 239 /* Trisate flag that indicates user preference for using bulk updates 240 (svn_tristate_true) with all the properties and content in the 241 update-report response. If svn_tristate_false, request a skelta 242 update-report with inlined properties. If svn_tristate_unknown then use 243 server preference. */ 244 svn_tristate_t bulk_updates; 245 246 /* Indicates if the server wants bulk update requests (Prefer) or only 247 accepts skelta requests (Off). If this value is On both options are 248 allowed. */ 249 const char *server_allows_bulk; 250 251 /* Indicates if the server supports sending inlined props in update editor 252 * in skelta mode (send-all == 'false'). */ 253 svn_boolean_t supports_inline_props; 254 255 /* Indicates whether the server supports issuing replay REPORTs 256 against rev resources (children of `rev_stub', elsestruct). */ 257 svn_boolean_t supports_rev_rsrc_replay; 258}; 259 260#define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL) 261 262/* 263 * Structure which represents a DAV element with a NAMESPACE and NAME. 264 */ 265typedef struct svn_ra_serf__dav_props_t { 266 /* Element namespace */ 267 const char *xmlns; 268 /* Element name */ 269 const char *name; 270} svn_ra_serf__dav_props_t; 271 272/** DAV property sets **/ 273 274static const svn_ra_serf__dav_props_t base_props[] = 275{ 276 { "DAV:", "version-controlled-configuration" }, 277 { "DAV:", "resourcetype" }, 278 { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" }, 279 { SVN_DAV_PROP_NS_DAV, "repository-uuid" }, 280 { NULL } 281}; 282 283static const svn_ra_serf__dav_props_t checked_in_props[] = 284{ 285 { "DAV:", "checked-in" }, 286 { NULL } 287}; 288 289static const svn_ra_serf__dav_props_t baseline_props[] = 290{ 291 { "DAV:", "baseline-collection" }, 292 { "DAV:", SVN_DAV__VERSION_NAME }, 293 { NULL } 294}; 295 296static const svn_ra_serf__dav_props_t all_props[] = 297{ 298 { "DAV:", "allprop" }, 299 { NULL } 300}; 301 302static const svn_ra_serf__dav_props_t check_path_props[] = 303{ 304 { "DAV:", "resourcetype" }, 305 { NULL } 306}; 307 308static const svn_ra_serf__dav_props_t type_and_checksum_props[] = 309{ 310 { "DAV:", "resourcetype" }, 311 { SVN_DAV_PROP_NS_DAV, "sha1-checksum" }, 312 { NULL } 313}; 314 315/* WC props compatibility with ra_neon. */ 316#define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url" 317 318/** Serf utility functions **/ 319 320apr_status_t 321svn_ra_serf__conn_setup(apr_socket_t *sock, 322 serf_bucket_t **read_bkt, 323 serf_bucket_t **write_bkt, 324 void *baton, 325 apr_pool_t *pool); 326 327void 328svn_ra_serf__conn_closed(serf_connection_t *conn, 329 void *closed_baton, 330 apr_status_t why, 331 apr_pool_t *pool); 332 333 334/* Helper function to provide SSL client certificates. 335 * 336 * NOTE: This function sets the session's 'pending_error' member when 337 * returning an non-success status. 338 */ 339apr_status_t 340svn_ra_serf__handle_client_cert(void *data, 341 const char **cert_path); 342 343/* Helper function to provide SSL client certificate passwords. 344 * 345 * NOTE: This function sets the session's 'pending_error' member when 346 * returning an non-success status. 347 */ 348apr_status_t 349svn_ra_serf__handle_client_cert_pw(void *data, 350 const char *cert_path, 351 const char **password); 352 353 354/* 355 * This function will run the serf context in SESS until *DONE is TRUE. 356 */ 357svn_error_t * 358svn_ra_serf__context_run_wait(svn_boolean_t *done, 359 svn_ra_serf__session_t *sess, 360 apr_pool_t *scratch_pool); 361 362/* Run the context once. Manage waittime_left to handle timing out when 363 nothing happens over the session->timout. 364 */ 365svn_error_t * 366svn_ra_serf__context_run(svn_ra_serf__session_t *sess, 367 apr_interval_time_t *waittime_left, 368 apr_pool_t *scratch_pool); 369 370 371 372/* Callback for response handlers */ 373typedef svn_error_t * 374(*svn_ra_serf__response_handler_t)(serf_request_t *request, 375 serf_bucket_t *response, 376 void *handler_baton, 377 apr_pool_t *scratch_pool); 378 379/* Callback when the request is done */ 380typedef svn_error_t * 381(*svn_ra_serf__response_done_delegate_t)(serf_request_t *request, 382 void *done_baton, 383 apr_pool_t *scratch_pool); 384 385/* Callback for when a request body is needed. */ 386typedef svn_error_t * 387(*svn_ra_serf__request_body_delegate_t)(serf_bucket_t **body_bkt, 388 void *baton, 389 serf_bucket_alloc_t *alloc, 390 apr_pool_t *request_pool, 391 apr_pool_t *scratch_pool); 392 393/* Callback for when request headers are needed. */ 394typedef svn_error_t * 395(*svn_ra_serf__request_header_delegate_t)(serf_bucket_t *headers, 396 void *baton, 397 apr_pool_t *request_pool, 398 apr_pool_t *scratch_pool); 399 400/* Callback for when a response has an error. */ 401typedef svn_error_t * 402(*svn_ra_serf__response_error_t)(serf_request_t *request, 403 serf_bucket_t *response, 404 int status_code, 405 void *baton); 406 407/* ### we should reorder the types in this file. */ 408typedef struct svn_ra_serf__server_error_t svn_ra_serf__server_error_t; 409 410/* 411 * Structure that can be passed to our default handler to guide the 412 * execution of the request through its lifecycle. 413 * 414 * Use svn_ra_serf__create_handler() to create instances of this struct. 415 */ 416typedef struct svn_ra_serf__handler_t { 417 /* The HTTP method string of the request */ 418 const char *method; 419 420 /* The resource to the execute the method on. */ 421 const char *path; 422 423 /* The content-type of the request body. */ 424 const char *body_type; 425 426 /* If TRUE then default Accept-Encoding request header is not configured for 427 request. If FALSE then 'gzip' accept encoding will be used if compression 428 enabled. */ 429 svn_boolean_t custom_accept_encoding; 430 431 /* If TRUE then default DAV: capabilities request headers is not configured 432 for request. */ 433 svn_boolean_t no_dav_headers; 434 435 /* If TRUE doesn't fail requests on HTTP error statuses like 405, 408, 500 436 (see util.c response_done()) */ 437 svn_boolean_t no_fail_on_http_failure_status; 438 439 /* If TRUE doesn't fail requests on HTTP redirect statuses like 301, 307 */ 440 svn_boolean_t no_fail_on_http_redirect_status; 441 442 /* Has the request/response been completed? */ 443 svn_boolean_t done; 444 svn_boolean_t scheduled; /* Is the request scheduled in a context */ 445 446 /* If we captured an error from the server, then this will be non-NULL. 447 It will be allocated from HANDLER_POOL. */ 448 svn_ra_serf__server_error_t *server_error; 449 450 /* The handler and baton pair for our handler. */ 451 svn_ra_serf__response_handler_t response_handler; 452 void *response_baton; 453 454 /* When REPONSE_HANDLER is invoked, the following fields will be set 455 based on the response header. HANDLER_POOL must be non-NULL for these 456 values to be filled in. SLINE.REASON and LOCATION will be allocated 457 within HANDLER_POOL. */ 458 serf_status_line sline; /* The parsed Status-Line */ 459 const char *location; /* The Location: header, if any */ 460 461 /* This function and baton pair allows handling the completion of request. 462 * 463 * The default handler is responsible for the HTTP failure processing. 464 * 465 * If no_fail_on_http_failure_status is not TRUE, then the callback will 466 * return recorded server errors or if there is none and the http status 467 * specifies an error returns an error for that. 468 * 469 * The default baton is the handler itself. 470 */ 471 svn_ra_serf__response_done_delegate_t done_delegate; 472 void *done_delegate_baton; 473 474 /* The handler and baton pair to be executed when a non-recoverable error 475 * is detected. If it is NULL in the presence of an error, an abort() may 476 * be triggered. 477 */ 478 svn_ra_serf__response_error_t response_error; 479 void *response_error_baton; 480 481 /* This function and baton pair allows for custom request headers to 482 * be set. 483 * 484 * It will be executed after the request has been set up but before it is 485 * delivered. 486 */ 487 svn_ra_serf__request_header_delegate_t header_delegate; 488 void *header_delegate_baton; 489 490 /* This function and baton pair allows a body to be created right before 491 * delivery. 492 * 493 * It will be executed after the request has been set up but before it is 494 * delivered. 495 * 496 * May be NULL if there is no body to send. 497 * 498 */ 499 svn_ra_serf__request_body_delegate_t body_delegate; 500 void *body_delegate_baton; 501 502 /* The connection and session to be used for this request. */ 503 svn_ra_serf__connection_t *conn; 504 svn_ra_serf__session_t *session; 505 506 /* Internal flag to indicate we've parsed the headers. */ 507 svn_boolean_t reading_body; 508 509 /* When this flag will be set, the core handler will discard any unread 510 portion of the response body. The registered response handler will 511 no longer be called. */ 512 svn_boolean_t discard_body; 513 514 /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL, 515 then the requestor does not care about SLINE and LOCATION. */ 516 apr_pool_t *handler_pool; 517} svn_ra_serf__handler_t; 518 519 520/* Run one request and process the response. 521 522 Similar to context_run_wait(), but this creates the request for HANDLER 523 and then waits for it to complete. 524 525 WARNING: context_run_wait() does NOT create a request, whereas this 526 function DOES. Avoid a double-create. */ 527svn_error_t * 528svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler, 529 apr_pool_t *scratch_pool); 530 531 532/* 533 * Helper function to queue a request in the @a handler's connection. 534 */ 535void svn_ra_serf__request_create(svn_ra_serf__handler_t *handler); 536 537/* v2 of the XML parsing functions */ 538 539/* The XML parsing context. */ 540typedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t; 541 542 543/* An opaque structure for the XML parse element/state. */ 544typedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t; 545 546/* Called just after the parser moves into ENTERED_STATE. The tag causing 547 the transition is passed in TAG. 548 549 This callback is applied to a parsing context by using the 550 svn_ra_serf__xml_context_customize() function. 551 552 NOTE: this callback, when set, will be invoked on *every* transition. 553 The callback must examine ENTERED_STATE to determine if any action 554 must be taken. The original state is not provided, but must be derived 555 from ENTERED_STATE and/or the TAG causing the transition (if needed). */ 556typedef svn_error_t * 557(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes, 558 void *baton, 559 int entered_state, 560 const svn_ra_serf__dav_props_t *tag, 561 apr_pool_t *scratch_pool); 562 563 564/* Called just before the parser leaves LEAVING_STATE. 565 566 If cdata collection was enabled for this state, then CDATA will be 567 non-NULL and contain the collected cdata. 568 569 If attribute collection was enabled for this state, then ATTRS will 570 contain the attributes collected for this element only, along with 571 any values stored via svn_ra_serf__xml_note(). 572 573 Use svn_ra_serf__xml_gather_since() to gather up data from outer states. 574 575 ATTRS is char* -> char*. 576 577 Temporary allocations may be made in SCRATCH_POOL. */ 578typedef svn_error_t * 579(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes, 580 void *baton, 581 int leaving_state, 582 const svn_string_t *cdata, 583 apr_hash_t *attrs, 584 apr_pool_t *scratch_pool); 585 586 587/* Called for all states that are not using the builtin cdata collection. 588 This callback is (only) appropriate for unbounded-size cdata content. 589 590 CURRENT_STATE may be used to decide what to do with the data. 591 592 Temporary allocations may be made in SCRATCH_POOL. */ 593typedef svn_error_t * 594(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes, 595 void *baton, 596 int current_state, 597 const char *data, 598 apr_size_t len, 599 apr_pool_t *scratch_pool); 600 601 602/* Magic state value for the initial state in a svn_ra_serf__xml_transition_t 603 table */ 604#define XML_STATE_INITIAL 0 605 606/* State transition table. 607 608 When the XML Context is constructed, it is in state 0. User states are 609 positive integers. 610 611 In a list of transitions, use { 0 } to indicate the end. Specifically, 612 the code looks for NS == NULL. 613 614 The initial state for each transition table is XML_STATE_INITIAL. 615 616 ### more docco 617*/ 618typedef struct svn_ra_serf__xml_transition_t { 619 /* This transition applies when in this state */ 620 int from_state; 621 622 /* And when this tag is observed */ 623 const char *ns; 624 const char *name; 625 626 /* Moving to this state */ 627 int to_state; 628 629 /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should 630 be TRUE in order to capture this cdata. */ 631 svn_boolean_t collect_cdata; 632 633 /* Which attributes of NAME should be collected? Terminate with NULL. 634 Maximum of 10 attributes may be collected. Note that attribute 635 namespaces are ignored at this time. 636 637 Attribute names beginning with "?" are optional. Other names must 638 exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised. */ 639 const char *collect_attrs[11]; 640 641 /* When NAME is closed, should the callback be invoked? */ 642 svn_boolean_t custom_close; 643 644} svn_ra_serf__xml_transition_t; 645 646/* Constructor for svn_ra_serf__handler_t. Initializes a new handler 647 with default settings for SESSION. */ 648svn_ra_serf__handler_t * 649svn_ra_serf__create_handler(svn_ra_serf__session_t *session, 650 apr_pool_t *result_pool); 651 652/* Construct an XML parsing context, based on the TTABLE transition table. 653 As content is parsed, the CLOSED_CB callback will be invoked according 654 to the definition in the table. 655 656 If OPENED_CB is not NULL, then it will be invoked for *every* tag-open 657 event. The callback will need to use the ENTERED_STATE and TAG parameters 658 to decide what it would like to do. 659 660 If CDATA_CB is not NULL, then it will be called for all cdata that is 661 not be automatically collected (based on the transition table record's 662 COLLECT_CDATA flag). It will be called in every state, so the callback 663 must examine the CURRENT_STATE parameter to decide what to do. 664 665 The same BATON value will be passed to all three callbacks. 666 667 The context will be created within RESULT_POOL. */ 668svn_ra_serf__xml_context_t * 669svn_ra_serf__xml_context_create( 670 const svn_ra_serf__xml_transition_t *ttable, 671 svn_ra_serf__xml_opened_t opened_cb, 672 svn_ra_serf__xml_closed_t closed_cb, 673 svn_ra_serf__xml_cdata_t cdata_cb, 674 void *baton, 675 apr_pool_t *result_pool); 676 677/* Verifies if the parsing completed successfully and destroys 678 all subpools. */ 679svn_error_t * 680svn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx); 681 682/* Construct a handler with the response function/baton set up to parse 683 a response body using the given XML context. The handler and its 684 internal structures are allocated in RESULT_POOL. 685 686 As part of the handling the http status value is compared to 200, or 687 if EXPECTED_STATUS is not NULL to all the values in EXPECTED_STATUS. 688 EXPECTED_STATUS is expected to be a list of integers ending with a 0 689 that lives at least as long as RESULT_POOL. If the status doesn't 690 match the request has failed and will be parsed as en error response. 691 692 This also initializes HANDLER_POOL to the given RESULT_POOL. */ 693svn_ra_serf__handler_t * 694svn_ra_serf__create_expat_handler(svn_ra_serf__session_t *session, 695 svn_ra_serf__xml_context_t *xmlctx, 696 const int *expected_status, 697 apr_pool_t *result_pool); 698 699 700/* Allocated within XES->STATE_POOL. Changes are not allowd (callers 701 should make a deep copy if they need to make changes). 702 703 The resulting hash maps char* names to char* values. */ 704apr_hash_t * 705svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes, 706 int stop_state); 707 708 709/* Attach the NAME/VALUE pair onto this/parent state identified by STATE. 710 The name and value will be copied into the target state's pool. 711 712 These values will be available to the CLOSED_CB for the target state, 713 or part of the gathered state via xml_gather_since(). 714 715 Typically, this function is used by a child state's close callback, 716 or within an opening callback to store additional data. 717 718 Note: if the state is not found, then a programmer error has occurred, 719 so the function will invoke SVN_ERR_MALFUNCTION(). */ 720void 721svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes, 722 int state, 723 const char *name, 724 const char *value); 725 726 727/* Returns XES->STATE_POOL for allocating structures that should live 728 as long as the state identified by XES. 729 730 Note: a state pool is created upon demand, so only use this function 731 when memory is required for a given state. */ 732apr_pool_t * 733svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes); 734 735/* 736 * Parses a server-side error message into a local Subversion error. 737 */ 738struct svn_ra_serf__server_error_t { 739 apr_pool_t *pool; 740 741 /* XML parser and namespace used to parse the remote response */ 742 svn_ra_serf__xml_context_t *xmlctx; 743 744 svn_ra_serf__response_handler_t response_handler; 745 void *response_baton; 746 747 /* The partial errors to construct the final error from */ 748 apr_array_header_t *items; 749 750 /* The hooked handler */ 751 svn_ra_serf__handler_t *handler; 752}; 753 754/* 755 * Handler that discards the entire @a response body associated with a 756 * @a request. Implements svn_ra_serf__response_handler_t. 757 * 758 * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an 759 * error is detected, it will be populated for later detection. 760 * 761 * All temporary allocations will be made in a @a pool. 762 */ 763svn_error_t * 764svn_ra_serf__handle_discard_body(serf_request_t *request, 765 serf_bucket_t *response, 766 void *baton, 767 apr_pool_t *pool); 768 769 770/* 771 * Handler that retrieves the embedded XML multistatus response from the 772 * the @a RESPONSE body associated with a @a REQUEST. 773 * 774 * Implements svn_ra_serf__response_handler_t. 775 * 776 * The @a BATON should be of type svn_ra_serf__handler_t. When the request 777 * is complete, the handler's DONE flag will be set to TRUE. 778 * 779 * All temporary allocations will be made in a @a scratch_pool. 780 */ 781svn_error_t * 782svn_ra_serf__handle_multistatus_only(serf_request_t *request, 783 serf_bucket_t *response, 784 void *baton, 785 apr_pool_t *scratch_pool); 786 787 788/* Handler that expects an empty body. 789 790 If a body IS present, and it is text/xml, then it will be parsed for 791 a server-side error. 792 793 BATON should be the svn_ra_serf__handler_t running REQUEST. 794 795 Status line information will be in HANDLER->SLINE. 796 797 Any parsed errors will be left in HANDLER->SERVER_ERROR. That member 798 may be NULL if no body was present, or a problem occurred trying to 799 parse the body. 800 801 All temporary allocations will be made in SCRATCH_POOL. */ 802svn_error_t * 803svn_ra_serf__expect_empty_body(serf_request_t *request, 804 serf_bucket_t *response, 805 void *baton, 806 apr_pool_t *scratch_pool); 807 808 809/* 810 * This function sets up error parsing for an existing request 811 */ 812svn_error_t * 813svn_ra_serf__setup_error_parsing(svn_ra_serf__server_error_t **server_err, 814 svn_ra_serf__handler_t *handler, 815 svn_boolean_t expect_207_only, 816 apr_pool_t *result_pool, 817 apr_pool_t *scratch_pool); 818 819/* 820 * Forwards response data to the server error parser 821 */ 822svn_error_t * 823svn_ra_serf__handle_server_error(svn_ra_serf__server_error_t *server_error, 824 svn_ra_serf__handler_t *handler, 825 serf_request_t *request, 826 serf_bucket_t *response, 827 apr_status_t *serf_status, 828 apr_pool_t *scratch_pool); 829 830/* 831 * Creates the svn_error_t * instance from the error recorded in 832 * HANDLER->server_error 833 */ 834svn_error_t * 835svn_ra_serf__server_error_create(svn_ra_serf__handler_t *handler, 836 apr_pool_t *scratch_pool); 837 838/* serf_response_handler_t implementation that completely discards 839 * the response. 840 * 841 * All temporary allocations will be made in @a pool. 842 */ 843apr_status_t 844svn_ra_serf__response_discard_handler(serf_request_t *request, 845 serf_bucket_t *response, 846 void *baton, 847 apr_pool_t *pool); 848 849 850/* 851 * Add the appropriate serf buckets to @a agg_bucket represented by 852 * the XML * @a tag and @a value. 853 * 854 * The bucket will be allocated from @a bkt_alloc. 855 */ 856void 857svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket, 858 const char *tag, 859 const char *value, 860 serf_bucket_alloc_t *bkt_alloc); 861 862/* 863 * Add the appropriate serf buckets to AGG_BUCKET with standard XML header: 864 * <?xml version="1.0" encoding="utf-8"?> 865 * 866 * The bucket will be allocated from BKT_ALLOC. 867 */ 868void 869svn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket, 870 serf_bucket_alloc_t *bkt_alloc); 871 872/* 873 * Add the appropriate serf buckets to AGG_BUCKET representing the XML 874 * open tag with name TAG. 875 * 876 * Take the tag's attributes from varargs, a NULL-terminated list of 877 * alternating <tt>char *</tt> key and <tt>char *</tt> val. Attribute 878 * will be ignored if it's value is NULL. 879 * 880 * NOTE: Callers are responsible for XML-escaping attribute values as 881 * necessary. 882 * 883 * The bucket will be allocated from BKT_ALLOC. 884 */ 885void 886svn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket, 887 serf_bucket_alloc_t *bkt_alloc, 888 const char *tag, 889 ...) SVN_NEEDS_SENTINEL_NULL; 890 891/* 892 * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close 893 * with name TAG. 894 * 895 * The bucket will be allocated from BKT_ALLOC. 896 */ 897void 898svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket, 899 serf_bucket_alloc_t *bkt_alloc, 900 const char *tag); 901 902/* Add the appropriate serf buckets to AGG_BUCKET representing the XML 903 * open tag with name TAG, and then immediately closes the tag using the /> 904 * notation 905 */ 906void 907svn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket, 908 serf_bucket_alloc_t *bkt_alloc, 909 const char *tag, 910 ...) SVN_NEEDS_SENTINEL_NULL; 911 912/* 913 * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped 914 * version of DATA. 915 * 916 * The bucket will be allocated from BKT_ALLOC. 917 */ 918void 919svn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket, 920 serf_bucket_alloc_t *bkt_alloc, 921 const char *data, apr_size_t len); 922 923 924/** PROPFIND-related functions **/ 925 926/* Removes all non regular properties from PROPS */ 927void 928svn_ra_serf__keep_only_regular_props(apr_hash_t *props, 929 apr_pool_t *scratch_pool); 930 931 932/* Callback used via svn_ra_serf__deliver_props2 */ 933typedef svn_error_t * 934(*svn_ra_serf__prop_func_t)(void *baton, 935 const char *path, 936 const char *ns, 937 const char *name, 938 const svn_string_t *value, 939 apr_pool_t *scratch_pool); 940 941/* 942 * Implementation of svn_ra_serf__prop_func_t that just delivers svn compatible 943 * properties in the apr_hash_t * that is used as baton. 944 */ 945svn_error_t * 946svn_ra_serf__deliver_svn_props(void *baton, 947 const char *path, 948 const char *ns, 949 const char *name, 950 const svn_string_t *value, 951 apr_pool_t *scratch_pool); 952 953/* 954 * This function will create a handler for a PROPFIND request, which will deliver 955 * properties to PROP_FUNC() with PROP_BATON for the properties listed in LOOKUP_PROPS 956 * at URL for DEPTH ("0","1","infinity"). 957 */ 958svn_error_t * 959svn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **handler, 960 svn_ra_serf__session_t *session, 961 const char *path, 962 svn_revnum_t rev, 963 const char *depth, 964 const svn_ra_serf__dav_props_t *find_props, 965 svn_ra_serf__prop_func_t prop_func, 966 void *prop_func_baton, 967 apr_pool_t *result_pool); 968 969 970/* Using SESSION, fetch the properties specified by WHICH_PROPS using CONN 971 for URL at REVISION. The resulting properties are placed into a 2-level 972 hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which 973 is allocated in RESULT_POOL. 974 975 If REVISION is SVN_INVALID_REVNUM, then the properties are fetched 976 from HEAD for URL. 977 978 This function performs the request synchronously. 979 980 Temporary allocations are made in SCRATCH_POOL. */ 981svn_error_t * 982svn_ra_serf__fetch_node_props(apr_hash_t **results, 983 svn_ra_serf__session_t *session, 984 const char *url, 985 svn_revnum_t revision, 986 const svn_ra_serf__dav_props_t *which_props, 987 apr_pool_t *result_pool, 988 apr_pool_t *scratch_pool); 989 990 991/* Using SESSION, fetch a DAV: property from the resource identified by URL 992 within REVISION. The PROPNAME may be one of: 993 994 "checked-in" 995 "href" 996 997 The resulting value will be allocated in RESULT_POOL, and may be NULL 998 if the property does not exist (note: "href" always exists). 999 1000 This function performs the request synchronously. 1001 1002 Temporary allocations are made in SCRATCH_POOL. */ 1003svn_error_t * 1004svn_ra_serf__fetch_dav_prop(const char **value, 1005 svn_ra_serf__session_t *session, 1006 const char *url, 1007 svn_revnum_t revision, 1008 const char *propname, 1009 apr_pool_t *result_pool, 1010 apr_pool_t *scratch_pool); 1011 1012/* Map a property name, as passed over the wire, into its corresponding 1013 Subversion-internal name. The returned name will be a static value, 1014 or allocated within RESULT_POOL. 1015 1016 If the property should be ignored (eg. some DAV properties), then NULL 1017 will be returned. */ 1018const char * 1019svn_ra_serf__svnname_from_wirename(const char *ns, 1020 const char *name, 1021 apr_pool_t *result_pool); 1022 1023/** MERGE-related functions **/ 1024 1025void 1026svn_ra_serf__merge_lock_token_list(apr_hash_t *lock_tokens, 1027 const char *parent, 1028 serf_bucket_t *body, 1029 serf_bucket_alloc_t *alloc, 1030 apr_pool_t *pool); 1031 1032/* Create an MERGE request aimed at the SESSION url, requesting the 1033 merge of the resource identified by MERGE_RESOURCE_URL. 1034 LOCK_TOKENS is a hash mapping paths to lock tokens owned by the 1035 client. If KEEP_LOCKS is set, instruct the server to not release 1036 locks set on the paths included in this commit. */ 1037svn_error_t * 1038svn_ra_serf__run_merge(const svn_commit_info_t **commit_info, 1039 svn_ra_serf__session_t *session, 1040 const char *merge_resource_url, 1041 apr_hash_t *lock_tokens, 1042 svn_boolean_t keep_locks, 1043 apr_pool_t *result_pool, 1044 apr_pool_t *scratch_pool); 1045 1046 1047/** OPTIONS-related functions **/ 1048 1049/* When running with a proxy, we may need to detect and correct for problems. 1050 This probing function will send a simple OPTIONS request to detect problems 1051 with the connection. */ 1052svn_error_t * 1053svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess, 1054 apr_pool_t *scratch_pool); 1055 1056 1057/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the 1058 current youngest revnum, returning it in *YOUNGEST. 1059 1060 (the revnum is headers of the OPTIONS response) 1061 1062 This function performs the request synchronously. 1063 1064 All temporary allocations will be made in SCRATCH_POOL. */ 1065svn_error_t * 1066svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest, 1067 svn_ra_serf__session_t *session, 1068 apr_pool_t *scratch_pool); 1069 1070 1071/* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the 1072 activity collection set and return it in *ACTIVITY_URL, allocated 1073 from RESULT_POOL. 1074 1075 (the activity-collection-set is in the body of the OPTIONS response) 1076 1077 This function performs the request synchronously. 1078 1079 All temporary allocations will be made in SCRATCH_POOL. */ 1080svn_error_t * 1081svn_ra_serf__v1_get_activity_collection(const char **activity_url, 1082 svn_ra_serf__session_t *session, 1083 apr_pool_t *result_pool, 1084 apr_pool_t *scratch_pool); 1085 1086 1087/* Set @a VCC_URL to the default VCC for our repository based on @a 1088 * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and 1089 * repository root URLs are cached in @a SESSION. 1090 * 1091 * All temporary allocations will be made in @a SCRATCH_POOL. */ 1092svn_error_t * 1093svn_ra_serf__discover_vcc(const char **vcc_url, 1094 svn_ra_serf__session_t *session, 1095 apr_pool_t *scratch_pool); 1096 1097/* Set @a REPORT_TARGET to the URI of the resource at which generic 1098 * (path-agnostic) REPORTs should be aimed for @a SESSION. 1099 * 1100 * All temporary allocations will be made in @a POOL. 1101 */ 1102svn_error_t * 1103svn_ra_serf__report_resource(const char **report_target, 1104 svn_ra_serf__session_t *session, 1105 apr_pool_t *pool); 1106 1107/* Set @a REL_PATH to a path (not URI-encoded) relative to the root of 1108 * the repository pointed to by @a SESSION, based on original path 1109 * (URI-encoded) @a ORIG_PATH. Use @a CONN for any required network 1110 * communications if it is non-NULL; otherwise use the default 1111 * connection. Use POOL for allocations. */ 1112svn_error_t * 1113svn_ra_serf__get_relative_path(const char **rel_path, 1114 const char *orig_path, 1115 svn_ra_serf__session_t *session, 1116 apr_pool_t *pool); 1117 1118 1119/* Using the default connection in SESSION (conns[0]), get the youngest 1120 revnum from the server, returning it in *YOUNGEST. 1121 1122 This function operates synchronously. 1123 1124 All temporary allocations are performed in SCRATCH_POOL. */ 1125svn_error_t * 1126svn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest, 1127 svn_ra_serf__session_t *session, 1128 apr_pool_t *scratch_pool); 1129 1130 1131/* Generate a revision-stable URL. 1132 1133 The RA APIs all refer to user/public URLs that float along with the 1134 youngest revision. In many cases, we do NOT want to work with that URL 1135 since it can change from one moment to the next. Especially if we 1136 attempt to operation against multiple floating URLs -- we could end up 1137 referring to two separate revisions. 1138 1139 The DAV RA provider(s) solve this by generating a URL that is specific 1140 to a revision by using a URL into a "baseline collection". 1141 1142 For a specified SESSION, generate a revision-stable URL for URL at 1143 REVISION. If REVISION is SVN_INVALID_REVNUM, then the stable URL will 1144 refer to the youngest revision at the time this function was called. 1145 1146 If URL is NULL, then the session root will be used. 1147 1148 The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL. 1149 1150 If LATEST_REVNUM is not NULL, then the revision used will be placed into 1151 *LATEST_REVNUM. That will be equal to youngest, or the given REVISION. 1152 1153 This function operates synchronously, if any communication to the server 1154 is required. Communication is needed if REVISION is SVN_INVALID_REVNUM 1155 (to get the current youngest revnum), or if the specified REVISION is not 1156 (yet) in our cache of baseline collections. 1157 1158 All temporary allocations are performed in SCRATCH_POOL. */ 1159svn_error_t * 1160svn_ra_serf__get_stable_url(const char **stable_url, 1161 svn_revnum_t *latest_revnum, 1162 svn_ra_serf__session_t *session, 1163 const char *url, 1164 svn_revnum_t revision, 1165 apr_pool_t *result_pool, 1166 apr_pool_t *scratch_pool); 1167 1168 1169/** RA functions **/ 1170 1171/* Implements svn_ra__vtable_t.reparent(). */ 1172svn_error_t * 1173svn_ra_serf__reparent(svn_ra_session_t *ra_session, 1174 const char *url, 1175 apr_pool_t *pool); 1176 1177/* Implements svn_ra__vtable_t.rev_prop(). */ 1178svn_error_t * 1179svn_ra_serf__rev_prop(svn_ra_session_t *session, 1180 svn_revnum_t rev, 1181 const char *name, 1182 svn_string_t **value, 1183 apr_pool_t *pool); 1184 1185/* Implements svn_ra__vtable_t.get_log(). */ 1186svn_error_t * 1187svn_ra_serf__get_log(svn_ra_session_t *session, 1188 const apr_array_header_t *paths, 1189 svn_revnum_t start, 1190 svn_revnum_t end, 1191 int limit, 1192 svn_boolean_t discover_changed_paths, 1193 svn_boolean_t strict_node_history, 1194 svn_boolean_t include_merged_revisions, 1195 const apr_array_header_t *revprops, 1196 svn_log_entry_receiver_t receiver, 1197 void *receiver_baton, 1198 apr_pool_t *pool); 1199 1200/* Implements svn_ra__vtable_t.check_path(). */ 1201svn_error_t * 1202svn_ra_serf__check_path(svn_ra_session_t *ra_session, 1203 const char *rel_path, 1204 svn_revnum_t revision, 1205 svn_node_kind_t *kind, 1206 apr_pool_t *pool); 1207 1208/* Implements svn_ra__vtable_t.stat(). */ 1209svn_error_t * 1210svn_ra_serf__stat(svn_ra_session_t *ra_session, 1211 const char *rel_path, 1212 svn_revnum_t revision, 1213 svn_dirent_t **dirent, 1214 apr_pool_t *pool); 1215 1216/* Implements svn_ra__vtable_t.get_locations(). */ 1217svn_error_t * 1218svn_ra_serf__get_locations(svn_ra_session_t *session, 1219 apr_hash_t **locations, 1220 const char *path, 1221 svn_revnum_t peg_revision, 1222 const apr_array_header_t *location_revisions, 1223 apr_pool_t *pool); 1224 1225/* Implements svn_ra__vtable_t.get_location_segments(). */ 1226svn_error_t * 1227svn_ra_serf__get_location_segments(svn_ra_session_t *session, 1228 const char *path, 1229 svn_revnum_t peg_revision, 1230 svn_revnum_t start_rev, 1231 svn_revnum_t end_rev, 1232 svn_location_segment_receiver_t receiver, 1233 void *receiver_baton, 1234 apr_pool_t *pool); 1235 1236/* Implements svn_ra__vtable_t.do_diff(). */ 1237svn_error_t * 1238svn_ra_serf__do_diff(svn_ra_session_t *session, 1239 const svn_ra_reporter3_t **reporter, 1240 void **report_baton, 1241 svn_revnum_t revision, 1242 const char *diff_target, 1243 svn_depth_t depth, 1244 svn_boolean_t ignore_ancestry, 1245 svn_boolean_t text_deltas, 1246 const char *versus_url, 1247 const svn_delta_editor_t *diff_editor, 1248 void *diff_baton, 1249 apr_pool_t *pool); 1250 1251/* Implements svn_ra__vtable_t.do_status(). */ 1252svn_error_t * 1253svn_ra_serf__do_status(svn_ra_session_t *ra_session, 1254 const svn_ra_reporter3_t **reporter, 1255 void **report_baton, 1256 const char *status_target, 1257 svn_revnum_t revision, 1258 svn_depth_t depth, 1259 const svn_delta_editor_t *status_editor, 1260 void *status_baton, 1261 apr_pool_t *pool); 1262 1263/* Implements svn_ra__vtable_t.do_update(). */ 1264svn_error_t * 1265svn_ra_serf__do_update(svn_ra_session_t *ra_session, 1266 const svn_ra_reporter3_t **reporter, 1267 void **report_baton, 1268 svn_revnum_t revision_to_update_to, 1269 const char *update_target, 1270 svn_depth_t depth, 1271 svn_boolean_t send_copyfrom_args, 1272 svn_boolean_t ignore_ancestry, 1273 const svn_delta_editor_t *update_editor, 1274 void *update_baton, 1275 apr_pool_t *result_pool, 1276 apr_pool_t *scratch_pool); 1277 1278/* Implements svn_ra__vtable_t.do_switch(). */ 1279svn_error_t * 1280svn_ra_serf__do_switch(svn_ra_session_t *ra_session, 1281 const svn_ra_reporter3_t **reporter, 1282 void **report_baton, 1283 svn_revnum_t revision_to_switch_to, 1284 const char *switch_target, 1285 svn_depth_t depth, 1286 const char *switch_url, 1287 svn_boolean_t send_copyfrom_args, 1288 svn_boolean_t ignore_ancestry, 1289 const svn_delta_editor_t *switch_editor, 1290 void *switch_baton, 1291 apr_pool_t *result_pool, 1292 apr_pool_t *scratch_pool); 1293 1294/* Implements svn_ra__vtable_t.get_file_revs(). */ 1295svn_error_t * 1296svn_ra_serf__get_file_revs(svn_ra_session_t *session, 1297 const char *path, 1298 svn_revnum_t start, 1299 svn_revnum_t end, 1300 svn_boolean_t include_merged_revisions, 1301 svn_file_rev_handler_t handler, 1302 void *handler_baton, 1303 apr_pool_t *pool); 1304 1305/* Implements svn_ra__vtable_t.get_dated_revision(). */ 1306svn_error_t * 1307svn_ra_serf__get_dated_revision(svn_ra_session_t *session, 1308 svn_revnum_t *revision, 1309 apr_time_t tm, 1310 apr_pool_t *pool); 1311 1312/* Implements svn_ra__vtable_t.get_commit_editor(). 1313 * 1314 * Note: Like other commit editors, the returned editor requires that the 1315 * @c copyfrom_path parameter passed to its @c add_file and @c add_directory 1316 * methods is a URL, not a relative path. 1317 */ 1318svn_error_t * 1319svn_ra_serf__get_commit_editor(svn_ra_session_t *session, 1320 const svn_delta_editor_t **editor, 1321 void **edit_baton, 1322 apr_hash_t *revprop_table, 1323 svn_commit_callback2_t callback, 1324 void *callback_baton, 1325 apr_hash_t *lock_tokens, 1326 svn_boolean_t keep_locks, 1327 apr_pool_t *pool); 1328 1329/* Implements svn_ra__vtable_t.get_file(). */ 1330svn_error_t * 1331svn_ra_serf__get_file(svn_ra_session_t *session, 1332 const char *path, 1333 svn_revnum_t revision, 1334 svn_stream_t *stream, 1335 svn_revnum_t *fetched_rev, 1336 apr_hash_t **props, 1337 apr_pool_t *pool); 1338 1339/* Implements svn_ra__vtable_t.get_dir(). */ 1340svn_error_t * 1341svn_ra_serf__get_dir(svn_ra_session_t *ra_session, 1342 apr_hash_t **dirents, 1343 svn_revnum_t *fetched_rev, 1344 apr_hash_t **ret_props, 1345 const char *rel_path, 1346 svn_revnum_t revision, 1347 apr_uint32_t dirent_fields, 1348 apr_pool_t *result_pool); 1349 1350/* Implements svn_ra__vtable_t.change_rev_prop(). */ 1351svn_error_t * 1352svn_ra_serf__change_rev_prop(svn_ra_session_t *session, 1353 svn_revnum_t rev, 1354 const char *name, 1355 const svn_string_t *const *old_value_p, 1356 const svn_string_t *value, 1357 apr_pool_t *pool); 1358 1359/* Implements svn_ra__vtable_t.replay(). */ 1360svn_error_t * 1361svn_ra_serf__replay(svn_ra_session_t *ra_session, 1362 svn_revnum_t revision, 1363 svn_revnum_t low_water_mark, 1364 svn_boolean_t text_deltas, 1365 const svn_delta_editor_t *editor, 1366 void *edit_baton, 1367 apr_pool_t *pool); 1368 1369/* Implements svn_ra__vtable_t.replay_range(). */ 1370svn_error_t * 1371svn_ra_serf__replay_range(svn_ra_session_t *ra_session, 1372 svn_revnum_t start_revision, 1373 svn_revnum_t end_revision, 1374 svn_revnum_t low_water_mark, 1375 svn_boolean_t send_deltas, 1376 svn_ra_replay_revstart_callback_t revstart_func, 1377 svn_ra_replay_revfinish_callback_t revfinish_func, 1378 void *replay_baton, 1379 apr_pool_t *pool); 1380 1381/* Implements svn_ra__vtable_t.lock(). */ 1382svn_error_t * 1383svn_ra_serf__lock(svn_ra_session_t *ra_session, 1384 apr_hash_t *path_revs, 1385 const char *comment, 1386 svn_boolean_t force, 1387 svn_ra_lock_callback_t lock_func, 1388 void *lock_baton, 1389 apr_pool_t *pool); 1390 1391/* Implements svn_ra__vtable_t.unlock(). */ 1392svn_error_t * 1393svn_ra_serf__unlock(svn_ra_session_t *ra_session, 1394 apr_hash_t *path_tokens, 1395 svn_boolean_t force, 1396 svn_ra_lock_callback_t lock_func, 1397 void *lock_baton, 1398 apr_pool_t *pool); 1399 1400/* Implements svn_ra__vtable_t.get_lock(). */ 1401svn_error_t * 1402svn_ra_serf__get_lock(svn_ra_session_t *ra_session, 1403 svn_lock_t **lock, 1404 const char *path, 1405 apr_pool_t *pool); 1406 1407/* Implements svn_ra__vtable_t.get_locks(). */ 1408svn_error_t * 1409svn_ra_serf__get_locks(svn_ra_session_t *ra_session, 1410 apr_hash_t **locks, 1411 const char *path, 1412 svn_depth_t depth, 1413 apr_pool_t *pool); 1414 1415/* Request a mergeinfo-report from the URL attached to SESSION, 1416 and fill in the MERGEINFO hash with the results. 1417 1418 Implements svn_ra__vtable_t.get_mergeinfo(). 1419 */ 1420svn_error_t * 1421svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session, 1422 apr_hash_t **mergeinfo, 1423 const apr_array_header_t *paths, 1424 svn_revnum_t revision, 1425 svn_mergeinfo_inheritance_t inherit, 1426 svn_boolean_t include_descendants, 1427 apr_pool_t *pool); 1428 1429/* Exchange capabilities with the server, by sending an OPTIONS 1430 * request announcing the client's capabilities, and by filling 1431 * SERF_SESS->capabilities with the server's capabilities as read from 1432 * the response headers. Use POOL only for temporary allocation. 1433 * 1434 * If the CORRECTED_URL is non-NULL, allow the OPTIONS response to 1435 * report a server-dictated redirect or relocation (HTTP 301 or 302 1436 * error codes), setting *CORRECTED_URL to the value of the corrected 1437 * repository URL. Otherwise, such responses from the server will 1438 * generate an error. (In either case, no capabilities are exchanged 1439 * if there is, in fact, such a response from the server.) 1440 */ 1441svn_error_t * 1442svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess, 1443 const char **corrected_url, 1444 apr_pool_t *result_pool, 1445 apr_pool_t *scratch_pool); 1446 1447/* Implements svn_ra__vtable_t.has_capability(). */ 1448svn_error_t * 1449svn_ra_serf__has_capability(svn_ra_session_t *ra_session, 1450 svn_boolean_t *has, 1451 const char *capability, 1452 apr_pool_t *pool); 1453 1454/* Implements svn_ra__vtable_t.get_deleted_rev(). */ 1455svn_error_t * 1456svn_ra_serf__get_deleted_rev(svn_ra_session_t *session, 1457 const char *path, 1458 svn_revnum_t peg_revision, 1459 svn_revnum_t end_revision, 1460 svn_revnum_t *revision_deleted, 1461 apr_pool_t *pool); 1462 1463/* Implements the get_inherited_props RA layer function. */ 1464svn_error_t * svn_ra_serf__get_inherited_props(svn_ra_session_t *session, 1465 apr_array_header_t **iprops, 1466 const char *path, 1467 svn_revnum_t revision, 1468 apr_pool_t *result_pool, 1469 apr_pool_t *scratch_pool); 1470 1471/* Implements svn_ra__vtable_t.get_repos_root(). */ 1472svn_error_t * 1473svn_ra_serf__get_repos_root(svn_ra_session_t *ra_session, 1474 const char **url, 1475 apr_pool_t *pool); 1476 1477/* Implements svn_ra__vtable_t.register_editor_shim_callbacks(). */ 1478svn_error_t * 1479svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session, 1480 svn_delta_shim_callbacks_t *callbacks); 1481 1482/*** Authentication handler declarations ***/ 1483 1484/** 1485 * Callback function that loads the credentials for Basic and Digest 1486 * authentications, both for server and proxy authentication. 1487 */ 1488apr_status_t 1489svn_ra_serf__credentials_callback(char **username, char **password, 1490 serf_request_t *request, void *baton, 1491 int code, const char *authn_type, 1492 const char *realm, 1493 apr_pool_t *pool); 1494 1495 1496/*** General utility functions ***/ 1497 1498/** 1499 * Convert an HTTP STATUS_CODE resulting from a WebDAV request against 1500 * PATH to the relevant error code. Use the response-supplied LOCATION 1501 * where it necessary. 1502 * 1503 * Returns SVN_NO_ERROR if sline doesn't specify an error condition 1504 */ 1505svn_error_t * 1506svn_ra_serf__error_on_status(serf_status_line sline, 1507 const char *path, 1508 const char *location); 1509 1510/** 1511 * Convert an unexpected HTTP STATUS_CODE from a request to the relevant error 1512 * code. Unlike svn_ra_serf__error_on_status() this function creates an error 1513 * for any result 1514 */ 1515svn_error_t * 1516svn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler); 1517 1518 1519/* ###? */ 1520svn_error_t * 1521svn_ra_serf__copy_into_spillbuf(svn_spillbuf_t **spillbuf, 1522 serf_bucket_t *bkt, 1523 apr_pool_t *result_pool, 1524 apr_pool_t *scratch_pool); 1525 1526/* ###? */ 1527serf_bucket_t * 1528svn_ra_serf__create_sb_bucket(svn_spillbuf_t *spillbuf, 1529 serf_bucket_alloc_t *allocator, 1530 apr_pool_t *result_pool, 1531 apr_pool_t *scratch_pool); 1532 1533/** Wrap STATUS from an serf function. If STATUS is not serf error code, 1534 * this is equivalent to svn_error_wrap_apr(). 1535 */ 1536svn_error_t * 1537svn_ra_serf__wrap_err(apr_status_t status, 1538 const char *fmt, 1539 ...); 1540 1541/* Create a bucket that just returns DATA (with length LEN) and then returns 1542 the APR_EAGAIN status */ 1543serf_bucket_t * 1544svn_ra_serf__create_bucket_with_eagain(const char *data, 1545 apr_size_t len, 1546 serf_bucket_alloc_t *allocator); 1547 1548/* Parse a given URL_STR, fill in all supplied fields of URI 1549 * structure. 1550 * 1551 * This function is a compatibility wrapper around apr_uri_parse(). 1552 * Different apr-util versions set apr_uri_t.path to either NULL or "" 1553 * for root paths, and serf expects to see "/". This function always 1554 * sets URI.path to "/" for these paths. */ 1555svn_error_t * 1556svn_ra_serf__uri_parse(apr_uri_t *uri, 1557 const char *url_str, 1558 apr_pool_t *result_pool); 1559 1560 1561#if defined(SVN_DEBUG) 1562/* Wrapper macros to collect file and line information */ 1563#define svn_ra_serf__wrap_err \ 1564 (svn_error__locate(__FILE__,__LINE__), (svn_ra_serf__wrap_err)) 1565 1566#endif 1567 1568#ifdef __cplusplus 1569} 1570#endif /* __cplusplus */ 1571 1572#endif /* SVN_LIBSVN_RA_SERF_RA_SERF_H */ 1573