1 /* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #ifndef SERF_BUCKET_TYPES_H
17 #define SERF_BUCKET_TYPES_H
22 /* this header and serf.h refer to each other, so take a little extra care */
29 * @file serf_bucket_types.h
30 * @brief serf-supported bucket types
32 /* ### this whole file needs docco ... */
38 /* ==================================================================== */
41 extern const serf_bucket_type_t serf_bucket_type_request;
42 #define SERF_BUCKET_IS_REQUEST(b) SERF_BUCKET_CHECK((b), request)
44 serf_bucket_t *serf_bucket_request_create(
48 serf_bucket_alloc_t *allocator);
50 /* Send a Content-Length header with @a len. The @a body bucket should
51 contain precisely that much data. */
52 void serf_bucket_request_set_CL(
53 serf_bucket_t *bucket,
56 serf_bucket_t *serf_bucket_request_get_headers(
57 serf_bucket_t *request);
59 void serf_bucket_request_become(
60 serf_bucket_t *bucket,
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 '/'.
71 void serf_bucket_request_set_root(
72 serf_bucket_t *bucket,
73 const char *root_url);
75 /* ==================================================================== */
78 extern const serf_bucket_type_t serf_bucket_type_response;
79 #define SERF_BUCKET_IS_RESPONSE(b) SERF_BUCKET_CHECK((b), response)
81 serf_bucket_t *serf_bucket_response_create(
82 serf_bucket_t *stream,
83 serf_bucket_alloc_t *allocator);
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)
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.
106 apr_status_t serf_bucket_response_status(
108 serf_status_line *sline);
111 * Wait for the HTTP headers to be processed for a @a response.
113 * If the headers are available, APR_SUCCESS is returned.
114 * If the headers aren't available, APR_EAGAIN is returned.
116 apr_status_t serf_bucket_response_wait_for_headers(
117 serf_bucket_t *response);
120 * Get the headers bucket for @a response.
122 serf_bucket_t *serf_bucket_response_get_headers(
123 serf_bucket_t *response);
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.
129 void serf_bucket_response_set_head(
130 serf_bucket_t *bucket);
132 /* ==================================================================== */
134 extern const serf_bucket_type_t serf_bucket_type_response_body;
135 #define SERF_BUCKET_IS_RESPONSE_BODY(b) SERF_BUCKET_CHECK((b), response_body)
137 serf_bucket_t *serf_bucket_response_body_create(
138 serf_bucket_t *stream,
140 serf_bucket_alloc_t *allocator);
142 /* ==================================================================== */
144 extern const serf_bucket_type_t serf_bucket_type_bwtp_frame;
145 #define SERF_BUCKET_IS_BWTP_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_frame)
147 extern 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)
150 int serf_bucket_bwtp_frame_get_channel(
153 int serf_bucket_bwtp_frame_get_type(
156 const char *serf_bucket_bwtp_frame_get_phrase(
159 serf_bucket_t *serf_bucket_bwtp_frame_get_headers(
162 serf_bucket_t *serf_bucket_bwtp_channel_open(
165 serf_bucket_alloc_t *allocator);
167 serf_bucket_t *serf_bucket_bwtp_channel_close(
169 serf_bucket_alloc_t *allocator);
171 serf_bucket_t *serf_bucket_bwtp_header_create(
174 serf_bucket_alloc_t *allocator);
176 serf_bucket_t *serf_bucket_bwtp_message_create(
179 serf_bucket_alloc_t *allocator);
181 serf_bucket_t *serf_bucket_bwtp_incoming_frame_create(
183 serf_bucket_alloc_t *allocator);
185 apr_status_t serf_bucket_bwtp_incoming_frame_wait_for_headers(
188 /* ==================================================================== */
191 extern const serf_bucket_type_t serf_bucket_type_aggregate;
192 #define SERF_BUCKET_IS_AGGREGATE(b) SERF_BUCKET_CHECK((b), aggregate)
194 typedef apr_status_t (*serf_bucket_aggregate_eof_t)(
196 serf_bucket_t *aggregate_bucket);
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. */
201 void serf_bucket_aggregate_cleanup(
202 serf_bucket_t *bucket,
203 serf_bucket_alloc_t *allocator);
205 serf_bucket_t *serf_bucket_aggregate_create(
206 serf_bucket_alloc_t *allocator);
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.
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
218 serf_bucket_t *serf__bucket_stream_create(
219 serf_bucket_alloc_t *allocator,
220 serf_bucket_aggregate_eof_t fn,
223 /** Transform @a bucket in-place into an aggregate bucket. */
224 void serf_bucket_aggregate_become(
225 serf_bucket_t *bucket);
227 void serf_bucket_aggregate_prepend(
228 serf_bucket_t *aggregate_bucket,
229 serf_bucket_t *prepend_bucket);
231 void serf_bucket_aggregate_append(
232 serf_bucket_t *aggregate_bucket,
233 serf_bucket_t *append_bucket);
235 void serf_bucket_aggregate_hold_open(
236 serf_bucket_t *aggregate_bucket,
237 serf_bucket_aggregate_eof_t fn,
240 void serf_bucket_aggregate_prepend_iovec(
241 serf_bucket_t *aggregate_bucket,
245 void serf_bucket_aggregate_append_iovec(
246 serf_bucket_t *aggregate_bucket,
250 /* ==================================================================== */
253 extern const serf_bucket_type_t serf_bucket_type_file;
254 #define SERF_BUCKET_IS_FILE(b) SERF_BUCKET_CHECK((b), file)
256 serf_bucket_t *serf_bucket_file_create(
258 serf_bucket_alloc_t *allocator);
261 /* ==================================================================== */
264 extern const serf_bucket_type_t serf_bucket_type_socket;
265 #define SERF_BUCKET_IS_SOCKET(b) SERF_BUCKET_CHECK((b), socket)
267 serf_bucket_t *serf_bucket_socket_create(
269 serf_bucket_alloc_t *allocator);
272 * Call @a progress_func every time bytes are read from the socket, pass
273 * the number of bytes read.
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
279 void serf_bucket_socket_set_read_progress_cb(
280 serf_bucket_t *bucket,
281 const serf_progress_t progress_func,
282 void *progress_baton);
284 /* ==================================================================== */
287 extern const serf_bucket_type_t serf_bucket_type_simple;
288 #define SERF_BUCKET_IS_SIMPLE(b) SERF_BUCKET_CHECK((b), simple)
290 typedef void (*serf_simple_freefunc_t)(
294 serf_bucket_t *serf_bucket_simple_create(
297 serf_simple_freefunc_t freefunc,
298 void *freefunc_baton,
299 serf_bucket_alloc_t *allocator);
302 * Equivalent to serf_bucket_simple_create, except that the bucket takes
303 * ownership of a private copy of the data.
305 serf_bucket_t *serf_bucket_simple_copy_create(
308 serf_bucket_alloc_t *allocator);
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.
315 serf_bucket_t *serf_bucket_simple_own_create(
318 serf_bucket_alloc_t *allocator);
320 #define SERF_BUCKET_SIMPLE_STRING(s,a) \
321 serf_bucket_simple_create(s, strlen(s), NULL, NULL, a);
323 #define SERF_BUCKET_SIMPLE_STRING_LEN(s,l,a) \
324 serf_bucket_simple_create(s, l, NULL, NULL, a);
326 /* ==================================================================== */
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. */
332 extern const serf_bucket_type_t serf_bucket_type_mmap;
333 #define SERF_BUCKET_IS_MMAP(b) SERF_BUCKET_CHECK((b), mmap)
335 serf_bucket_t *serf_bucket_mmap_create(
337 serf_bucket_alloc_t *allocator);
340 /* ==================================================================== */
343 extern const serf_bucket_type_t serf_bucket_type_headers;
344 #define SERF_BUCKET_IS_HEADERS(b) SERF_BUCKET_CHECK((b), headers)
346 serf_bucket_t *serf_bucket_headers_create(
347 serf_bucket_alloc_t *allocator);
350 * Set, default: value copied.
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.
356 void serf_bucket_headers_set(
357 serf_bucket_t *headers_bucket,
362 * Set, copies: header and value copied.
364 * Copy the specified @a header and @a value into the bucket, using space
365 * from this bucket's allocator.
367 void serf_bucket_headers_setc(
368 serf_bucket_t *headers_bucket,
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.
379 * @note In the case where a header already exists this will result
380 * in a reallocation and copy, @see serf_bucket_headers_setn.
382 void serf_bucket_headers_setn(
383 serf_bucket_t *headers_bucket,
388 * Set, extended: fine grained copy control of header and value.
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.
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.
402 void serf_bucket_headers_setx(
403 serf_bucket_t *headers_bucket,
405 apr_size_t header_size,
408 apr_size_t value_size,
411 const char *serf_bucket_headers_get(
412 serf_bucket_t *headers_bucket,
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
420 typedef int (serf_bucket_headers_do_callback_fn_t)(
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
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
435 void serf_bucket_headers_do(
436 serf_bucket_t *headers_bucket,
437 serf_bucket_headers_do_callback_fn_t func,
441 /* ==================================================================== */
444 extern const serf_bucket_type_t serf_bucket_type_chunk;
445 #define SERF_BUCKET_IS_CHUNK(b) SERF_BUCKET_CHECK((b), chunk)
447 serf_bucket_t *serf_bucket_chunk_create(
448 serf_bucket_t *stream,
449 serf_bucket_alloc_t *allocator);
452 /* ==================================================================== */
455 extern const serf_bucket_type_t serf_bucket_type_dechunk;
456 #define SERF_BUCKET_IS_DECHUNK(b) SERF_BUCKET_CHECK((b), dechunk)
458 serf_bucket_t *serf_bucket_dechunk_create(
459 serf_bucket_t *stream,
460 serf_bucket_alloc_t *allocator);
463 /* ==================================================================== */
466 extern const serf_bucket_type_t serf_bucket_type_deflate;
467 #define SERF_BUCKET_IS_DEFLATE(b) SERF_BUCKET_CHECK((b), deflate)
469 #define SERF_DEFLATE_GZIP 0
470 #define SERF_DEFLATE_DEFLATE 1
472 serf_bucket_t *serf_bucket_deflate_create(
473 serf_bucket_t *stream,
474 serf_bucket_alloc_t *allocator,
478 /* ==================================================================== */
481 extern const serf_bucket_type_t serf_bucket_type_limit;
482 #define SERF_BUCKET_IS_LIMIT(b) SERF_BUCKET_CHECK((b), limit)
484 serf_bucket_t *serf_bucket_limit_create(
485 serf_bucket_t *stream,
487 serf_bucket_alloc_t *allocator);
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
498 extern const serf_bucket_type_t serf_bucket_type_ssl_encrypt;
499 #define SERF_BUCKET_IS_SSL_ENCRYPT(b) SERF_BUCKET_CHECK((b), ssl_encrypt)
501 typedef struct serf_ssl_context_t serf_ssl_context_t;
502 typedef struct serf_ssl_certificate_t serf_ssl_certificate_t;
504 typedef apr_status_t (*serf_ssl_need_client_cert_t)(
506 const char **cert_path);
508 typedef apr_status_t (*serf_ssl_need_cert_password_t)(
510 const char *cert_path,
511 const char **password);
513 typedef apr_status_t (*serf_ssl_need_server_cert_t)(
516 const serf_ssl_certificate_t *cert);
518 typedef apr_status_t (*serf_ssl_server_cert_chain_cb_t)(
522 const serf_ssl_certificate_t * const * certs,
523 apr_size_t certs_len);
525 void serf_ssl_client_cert_provider_set(
526 serf_ssl_context_t *context,
527 serf_ssl_need_client_cert_t callback,
531 void serf_ssl_client_cert_password_set(
532 serf_ssl_context_t *context,
533 serf_ssl_need_cert_password_t callback,
538 * Set a callback to override the default SSL server certificate validation
541 void serf_ssl_server_cert_callback_set(
542 serf_ssl_context_t *context,
543 serf_ssl_need_server_cert_t callback,
547 * Set callbacks to override the default SSL server certificate validation
548 * algorithm for the current certificate or the entire certificate chain.
550 void 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,
557 * Use the default root CA certificates as included with the OpenSSL library.
559 apr_status_t serf_ssl_use_default_certificates(
560 serf_ssl_context_t *context);
563 * Allow SNI indicators to be sent to the server.
565 apr_status_t serf_ssl_set_hostname(
566 serf_ssl_context_t *context, const char *hostname);
569 * Return the depth of the certificate.
571 int serf_ssl_cert_depth(
572 const serf_ssl_certificate_t *cert);
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.
578 apr_hash_t *serf_ssl_cert_issuer(
579 const serf_ssl_certificate_t *cert,
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.
586 apr_hash_t *serf_ssl_cert_subject(
587 const serf_ssl_certificate_t *cert,
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.
594 apr_hash_t *serf_ssl_cert_certificate(
595 const serf_ssl_certificate_t *cert,
599 * Export a certificate to base64-encoded, zero-terminated string.
600 * The returned string is allocated in @a pool. Returns NULL on failure.
602 const char *serf_ssl_cert_export(
603 const serf_ssl_certificate_t *cert,
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.
611 apr_status_t serf_ssl_load_cert_file(
612 serf_ssl_certificate_t **cert,
613 const char *file_path,
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.
621 apr_status_t serf_ssl_trust_cert(
622 serf_ssl_context_t *ssl_ctx,
623 serf_ssl_certificate_t *cert);
626 * Enable or disable SSL compression on a SSL session.
627 * @a enabled = 1 to enable compression, 0 to disable compression.
628 * Default = disabled.
630 apr_status_t serf_ssl_use_compression(
631 serf_ssl_context_t *ssl_ctx,
634 serf_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);
639 serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get(
640 serf_bucket_t *bucket);
642 /* ==================================================================== */
645 extern const serf_bucket_type_t serf_bucket_type_ssl_decrypt;
646 #define SERF_BUCKET_IS_SSL_DECRYPT(b) SERF_BUCKET_CHECK((b), ssl_decrypt)
648 serf_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);
653 serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get(
654 serf_bucket_t *bucket);
657 /* ==================================================================== */
660 extern const serf_bucket_type_t serf_bucket_type_barrier;
661 #define SERF_BUCKET_IS_BARRIER(b) SERF_BUCKET_CHECK((b), barrier)
663 serf_bucket_t *serf_bucket_barrier_create(
664 serf_bucket_t *stream,
665 serf_bucket_alloc_t *allocator);
668 /* ==================================================================== */
670 extern const serf_bucket_type_t serf_bucket_type_iovec;
671 #define SERF_BUCKET_IS_IOVEC(b) SERF_BUCKET_CHECK((b), iovec)
673 serf_bucket_t *serf_bucket_iovec_create(
676 serf_bucket_alloc_t *allocator);
679 /* ==================================================================== */
681 /* ### do we need a PIPE bucket type? they are simple apr_file_t objects */
688 #endif /* !SERF_BUCKET_TYPES_H */