1/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef SERF_BUCKET_TYPES_H 17#define SERF_BUCKET_TYPES_H 18 19#include <apr_mmap.h> 20#include <apr_hash.h> 21 22/* this header and serf.h refer to each other, so take a little extra care */ 23#ifndef SERF_H 24#include "serf.h" 25#endif 26 27 28/** 29 * @file serf_bucket_types.h 30 * @brief serf-supported bucket types 31 */ 32/* ### this whole file needs docco ... */ 33 34#ifdef __cplusplus 35extern "C" { 36#endif 37 38/* ==================================================================== */ 39 40 41extern const serf_bucket_type_t serf_bucket_type_request; 42#define SERF_BUCKET_IS_REQUEST(b) SERF_BUCKET_CHECK((b), request) 43 44serf_bucket_t *serf_bucket_request_create( 45 const char *method, 46 const char *URI, 47 serf_bucket_t *body, 48 serf_bucket_alloc_t *allocator); 49 50/* Send a Content-Length header with @a len. The @a body bucket should 51 contain precisely that much data. */ 52void serf_bucket_request_set_CL( 53 serf_bucket_t *bucket, 54 apr_int64_t len); 55 56serf_bucket_t *serf_bucket_request_get_headers( 57 serf_bucket_t *request); 58 59void serf_bucket_request_become( 60 serf_bucket_t *bucket, 61 const char *method, 62 const char *uri, 63 serf_bucket_t *body); 64 65/** 66 * Sets the root url of the remote host. If this request contains a relative 67 * url, it will be prefixed with the root url to form an absolute url. 68 * @a bucket is the request bucket. @a root_url is the absolute url of the 69 * root of the remote host, without the closing '/'. 70 */ 71void serf_bucket_request_set_root( 72 serf_bucket_t *bucket, 73 const char *root_url); 74 75/* ==================================================================== */ 76 77 78extern const serf_bucket_type_t serf_bucket_type_response; 79#define SERF_BUCKET_IS_RESPONSE(b) SERF_BUCKET_CHECK((b), response) 80 81serf_bucket_t *serf_bucket_response_create( 82 serf_bucket_t *stream, 83 serf_bucket_alloc_t *allocator); 84 85#define SERF_HTTP_VERSION(major, minor) ((major) * 1000 + (minor)) 86#define SERF_HTTP_11 SERF_HTTP_VERSION(1, 1) 87#define SERF_HTTP_10 SERF_HTTP_VERSION(1, 0) 88#define SERF_HTTP_VERSION_MAJOR(shv) ((int)shv / 1000) 89#define SERF_HTTP_VERSION_MINOR(shv) ((int)shv % 1000) 90 91typedef struct { 92 int version; 93 int code; 94 const char *reason; 95} serf_status_line; 96 97/** 98 * Return the Status-Line information, if available. This function 99 * works like other bucket read functions: it may return APR_EAGAIN or 100 * APR_EOF to signal the state of the bucket for reading. A return 101 * value of APR_SUCCESS will always indicate that status line 102 * information was returned; for other return values the caller must 103 * check the version field in @a sline. A value of 0 means that the 104 * data is not (yet) present. 105 */ 106apr_status_t serf_bucket_response_status( 107 serf_bucket_t *bkt, 108 serf_status_line *sline); 109 110/** 111 * Wait for the HTTP headers to be processed for a @a response. 112 * 113 * If the headers are available, APR_SUCCESS is returned. 114 * If the headers aren't available, APR_EAGAIN is returned. 115 */ 116apr_status_t serf_bucket_response_wait_for_headers( 117 serf_bucket_t *response); 118 119/** 120 * Get the headers bucket for @a response. 121 */ 122serf_bucket_t *serf_bucket_response_get_headers( 123 serf_bucket_t *response); 124 125/** 126 * Advise the response @a bucket that this was from a HEAD request and 127 * that it should not expect to see a response body. 128 */ 129void serf_bucket_response_set_head( 130 serf_bucket_t *bucket); 131 132/* ==================================================================== */ 133 134extern const serf_bucket_type_t serf_bucket_type_response_body; 135#define SERF_BUCKET_IS_RESPONSE_BODY(b) SERF_BUCKET_CHECK((b), response_body) 136 137serf_bucket_t *serf_bucket_response_body_create( 138 serf_bucket_t *stream, 139 apr_uint64_t limit, 140 serf_bucket_alloc_t *allocator); 141 142/* ==================================================================== */ 143 144extern const serf_bucket_type_t serf_bucket_type_bwtp_frame; 145#define SERF_BUCKET_IS_BWTP_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_frame) 146 147extern const serf_bucket_type_t serf_bucket_type_bwtp_incoming_frame; 148#define SERF_BUCKET_IS_BWTP_INCOMING_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_incoming_frame) 149 150int serf_bucket_bwtp_frame_get_channel( 151 serf_bucket_t *hdr); 152 153int serf_bucket_bwtp_frame_get_type( 154 serf_bucket_t *hdr); 155 156const char *serf_bucket_bwtp_frame_get_phrase( 157 serf_bucket_t *hdr); 158 159serf_bucket_t *serf_bucket_bwtp_frame_get_headers( 160 serf_bucket_t *hdr); 161 162serf_bucket_t *serf_bucket_bwtp_channel_open( 163 int channel, 164 const char *URI, 165 serf_bucket_alloc_t *allocator); 166 167serf_bucket_t *serf_bucket_bwtp_channel_close( 168 int channel, 169 serf_bucket_alloc_t *allocator); 170 171serf_bucket_t *serf_bucket_bwtp_header_create( 172 int channel, 173 const char *phrase, 174 serf_bucket_alloc_t *allocator); 175 176serf_bucket_t *serf_bucket_bwtp_message_create( 177 int channel, 178 serf_bucket_t *body, 179 serf_bucket_alloc_t *allocator); 180 181serf_bucket_t *serf_bucket_bwtp_incoming_frame_create( 182 serf_bucket_t *bkt, 183 serf_bucket_alloc_t *allocator); 184 185apr_status_t serf_bucket_bwtp_incoming_frame_wait_for_headers( 186 serf_bucket_t *bkt); 187 188/* ==================================================================== */ 189 190 191extern const serf_bucket_type_t serf_bucket_type_aggregate; 192#define SERF_BUCKET_IS_AGGREGATE(b) SERF_BUCKET_CHECK((b), aggregate) 193 194typedef apr_status_t (*serf_bucket_aggregate_eof_t)( 195 void *baton, 196 serf_bucket_t *aggregate_bucket); 197 198/** serf_bucket_aggregate_cleanup will instantly destroy all buckets in 199 the aggregate bucket that have been read completely. Whereas normally, 200 these buckets are destroyed on every read operation. */ 201void serf_bucket_aggregate_cleanup( 202 serf_bucket_t *bucket, 203 serf_bucket_alloc_t *allocator); 204 205serf_bucket_t *serf_bucket_aggregate_create( 206 serf_bucket_alloc_t *allocator); 207 208/* Creates a stream bucket. 209 A stream bucket is like an aggregate bucket, but: 210 - it doesn't destroy its child buckets on cleanup 211 - one can always keep adding child buckets, the handler FN should return 212 APR_EOF when no more buckets will be added. 213 214 Note: keep this factory function internal for now. If it turns out this 215 bucket type is useful outside serf, we should make it an actual separate 216 type. 217 */ 218serf_bucket_t *serf__bucket_stream_create( 219 serf_bucket_alloc_t *allocator, 220 serf_bucket_aggregate_eof_t fn, 221 void *baton); 222 223/** Transform @a bucket in-place into an aggregate bucket. */ 224void serf_bucket_aggregate_become( 225 serf_bucket_t *bucket); 226 227void serf_bucket_aggregate_prepend( 228 serf_bucket_t *aggregate_bucket, 229 serf_bucket_t *prepend_bucket); 230 231void serf_bucket_aggregate_append( 232 serf_bucket_t *aggregate_bucket, 233 serf_bucket_t *append_bucket); 234 235void serf_bucket_aggregate_hold_open( 236 serf_bucket_t *aggregate_bucket, 237 serf_bucket_aggregate_eof_t fn, 238 void *baton); 239 240void serf_bucket_aggregate_prepend_iovec( 241 serf_bucket_t *aggregate_bucket, 242 struct iovec *vecs, 243 int vecs_count); 244 245void serf_bucket_aggregate_append_iovec( 246 serf_bucket_t *aggregate_bucket, 247 struct iovec *vecs, 248 int vecs_count); 249 250/* ==================================================================== */ 251 252 253extern const serf_bucket_type_t serf_bucket_type_file; 254#define SERF_BUCKET_IS_FILE(b) SERF_BUCKET_CHECK((b), file) 255 256serf_bucket_t *serf_bucket_file_create( 257 apr_file_t *file, 258 serf_bucket_alloc_t *allocator); 259 260 261/* ==================================================================== */ 262 263 264extern const serf_bucket_type_t serf_bucket_type_socket; 265#define SERF_BUCKET_IS_SOCKET(b) SERF_BUCKET_CHECK((b), socket) 266 267serf_bucket_t *serf_bucket_socket_create( 268 apr_socket_t *skt, 269 serf_bucket_alloc_t *allocator); 270 271/** 272 * Call @a progress_func every time bytes are read from the socket, pass 273 * the number of bytes read. 274 * 275 * When using serf's bytes read & written progress indicator, pass 276 * @a serf_context_progress_delta for progress_func and the serf_context for 277 * progress_baton. 278 */ 279void serf_bucket_socket_set_read_progress_cb( 280 serf_bucket_t *bucket, 281 const serf_progress_t progress_func, 282 void *progress_baton); 283 284/* ==================================================================== */ 285 286 287extern const serf_bucket_type_t serf_bucket_type_simple; 288#define SERF_BUCKET_IS_SIMPLE(b) SERF_BUCKET_CHECK((b), simple) 289 290typedef void (*serf_simple_freefunc_t)( 291 void *baton, 292 const char *data); 293 294serf_bucket_t *serf_bucket_simple_create( 295 const char *data, 296 apr_size_t len, 297 serf_simple_freefunc_t freefunc, 298 void *freefunc_baton, 299 serf_bucket_alloc_t *allocator); 300 301/** 302 * Equivalent to serf_bucket_simple_create, except that the bucket takes 303 * ownership of a private copy of the data. 304 */ 305serf_bucket_t *serf_bucket_simple_copy_create( 306 const char *data, 307 apr_size_t len, 308 serf_bucket_alloc_t *allocator); 309 310/** 311 * Equivalent to serf_bucket_simple_create, except that the bucket assumes 312 * responsibility for freeing the data on this allocator without making 313 * a copy. It is assumed that data was created by a call from allocator. 314 */ 315serf_bucket_t *serf_bucket_simple_own_create( 316 const char *data, 317 apr_size_t len, 318 serf_bucket_alloc_t *allocator); 319 320#define SERF_BUCKET_SIMPLE_STRING(s,a) \ 321 serf_bucket_simple_create(s, strlen(s), NULL, NULL, a); 322 323#define SERF_BUCKET_SIMPLE_STRING_LEN(s,l,a) \ 324 serf_bucket_simple_create(s, l, NULL, NULL, a); 325 326/* ==================================================================== */ 327 328 329/* Note: apr_mmap_t is always defined, but if APR doesn't have mmaps, then 330 the caller can never create an apr_mmap_t to pass to this function. */ 331 332extern const serf_bucket_type_t serf_bucket_type_mmap; 333#define SERF_BUCKET_IS_MMAP(b) SERF_BUCKET_CHECK((b), mmap) 334 335serf_bucket_t *serf_bucket_mmap_create( 336 apr_mmap_t *mmap, 337 serf_bucket_alloc_t *allocator); 338 339 340/* ==================================================================== */ 341 342 343extern const serf_bucket_type_t serf_bucket_type_headers; 344#define SERF_BUCKET_IS_HEADERS(b) SERF_BUCKET_CHECK((b), headers) 345 346serf_bucket_t *serf_bucket_headers_create( 347 serf_bucket_alloc_t *allocator); 348 349/** 350 * Set, default: value copied. 351 * 352 * Set the specified @a header within the bucket, copying the @a value 353 * into space from this bucket's allocator. The header is NOT copied, 354 * so it should remain in scope at least as long as the bucket. 355 */ 356void serf_bucket_headers_set( 357 serf_bucket_t *headers_bucket, 358 const char *header, 359 const char *value); 360 361/** 362 * Set, copies: header and value copied. 363 * 364 * Copy the specified @a header and @a value into the bucket, using space 365 * from this bucket's allocator. 366 */ 367void serf_bucket_headers_setc( 368 serf_bucket_t *headers_bucket, 369 const char *header, 370 const char *value); 371 372/** 373 * Set, no copies. 374 * 375 * Set the specified @a header and @a value into the bucket, without 376 * copying either attribute. Both attributes should remain in scope at 377 * least as long as the bucket. 378 * 379 * @note In the case where a header already exists this will result 380 * in a reallocation and copy, @see serf_bucket_headers_setn. 381 */ 382void serf_bucket_headers_setn( 383 serf_bucket_t *headers_bucket, 384 const char *header, 385 const char *value); 386 387/** 388 * Set, extended: fine grained copy control of header and value. 389 * 390 * Set the specified @a header, with length @a header_size with the 391 * @a value, and length @a value_size, into the bucket. The header will 392 * be copied if @a header_copy is set, and the value is copied if 393 * @a value_copy is set. If the values are not copied, then they should 394 * remain in scope at least as long as the bucket. 395 * 396 * If @a headers_bucket already contains a header with the same name 397 * as @a header, then append @a value to the existing value, 398 * separating with a comma (as per RFC 2616, section 4.2). In this 399 * case, the new value must be allocated and the header re-used, so 400 * behave as if @a value_copy were true and @a header_copy false. 401 */ 402void serf_bucket_headers_setx( 403 serf_bucket_t *headers_bucket, 404 const char *header, 405 apr_size_t header_size, 406 int header_copy, 407 const char *value, 408 apr_size_t value_size, 409 int value_copy); 410 411const char *serf_bucket_headers_get( 412 serf_bucket_t *headers_bucket, 413 const char *header); 414 415/** 416 * @param baton opaque baton as passed to @see serf_bucket_headers_do 417 * @param key The header key from this iteration through the table 418 * @param value The header value from this iteration through the table 419 */ 420typedef int (serf_bucket_headers_do_callback_fn_t)( 421 void *baton, 422 const char *key, 423 const char *value); 424 425/** 426 * Iterates over all headers of the message and invokes the callback 427 * function with header key and value. Stop iterating when no more 428 * headers are available or when the callback function returned a 429 * non-0 value. 430 * 431 * @param headers_bucket headers to iterate over 432 * @param func callback routine to invoke for every header in the bucket 433 * @param baton baton to pass on each invocation to func 434 */ 435void serf_bucket_headers_do( 436 serf_bucket_t *headers_bucket, 437 serf_bucket_headers_do_callback_fn_t func, 438 void *baton); 439 440 441/* ==================================================================== */ 442 443 444extern const serf_bucket_type_t serf_bucket_type_chunk; 445#define SERF_BUCKET_IS_CHUNK(b) SERF_BUCKET_CHECK((b), chunk) 446 447serf_bucket_t *serf_bucket_chunk_create( 448 serf_bucket_t *stream, 449 serf_bucket_alloc_t *allocator); 450 451 452/* ==================================================================== */ 453 454 455extern const serf_bucket_type_t serf_bucket_type_dechunk; 456#define SERF_BUCKET_IS_DECHUNK(b) SERF_BUCKET_CHECK((b), dechunk) 457 458serf_bucket_t *serf_bucket_dechunk_create( 459 serf_bucket_t *stream, 460 serf_bucket_alloc_t *allocator); 461 462 463/* ==================================================================== */ 464 465 466extern const serf_bucket_type_t serf_bucket_type_deflate; 467#define SERF_BUCKET_IS_DEFLATE(b) SERF_BUCKET_CHECK((b), deflate) 468 469#define SERF_DEFLATE_GZIP 0 470#define SERF_DEFLATE_DEFLATE 1 471 472serf_bucket_t *serf_bucket_deflate_create( 473 serf_bucket_t *stream, 474 serf_bucket_alloc_t *allocator, 475 int format); 476 477 478/* ==================================================================== */ 479 480 481extern const serf_bucket_type_t serf_bucket_type_limit; 482#define SERF_BUCKET_IS_LIMIT(b) SERF_BUCKET_CHECK((b), limit) 483 484serf_bucket_t *serf_bucket_limit_create( 485 serf_bucket_t *stream, 486 apr_uint64_t limit, 487 serf_bucket_alloc_t *allocator); 488 489 490/* ==================================================================== */ 491#define SERF_SSL_CERT_NOTYETVALID 1 492#define SERF_SSL_CERT_EXPIRED 2 493#define SERF_SSL_CERT_UNKNOWNCA 4 494#define SERF_SSL_CERT_SELF_SIGNED 8 495#define SERF_SSL_CERT_UNKNOWN_FAILURE 16 496#define SERF_SSL_CERT_REVOKED 32 497 498extern const serf_bucket_type_t serf_bucket_type_ssl_encrypt; 499#define SERF_BUCKET_IS_SSL_ENCRYPT(b) SERF_BUCKET_CHECK((b), ssl_encrypt) 500 501typedef struct serf_ssl_context_t serf_ssl_context_t; 502typedef struct serf_ssl_certificate_t serf_ssl_certificate_t; 503 504typedef apr_status_t (*serf_ssl_need_client_cert_t)( 505 void *data, 506 const char **cert_path); 507 508typedef apr_status_t (*serf_ssl_need_cert_password_t)( 509 void *data, 510 const char *cert_path, 511 const char **password); 512 513typedef apr_status_t (*serf_ssl_need_server_cert_t)( 514 void *data, 515 int failures, 516 const serf_ssl_certificate_t *cert); 517 518typedef apr_status_t (*serf_ssl_server_cert_chain_cb_t)( 519 void *data, 520 int failures, 521 int error_depth, 522 const serf_ssl_certificate_t * const * certs, 523 apr_size_t certs_len); 524 525void serf_ssl_client_cert_provider_set( 526 serf_ssl_context_t *context, 527 serf_ssl_need_client_cert_t callback, 528 void *data, 529 void *cache_pool); 530 531void serf_ssl_client_cert_password_set( 532 serf_ssl_context_t *context, 533 serf_ssl_need_cert_password_t callback, 534 void *data, 535 void *cache_pool); 536 537/** 538 * Set a callback to override the default SSL server certificate validation 539 * algorithm. 540 */ 541void serf_ssl_server_cert_callback_set( 542 serf_ssl_context_t *context, 543 serf_ssl_need_server_cert_t callback, 544 void *data); 545 546/** 547 * Set callbacks to override the default SSL server certificate validation 548 * algorithm for the current certificate or the entire certificate chain. 549 */ 550void serf_ssl_server_cert_chain_callback_set( 551 serf_ssl_context_t *context, 552 serf_ssl_need_server_cert_t cert_callback, 553 serf_ssl_server_cert_chain_cb_t cert_chain_callback, 554 void *data); 555 556/** 557 * Use the default root CA certificates as included with the OpenSSL library. 558 */ 559apr_status_t serf_ssl_use_default_certificates( 560 serf_ssl_context_t *context); 561 562/** 563 * Allow SNI indicators to be sent to the server. 564 */ 565apr_status_t serf_ssl_set_hostname( 566 serf_ssl_context_t *context, const char *hostname); 567 568/** 569 * Return the depth of the certificate. 570 */ 571int serf_ssl_cert_depth( 572 const serf_ssl_certificate_t *cert); 573 574/** 575 * Extract the fields of the issuer in a table with keys (E, CN, OU, O, L, 576 * ST and C). The returned table will be allocated in @a pool. 577 */ 578apr_hash_t *serf_ssl_cert_issuer( 579 const serf_ssl_certificate_t *cert, 580 apr_pool_t *pool); 581 582/** 583 * Extract the fields of the subject in a table with keys (E, CN, OU, O, L, 584 * ST and C). The returned table will be allocated in @a pool. 585 */ 586apr_hash_t *serf_ssl_cert_subject( 587 const serf_ssl_certificate_t *cert, 588 apr_pool_t *pool); 589 590/** 591 * Extract the fields of the certificate in a table with keys (sha1, notBefore, 592 * notAfter, subjectAltName). The returned table will be allocated in @a pool. 593 */ 594apr_hash_t *serf_ssl_cert_certificate( 595 const serf_ssl_certificate_t *cert, 596 apr_pool_t *pool); 597 598/** 599 * Export a certificate to base64-encoded, zero-terminated string. 600 * The returned string is allocated in @a pool. Returns NULL on failure. 601 */ 602const char *serf_ssl_cert_export( 603 const serf_ssl_certificate_t *cert, 604 apr_pool_t *pool); 605 606/** 607 * Load a CA certificate file from a path @a file_path. If the file was loaded 608 * and parsed correctly, a certificate @a cert will be created and returned. 609 * This certificate object will be alloced in @a pool. 610 */ 611apr_status_t serf_ssl_load_cert_file( 612 serf_ssl_certificate_t **cert, 613 const char *file_path, 614 apr_pool_t *pool); 615 616/** 617 * Adds the certificate @a cert to the list of trusted certificates in 618 * @a ssl_ctx that will be used for verification. 619 * See also @a serf_ssl_load_cert_file. 620 */ 621apr_status_t serf_ssl_trust_cert( 622 serf_ssl_context_t *ssl_ctx, 623 serf_ssl_certificate_t *cert); 624 625/** 626 * Enable or disable SSL compression on a SSL session. 627 * @a enabled = 1 to enable compression, 0 to disable compression. 628 * Default = disabled. 629 */ 630apr_status_t serf_ssl_use_compression( 631 serf_ssl_context_t *ssl_ctx, 632 int enabled); 633 634serf_bucket_t *serf_bucket_ssl_encrypt_create( 635 serf_bucket_t *stream, 636 serf_ssl_context_t *ssl_context, 637 serf_bucket_alloc_t *allocator); 638 639serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get( 640 serf_bucket_t *bucket); 641 642/* ==================================================================== */ 643 644 645extern const serf_bucket_type_t serf_bucket_type_ssl_decrypt; 646#define SERF_BUCKET_IS_SSL_DECRYPT(b) SERF_BUCKET_CHECK((b), ssl_decrypt) 647 648serf_bucket_t *serf_bucket_ssl_decrypt_create( 649 serf_bucket_t *stream, 650 serf_ssl_context_t *ssl_context, 651 serf_bucket_alloc_t *allocator); 652 653serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get( 654 serf_bucket_t *bucket); 655 656 657/* ==================================================================== */ 658 659 660extern const serf_bucket_type_t serf_bucket_type_barrier; 661#define SERF_BUCKET_IS_BARRIER(b) SERF_BUCKET_CHECK((b), barrier) 662 663serf_bucket_t *serf_bucket_barrier_create( 664 serf_bucket_t *stream, 665 serf_bucket_alloc_t *allocator); 666 667 668/* ==================================================================== */ 669 670extern const serf_bucket_type_t serf_bucket_type_iovec; 671#define SERF_BUCKET_IS_IOVEC(b) SERF_BUCKET_CHECK((b), iovec) 672 673serf_bucket_t *serf_bucket_iovec_create( 674 struct iovec vecs[], 675 int len, 676 serf_bucket_alloc_t *allocator); 677 678 679/* ==================================================================== */ 680 681/* ### do we need a PIPE bucket type? they are simple apr_file_t objects */ 682 683 684#ifdef __cplusplus 685} 686#endif 687 688#endif /* !SERF_BUCKET_TYPES_H */ 689