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