1 /* ====================================================================
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
18 * ====================================================================
21 #ifndef SERF_BUCKET_TYPES_H
22 #define SERF_BUCKET_TYPES_H
27 /* this header and serf.h refer to each other, so take a little extra care */
34 * @file serf_bucket_types.h
35 * @brief serf-supported bucket types
37 /* ### this whole file needs docco ... */
43 /* ==================================================================== */
46 extern const serf_bucket_type_t serf_bucket_type_request;
47 #define SERF_BUCKET_IS_REQUEST(b) SERF_BUCKET_CHECK((b), request)
49 serf_bucket_t *serf_bucket_request_create(
53 serf_bucket_alloc_t *allocator);
55 /* Send a Content-Length header with @a len. The @a body bucket should
56 contain precisely that much data. */
57 void serf_bucket_request_set_CL(
58 serf_bucket_t *bucket,
61 serf_bucket_t *serf_bucket_request_get_headers(
62 serf_bucket_t *request);
64 void serf_bucket_request_become(
65 serf_bucket_t *bucket,
71 * Sets the root url of the remote host. If this request contains a relative
72 * url, it will be prefixed with the root url to form an absolute url.
73 * @a bucket is the request bucket. @a root_url is the absolute url of the
74 * root of the remote host, without the closing '/'.
76 void serf_bucket_request_set_root(
77 serf_bucket_t *bucket,
78 const char *root_url);
80 /* ==================================================================== */
83 extern const serf_bucket_type_t serf_bucket_type_response;
84 #define SERF_BUCKET_IS_RESPONSE(b) SERF_BUCKET_CHECK((b), response)
86 serf_bucket_t *serf_bucket_response_create(
87 serf_bucket_t *stream,
88 serf_bucket_alloc_t *allocator);
90 #define SERF_HTTP_VERSION(major, minor) ((major) * 1000 + (minor))
91 #define SERF_HTTP_11 SERF_HTTP_VERSION(1, 1)
92 #define SERF_HTTP_10 SERF_HTTP_VERSION(1, 0)
93 #define SERF_HTTP_VERSION_MAJOR(shv) ((int)shv / 1000)
94 #define SERF_HTTP_VERSION_MINOR(shv) ((int)shv % 1000)
103 * Return the Status-Line information, if available. This function
104 * works like other bucket read functions: it may return APR_EAGAIN or
105 * APR_EOF to signal the state of the bucket for reading. A return
106 * value of APR_SUCCESS will always indicate that status line
107 * information was returned; for other return values the caller must
108 * check the version field in @a sline. A value of 0 means that the
109 * data is not (yet) present.
111 apr_status_t serf_bucket_response_status(
113 serf_status_line *sline);
116 * Wait for the HTTP headers to be processed for a @a response.
118 * If the headers are available, APR_SUCCESS is returned.
119 * If the headers aren't available, APR_EAGAIN is returned.
121 apr_status_t serf_bucket_response_wait_for_headers(
122 serf_bucket_t *response);
125 * Get the headers bucket for @a response.
127 serf_bucket_t *serf_bucket_response_get_headers(
128 serf_bucket_t *response);
131 * Advise the response @a bucket that this was from a HEAD request and
132 * that it should not expect to see a response body.
134 void serf_bucket_response_set_head(
135 serf_bucket_t *bucket);
137 /* ==================================================================== */
139 extern const serf_bucket_type_t serf_bucket_type_response_body;
140 #define SERF_BUCKET_IS_RESPONSE_BODY(b) SERF_BUCKET_CHECK((b), response_body)
142 serf_bucket_t *serf_bucket_response_body_create(
143 serf_bucket_t *stream,
145 serf_bucket_alloc_t *allocator);
147 /* ==================================================================== */
149 extern const serf_bucket_type_t serf_bucket_type_bwtp_frame;
150 #define SERF_BUCKET_IS_BWTP_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_frame)
152 extern const serf_bucket_type_t serf_bucket_type_bwtp_incoming_frame;
153 #define SERF_BUCKET_IS_BWTP_INCOMING_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_incoming_frame)
155 int serf_bucket_bwtp_frame_get_channel(
158 int serf_bucket_bwtp_frame_get_type(
161 const char *serf_bucket_bwtp_frame_get_phrase(
164 serf_bucket_t *serf_bucket_bwtp_frame_get_headers(
167 serf_bucket_t *serf_bucket_bwtp_channel_open(
170 serf_bucket_alloc_t *allocator);
172 serf_bucket_t *serf_bucket_bwtp_channel_close(
174 serf_bucket_alloc_t *allocator);
176 serf_bucket_t *serf_bucket_bwtp_header_create(
179 serf_bucket_alloc_t *allocator);
181 serf_bucket_t *serf_bucket_bwtp_message_create(
184 serf_bucket_alloc_t *allocator);
186 serf_bucket_t *serf_bucket_bwtp_incoming_frame_create(
188 serf_bucket_alloc_t *allocator);
190 apr_status_t serf_bucket_bwtp_incoming_frame_wait_for_headers(
193 /* ==================================================================== */
196 extern const serf_bucket_type_t serf_bucket_type_aggregate;
197 #define SERF_BUCKET_IS_AGGREGATE(b) SERF_BUCKET_CHECK((b), aggregate)
199 typedef apr_status_t (*serf_bucket_aggregate_eof_t)(
201 serf_bucket_t *aggregate_bucket);
203 /** serf_bucket_aggregate_cleanup will instantly destroy all buckets in
204 the aggregate bucket that have been read completely. Whereas normally,
205 these buckets are destroyed on every read operation. */
206 void serf_bucket_aggregate_cleanup(
207 serf_bucket_t *bucket,
208 serf_bucket_alloc_t *allocator);
210 serf_bucket_t *serf_bucket_aggregate_create(
211 serf_bucket_alloc_t *allocator);
213 /* Creates a stream bucket.
214 A stream bucket is like an aggregate bucket, but:
215 - it doesn't destroy its child buckets on cleanup
216 - one can always keep adding child buckets, the handler FN should return
217 APR_EOF when no more buckets will be added.
219 Note: keep this factory function internal for now. If it turns out this
220 bucket type is useful outside serf, we should make it an actual separate
223 serf_bucket_t *serf__bucket_stream_create(
224 serf_bucket_alloc_t *allocator,
225 serf_bucket_aggregate_eof_t fn,
228 /** Transform @a bucket in-place into an aggregate bucket. */
229 void serf_bucket_aggregate_become(
230 serf_bucket_t *bucket);
232 void serf_bucket_aggregate_prepend(
233 serf_bucket_t *aggregate_bucket,
234 serf_bucket_t *prepend_bucket);
236 void serf_bucket_aggregate_append(
237 serf_bucket_t *aggregate_bucket,
238 serf_bucket_t *append_bucket);
240 void serf_bucket_aggregate_hold_open(
241 serf_bucket_t *aggregate_bucket,
242 serf_bucket_aggregate_eof_t fn,
245 void serf_bucket_aggregate_prepend_iovec(
246 serf_bucket_t *aggregate_bucket,
250 void serf_bucket_aggregate_append_iovec(
251 serf_bucket_t *aggregate_bucket,
255 /* ==================================================================== */
258 extern const serf_bucket_type_t serf_bucket_type_file;
259 #define SERF_BUCKET_IS_FILE(b) SERF_BUCKET_CHECK((b), file)
261 serf_bucket_t *serf_bucket_file_create(
263 serf_bucket_alloc_t *allocator);
266 /* ==================================================================== */
269 extern const serf_bucket_type_t serf_bucket_type_socket;
270 #define SERF_BUCKET_IS_SOCKET(b) SERF_BUCKET_CHECK((b), socket)
272 serf_bucket_t *serf_bucket_socket_create(
274 serf_bucket_alloc_t *allocator);
277 * Call @a progress_func every time bytes are read from the socket, pass
278 * the number of bytes read.
280 * When using serf's bytes read & written progress indicator, pass
281 * @a serf_context_progress_delta for progress_func and the serf_context for
284 void serf_bucket_socket_set_read_progress_cb(
285 serf_bucket_t *bucket,
286 const serf_progress_t progress_func,
287 void *progress_baton);
289 /* ==================================================================== */
292 extern const serf_bucket_type_t serf_bucket_type_simple;
293 #define SERF_BUCKET_IS_SIMPLE(b) SERF_BUCKET_CHECK((b), simple)
295 typedef void (*serf_simple_freefunc_t)(
299 serf_bucket_t *serf_bucket_simple_create(
302 serf_simple_freefunc_t freefunc,
303 void *freefunc_baton,
304 serf_bucket_alloc_t *allocator);
307 * Equivalent to serf_bucket_simple_create, except that the bucket takes
308 * ownership of a private copy of the data.
310 serf_bucket_t *serf_bucket_simple_copy_create(
313 serf_bucket_alloc_t *allocator);
316 * Equivalent to serf_bucket_simple_create, except that the bucket assumes
317 * responsibility for freeing the data on this allocator without making
318 * a copy. It is assumed that data was created by a call from allocator.
320 serf_bucket_t *serf_bucket_simple_own_create(
323 serf_bucket_alloc_t *allocator);
325 #define SERF_BUCKET_SIMPLE_STRING(s,a) \
326 serf_bucket_simple_create(s, strlen(s), NULL, NULL, a);
328 #define SERF_BUCKET_SIMPLE_STRING_LEN(s,l,a) \
329 serf_bucket_simple_create(s, l, NULL, NULL, a);
331 /* ==================================================================== */
334 /* Note: apr_mmap_t is always defined, but if APR doesn't have mmaps, then
335 the caller can never create an apr_mmap_t to pass to this function. */
337 extern const serf_bucket_type_t serf_bucket_type_mmap;
338 #define SERF_BUCKET_IS_MMAP(b) SERF_BUCKET_CHECK((b), mmap)
340 serf_bucket_t *serf_bucket_mmap_create(
342 serf_bucket_alloc_t *allocator);
345 /* ==================================================================== */
348 extern const serf_bucket_type_t serf_bucket_type_headers;
349 #define SERF_BUCKET_IS_HEADERS(b) SERF_BUCKET_CHECK((b), headers)
351 serf_bucket_t *serf_bucket_headers_create(
352 serf_bucket_alloc_t *allocator);
355 * Set, default: value copied.
357 * Set the specified @a header within the bucket, copying the @a value
358 * into space from this bucket's allocator. The header is NOT copied,
359 * so it should remain in scope at least as long as the bucket.
361 void serf_bucket_headers_set(
362 serf_bucket_t *headers_bucket,
367 * Set, copies: header and value copied.
369 * Copy the specified @a header and @a value into the bucket, using space
370 * from this bucket's allocator.
372 void serf_bucket_headers_setc(
373 serf_bucket_t *headers_bucket,
380 * Set the specified @a header and @a value into the bucket, without
381 * copying either attribute. Both attributes should remain in scope at
382 * least as long as the bucket.
384 * @note In the case where a header already exists this will result
385 * in a reallocation and copy, @see serf_bucket_headers_setn.
387 void serf_bucket_headers_setn(
388 serf_bucket_t *headers_bucket,
393 * Set, extended: fine grained copy control of header and value.
395 * Set the specified @a header, with length @a header_size with the
396 * @a value, and length @a value_size, into the bucket. The header will
397 * be copied if @a header_copy is set, and the value is copied if
398 * @a value_copy is set. If the values are not copied, then they should
399 * remain in scope at least as long as the bucket.
401 * If @a headers_bucket already contains a header with the same name
402 * as @a header, then append @a value to the existing value,
403 * separating with a comma (as per RFC 2616, section 4.2). In this
404 * case, the new value must be allocated and the header re-used, so
405 * behave as if @a value_copy were true and @a header_copy false.
407 void serf_bucket_headers_setx(
408 serf_bucket_t *headers_bucket,
410 apr_size_t header_size,
413 apr_size_t value_size,
416 const char *serf_bucket_headers_get(
417 serf_bucket_t *headers_bucket,
421 * @param baton opaque baton as passed to @see serf_bucket_headers_do
422 * @param key The header key from this iteration through the table
423 * @param value The header value from this iteration through the table
425 typedef int (serf_bucket_headers_do_callback_fn_t)(
431 * Iterates over all headers of the message and invokes the callback
432 * function with header key and value. Stop iterating when no more
433 * headers are available or when the callback function returned a
436 * @param headers_bucket headers to iterate over
437 * @param func callback routine to invoke for every header in the bucket
438 * @param baton baton to pass on each invocation to func
440 void serf_bucket_headers_do(
441 serf_bucket_t *headers_bucket,
442 serf_bucket_headers_do_callback_fn_t func,
446 /* ==================================================================== */
449 extern const serf_bucket_type_t serf_bucket_type_chunk;
450 #define SERF_BUCKET_IS_CHUNK(b) SERF_BUCKET_CHECK((b), chunk)
452 serf_bucket_t *serf_bucket_chunk_create(
453 serf_bucket_t *stream,
454 serf_bucket_alloc_t *allocator);
457 /* ==================================================================== */
460 extern const serf_bucket_type_t serf_bucket_type_dechunk;
461 #define SERF_BUCKET_IS_DECHUNK(b) SERF_BUCKET_CHECK((b), dechunk)
463 serf_bucket_t *serf_bucket_dechunk_create(
464 serf_bucket_t *stream,
465 serf_bucket_alloc_t *allocator);
468 /* ==================================================================== */
471 extern const serf_bucket_type_t serf_bucket_type_deflate;
472 #define SERF_BUCKET_IS_DEFLATE(b) SERF_BUCKET_CHECK((b), deflate)
474 #define SERF_DEFLATE_GZIP 0
475 #define SERF_DEFLATE_DEFLATE 1
477 serf_bucket_t *serf_bucket_deflate_create(
478 serf_bucket_t *stream,
479 serf_bucket_alloc_t *allocator,
483 /* ==================================================================== */
486 extern const serf_bucket_type_t serf_bucket_type_limit;
487 #define SERF_BUCKET_IS_LIMIT(b) SERF_BUCKET_CHECK((b), limit)
489 serf_bucket_t *serf_bucket_limit_create(
490 serf_bucket_t *stream,
492 serf_bucket_alloc_t *allocator);
495 /* ==================================================================== */
496 #define SERF_SSL_CERT_NOTYETVALID 1
497 #define SERF_SSL_CERT_EXPIRED 2
498 #define SERF_SSL_CERT_UNKNOWNCA 4
499 #define SERF_SSL_CERT_SELF_SIGNED 8
500 #define SERF_SSL_CERT_UNKNOWN_FAILURE 16
501 #define SERF_SSL_CERT_REVOKED 32
503 extern const serf_bucket_type_t serf_bucket_type_ssl_encrypt;
504 #define SERF_BUCKET_IS_SSL_ENCRYPT(b) SERF_BUCKET_CHECK((b), ssl_encrypt)
506 typedef struct serf_ssl_context_t serf_ssl_context_t;
507 typedef struct serf_ssl_certificate_t serf_ssl_certificate_t;
509 typedef apr_status_t (*serf_ssl_need_client_cert_t)(
511 const char **cert_path);
513 typedef apr_status_t (*serf_ssl_need_cert_password_t)(
515 const char *cert_path,
516 const char **password);
518 typedef apr_status_t (*serf_ssl_need_server_cert_t)(
521 const serf_ssl_certificate_t *cert);
523 typedef apr_status_t (*serf_ssl_server_cert_chain_cb_t)(
527 const serf_ssl_certificate_t * const * certs,
528 apr_size_t certs_len);
530 void serf_ssl_client_cert_provider_set(
531 serf_ssl_context_t *context,
532 serf_ssl_need_client_cert_t callback,
536 void serf_ssl_client_cert_password_set(
537 serf_ssl_context_t *context,
538 serf_ssl_need_cert_password_t callback,
543 * Set a callback to override the default SSL server certificate validation
546 void serf_ssl_server_cert_callback_set(
547 serf_ssl_context_t *context,
548 serf_ssl_need_server_cert_t callback,
552 * Set callbacks to override the default SSL server certificate validation
553 * algorithm for the current certificate or the entire certificate chain.
555 void serf_ssl_server_cert_chain_callback_set(
556 serf_ssl_context_t *context,
557 serf_ssl_need_server_cert_t cert_callback,
558 serf_ssl_server_cert_chain_cb_t cert_chain_callback,
562 * Use the default root CA certificates as included with the OpenSSL library.
564 apr_status_t serf_ssl_use_default_certificates(
565 serf_ssl_context_t *context);
568 * Allow SNI indicators to be sent to the server.
570 apr_status_t serf_ssl_set_hostname(
571 serf_ssl_context_t *context, const char *hostname);
574 * Return the depth of the certificate.
576 int serf_ssl_cert_depth(
577 const serf_ssl_certificate_t *cert);
580 * Extract the fields of the issuer in a table with keys (E, CN, OU, O, L,
581 * ST and C). The returned table will be allocated in @a pool.
583 apr_hash_t *serf_ssl_cert_issuer(
584 const serf_ssl_certificate_t *cert,
588 * Extract the fields of the subject in a table with keys (E, CN, OU, O, L,
589 * ST and C). The returned table will be allocated in @a pool.
591 apr_hash_t *serf_ssl_cert_subject(
592 const serf_ssl_certificate_t *cert,
596 * Extract the fields of the certificate in a table with keys (sha1, notBefore,
597 * notAfter, subjectAltName). The returned table will be allocated in @a pool.
599 apr_hash_t *serf_ssl_cert_certificate(
600 const serf_ssl_certificate_t *cert,
604 * Export a certificate to base64-encoded, zero-terminated string.
605 * The returned string is allocated in @a pool. Returns NULL on failure.
607 const char *serf_ssl_cert_export(
608 const serf_ssl_certificate_t *cert,
612 * Load a CA certificate file from a path @a file_path. If the file was loaded
613 * and parsed correctly, a certificate @a cert will be created and returned.
614 * This certificate object will be alloced in @a pool.
616 apr_status_t serf_ssl_load_cert_file(
617 serf_ssl_certificate_t **cert,
618 const char *file_path,
622 * Adds the certificate @a cert to the list of trusted certificates in
623 * @a ssl_ctx that will be used for verification.
624 * See also @a serf_ssl_load_cert_file.
626 apr_status_t serf_ssl_trust_cert(
627 serf_ssl_context_t *ssl_ctx,
628 serf_ssl_certificate_t *cert);
631 * Enable or disable SSL compression on a SSL session.
632 * @a enabled = 1 to enable compression, 0 to disable compression.
633 * Default = disabled.
635 apr_status_t serf_ssl_use_compression(
636 serf_ssl_context_t *ssl_ctx,
639 serf_bucket_t *serf_bucket_ssl_encrypt_create(
640 serf_bucket_t *stream,
641 serf_ssl_context_t *ssl_context,
642 serf_bucket_alloc_t *allocator);
644 serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get(
645 serf_bucket_t *bucket);
647 /* ==================================================================== */
650 extern const serf_bucket_type_t serf_bucket_type_ssl_decrypt;
651 #define SERF_BUCKET_IS_SSL_DECRYPT(b) SERF_BUCKET_CHECK((b), ssl_decrypt)
653 serf_bucket_t *serf_bucket_ssl_decrypt_create(
654 serf_bucket_t *stream,
655 serf_ssl_context_t *ssl_context,
656 serf_bucket_alloc_t *allocator);
658 serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get(
659 serf_bucket_t *bucket);
662 /* ==================================================================== */
665 extern const serf_bucket_type_t serf_bucket_type_barrier;
666 #define SERF_BUCKET_IS_BARRIER(b) SERF_BUCKET_CHECK((b), barrier)
668 serf_bucket_t *serf_bucket_barrier_create(
669 serf_bucket_t *stream,
670 serf_bucket_alloc_t *allocator);
673 /* ==================================================================== */
675 extern const serf_bucket_type_t serf_bucket_type_iovec;
676 #define SERF_BUCKET_IS_IOVEC(b) SERF_BUCKET_CHECK((b), iovec)
678 serf_bucket_t *serf_bucket_iovec_create(
681 serf_bucket_alloc_t *allocator);
684 /* ==================================================================== */
686 /* ### do we need a PIPE bucket type? they are simple apr_file_t objects */
693 #endif /* !SERF_BUCKET_TYPES_H */