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