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
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
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
17 *    under the License.
18 * ====================================================================
19 */
20
21#ifndef SERF_BUCKET_TYPES_H
22#define SERF_BUCKET_TYPES_H
23
24#include <apr_mmap.h>
25#include <apr_hash.h>
26
27/* this header and serf.h refer to each other, so take a little extra care */
28#ifndef SERF_H
29#include "serf.h"
30#endif
31
32
33/**
34 * @file serf_bucket_types.h
35 * @brief serf-supported bucket types
36 */
37/* ### this whole file needs docco ... */
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/* ==================================================================== */
44
45
46extern const serf_bucket_type_t serf_bucket_type_request;
47#define SERF_BUCKET_IS_REQUEST(b) SERF_BUCKET_CHECK((b), request)
48
49serf_bucket_t *serf_bucket_request_create(
50    const char *method,
51    const char *URI,
52    serf_bucket_t *body,
53    serf_bucket_alloc_t *allocator);
54
55/* Send a Content-Length header with @a len. The @a body bucket should
56   contain precisely that much data.  */
57void serf_bucket_request_set_CL(
58    serf_bucket_t *bucket,
59    apr_int64_t len);
60
61serf_bucket_t *serf_bucket_request_get_headers(
62    serf_bucket_t *request);
63
64void serf_bucket_request_become(
65    serf_bucket_t *bucket,
66    const char *method,
67    const char *uri,
68    serf_bucket_t *body);
69
70/**
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 '/'.
75 */
76void serf_bucket_request_set_root(
77    serf_bucket_t *bucket,
78    const char *root_url);
79
80/* ==================================================================== */
81
82
83extern const serf_bucket_type_t serf_bucket_type_response;
84#define SERF_BUCKET_IS_RESPONSE(b) SERF_BUCKET_CHECK((b), response)
85
86serf_bucket_t *serf_bucket_response_create(
87    serf_bucket_t *stream,
88    serf_bucket_alloc_t *allocator);
89
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)
95
96typedef struct {
97    int version;
98    int code;
99    const char *reason;
100} serf_status_line;
101
102/**
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.
110 */
111apr_status_t serf_bucket_response_status(
112    serf_bucket_t *bkt,
113    serf_status_line *sline);
114
115/**
116 * Wait for the HTTP headers to be processed for a @a response.
117 *
118 * If the headers are available, APR_SUCCESS is returned.
119 * If the headers aren't available, APR_EAGAIN is returned.
120 */
121apr_status_t serf_bucket_response_wait_for_headers(
122    serf_bucket_t *response);
123
124/**
125 * Get the headers bucket for @a response.
126 */
127serf_bucket_t *serf_bucket_response_get_headers(
128    serf_bucket_t *response);
129
130/**
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.
133 */
134void serf_bucket_response_set_head(
135    serf_bucket_t *bucket);
136
137/* ==================================================================== */
138
139extern const serf_bucket_type_t serf_bucket_type_response_body;
140#define SERF_BUCKET_IS_RESPONSE_BODY(b) SERF_BUCKET_CHECK((b), response_body)
141
142serf_bucket_t *serf_bucket_response_body_create(
143    serf_bucket_t *stream,
144    apr_uint64_t limit,
145    serf_bucket_alloc_t *allocator);
146
147/* ==================================================================== */
148
149extern const serf_bucket_type_t serf_bucket_type_bwtp_frame;
150#define SERF_BUCKET_IS_BWTP_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_frame)
151
152extern 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)
154
155int serf_bucket_bwtp_frame_get_channel(
156    serf_bucket_t *hdr);
157
158int serf_bucket_bwtp_frame_get_type(
159    serf_bucket_t *hdr);
160
161const char *serf_bucket_bwtp_frame_get_phrase(
162    serf_bucket_t *hdr);
163
164serf_bucket_t *serf_bucket_bwtp_frame_get_headers(
165    serf_bucket_t *hdr);
166
167serf_bucket_t *serf_bucket_bwtp_channel_open(
168    int channel,
169    const char *URI,
170    serf_bucket_alloc_t *allocator);
171
172serf_bucket_t *serf_bucket_bwtp_channel_close(
173    int channel,
174    serf_bucket_alloc_t *allocator);
175
176serf_bucket_t *serf_bucket_bwtp_header_create(
177    int channel,
178    const char *phrase,
179    serf_bucket_alloc_t *allocator);
180
181serf_bucket_t *serf_bucket_bwtp_message_create(
182    int channel,
183    serf_bucket_t *body,
184    serf_bucket_alloc_t *allocator);
185
186serf_bucket_t *serf_bucket_bwtp_incoming_frame_create(
187    serf_bucket_t *bkt,
188    serf_bucket_alloc_t *allocator);
189
190apr_status_t serf_bucket_bwtp_incoming_frame_wait_for_headers(
191    serf_bucket_t *bkt);
192
193/* ==================================================================== */
194
195
196extern const serf_bucket_type_t serf_bucket_type_aggregate;
197#define SERF_BUCKET_IS_AGGREGATE(b) SERF_BUCKET_CHECK((b), aggregate)
198
199typedef apr_status_t (*serf_bucket_aggregate_eof_t)(
200    void *baton,
201    serf_bucket_t *aggregate_bucket);
202
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. */
206void serf_bucket_aggregate_cleanup(
207    serf_bucket_t *bucket,
208    serf_bucket_alloc_t *allocator);
209
210serf_bucket_t *serf_bucket_aggregate_create(
211    serf_bucket_alloc_t *allocator);
212
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.
218
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
221  type.
222  */
223serf_bucket_t *serf__bucket_stream_create(
224    serf_bucket_alloc_t *allocator,
225    serf_bucket_aggregate_eof_t fn,
226    void *baton);
227
228/** Transform @a bucket in-place into an aggregate bucket. */
229void serf_bucket_aggregate_become(
230    serf_bucket_t *bucket);
231
232void serf_bucket_aggregate_prepend(
233    serf_bucket_t *aggregate_bucket,
234    serf_bucket_t *prepend_bucket);
235
236void serf_bucket_aggregate_append(
237    serf_bucket_t *aggregate_bucket,
238    serf_bucket_t *append_bucket);
239
240void serf_bucket_aggregate_hold_open(
241    serf_bucket_t *aggregate_bucket,
242    serf_bucket_aggregate_eof_t fn,
243    void *baton);
244
245void serf_bucket_aggregate_prepend_iovec(
246    serf_bucket_t *aggregate_bucket,
247    struct iovec *vecs,
248    int vecs_count);
249
250void serf_bucket_aggregate_append_iovec(
251    serf_bucket_t *aggregate_bucket,
252    struct iovec *vecs,
253    int vecs_count);
254
255/* ==================================================================== */
256
257
258extern const serf_bucket_type_t serf_bucket_type_file;
259#define SERF_BUCKET_IS_FILE(b) SERF_BUCKET_CHECK((b), file)
260
261serf_bucket_t *serf_bucket_file_create(
262    apr_file_t *file,
263    serf_bucket_alloc_t *allocator);
264
265
266/* ==================================================================== */
267
268
269extern const serf_bucket_type_t serf_bucket_type_socket;
270#define SERF_BUCKET_IS_SOCKET(b) SERF_BUCKET_CHECK((b), socket)
271
272serf_bucket_t *serf_bucket_socket_create(
273    apr_socket_t *skt,
274    serf_bucket_alloc_t *allocator);
275
276/**
277 * Call @a progress_func every time bytes are read from the socket, pass
278 * the number of bytes read.
279 *
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
282 * progress_baton.
283 */
284void serf_bucket_socket_set_read_progress_cb(
285    serf_bucket_t *bucket,
286    const serf_progress_t progress_func,
287    void *progress_baton);
288
289/* ==================================================================== */
290
291
292extern const serf_bucket_type_t serf_bucket_type_simple;
293#define SERF_BUCKET_IS_SIMPLE(b) SERF_BUCKET_CHECK((b), simple)
294
295typedef void (*serf_simple_freefunc_t)(
296    void *baton,
297    const char *data);
298
299serf_bucket_t *serf_bucket_simple_create(
300    const char *data,
301    apr_size_t len,
302    serf_simple_freefunc_t freefunc,
303    void *freefunc_baton,
304    serf_bucket_alloc_t *allocator);
305
306/**
307 * Equivalent to serf_bucket_simple_create, except that the bucket takes
308 * ownership of a private copy of the data.
309 */
310serf_bucket_t *serf_bucket_simple_copy_create(
311    const char *data,
312    apr_size_t len,
313    serf_bucket_alloc_t *allocator);
314
315/**
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.
319 */
320serf_bucket_t *serf_bucket_simple_own_create(
321    const char *data,
322    apr_size_t len,
323    serf_bucket_alloc_t *allocator);
324
325#define SERF_BUCKET_SIMPLE_STRING(s,a) \
326    serf_bucket_simple_create(s, strlen(s), NULL, NULL, a);
327
328#define SERF_BUCKET_SIMPLE_STRING_LEN(s,l,a) \
329    serf_bucket_simple_create(s, l, NULL, NULL, a);
330
331/* ==================================================================== */
332
333
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. */
336
337extern const serf_bucket_type_t serf_bucket_type_mmap;
338#define SERF_BUCKET_IS_MMAP(b) SERF_BUCKET_CHECK((b), mmap)
339
340serf_bucket_t *serf_bucket_mmap_create(
341    apr_mmap_t *mmap,
342    serf_bucket_alloc_t *allocator);
343
344
345/* ==================================================================== */
346
347
348extern const serf_bucket_type_t serf_bucket_type_headers;
349#define SERF_BUCKET_IS_HEADERS(b) SERF_BUCKET_CHECK((b), headers)
350
351serf_bucket_t *serf_bucket_headers_create(
352    serf_bucket_alloc_t *allocator);
353
354/**
355 * Set, default: value copied.
356 *
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.
360 */
361void serf_bucket_headers_set(
362    serf_bucket_t *headers_bucket,
363    const char *header,
364    const char *value);
365
366/**
367 * Set, copies: header and value copied.
368 *
369 * Copy the specified @a header and @a value into the bucket, using space
370 * from this bucket's allocator.
371 */
372void serf_bucket_headers_setc(
373    serf_bucket_t *headers_bucket,
374    const char *header,
375    const char *value);
376
377/**
378 * Set, no copies.
379 *
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.
383 *
384 * @note In the case where a header already exists this will result
385 *       in a reallocation and copy, @see serf_bucket_headers_setn.
386 */
387void serf_bucket_headers_setn(
388    serf_bucket_t *headers_bucket,
389    const char *header,
390    const char *value);
391
392/**
393 * Set, extended: fine grained copy control of header and value.
394 *
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.
400 *
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.
406 */
407void serf_bucket_headers_setx(
408    serf_bucket_t *headers_bucket,
409    const char *header,
410    apr_size_t header_size,
411    int header_copy,
412    const char *value,
413    apr_size_t value_size,
414    int value_copy);
415
416const char *serf_bucket_headers_get(
417    serf_bucket_t *headers_bucket,
418    const char *header);
419
420/**
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
424 */
425typedef int (serf_bucket_headers_do_callback_fn_t)(
426    void *baton,
427    const char *key,
428    const char *value);
429
430/**
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
434 * non-0 value.
435 *
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
439 */
440void serf_bucket_headers_do(
441    serf_bucket_t *headers_bucket,
442    serf_bucket_headers_do_callback_fn_t func,
443    void *baton);
444
445
446/* ==================================================================== */
447
448
449extern const serf_bucket_type_t serf_bucket_type_chunk;
450#define SERF_BUCKET_IS_CHUNK(b) SERF_BUCKET_CHECK((b), chunk)
451
452serf_bucket_t *serf_bucket_chunk_create(
453    serf_bucket_t *stream,
454    serf_bucket_alloc_t *allocator);
455
456
457/* ==================================================================== */
458
459
460extern const serf_bucket_type_t serf_bucket_type_dechunk;
461#define SERF_BUCKET_IS_DECHUNK(b) SERF_BUCKET_CHECK((b), dechunk)
462
463serf_bucket_t *serf_bucket_dechunk_create(
464    serf_bucket_t *stream,
465    serf_bucket_alloc_t *allocator);
466
467
468/* ==================================================================== */
469
470
471extern const serf_bucket_type_t serf_bucket_type_deflate;
472#define SERF_BUCKET_IS_DEFLATE(b) SERF_BUCKET_CHECK((b), deflate)
473
474#define SERF_DEFLATE_GZIP 0
475#define SERF_DEFLATE_DEFLATE 1
476
477serf_bucket_t *serf_bucket_deflate_create(
478    serf_bucket_t *stream,
479    serf_bucket_alloc_t *allocator,
480    int format);
481
482
483/* ==================================================================== */
484
485
486extern const serf_bucket_type_t serf_bucket_type_limit;
487#define SERF_BUCKET_IS_LIMIT(b) SERF_BUCKET_CHECK((b), limit)
488
489serf_bucket_t *serf_bucket_limit_create(
490    serf_bucket_t *stream,
491    apr_uint64_t limit,
492    serf_bucket_alloc_t *allocator);
493
494
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
502
503extern const serf_bucket_type_t serf_bucket_type_ssl_encrypt;
504#define SERF_BUCKET_IS_SSL_ENCRYPT(b) SERF_BUCKET_CHECK((b), ssl_encrypt)
505
506typedef struct serf_ssl_context_t serf_ssl_context_t;
507typedef struct serf_ssl_certificate_t serf_ssl_certificate_t;
508
509typedef apr_status_t (*serf_ssl_need_client_cert_t)(
510    void *data,
511    const char **cert_path);
512
513typedef apr_status_t (*serf_ssl_need_cert_password_t)(
514    void *data,
515    const char *cert_path,
516    const char **password);
517
518typedef apr_status_t (*serf_ssl_need_server_cert_t)(
519    void *data,
520    int failures,
521    const serf_ssl_certificate_t *cert);
522
523typedef apr_status_t (*serf_ssl_server_cert_chain_cb_t)(
524    void *data,
525    int failures,
526    int error_depth,
527    const serf_ssl_certificate_t * const * certs,
528    apr_size_t certs_len);
529
530void serf_ssl_client_cert_provider_set(
531    serf_ssl_context_t *context,
532    serf_ssl_need_client_cert_t callback,
533    void *data,
534    void *cache_pool);
535
536void serf_ssl_client_cert_password_set(
537    serf_ssl_context_t *context,
538    serf_ssl_need_cert_password_t callback,
539    void *data,
540    void *cache_pool);
541
542/**
543 * Set a callback to override the default SSL server certificate validation
544 * algorithm.
545 */
546void serf_ssl_server_cert_callback_set(
547    serf_ssl_context_t *context,
548    serf_ssl_need_server_cert_t callback,
549    void *data);
550
551/**
552 * Set callbacks to override the default SSL server certificate validation
553 * algorithm for the current certificate or the entire certificate chain.
554 */
555void 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,
559    void *data);
560
561/**
562 * Use the default root CA certificates as included with the OpenSSL library.
563 */
564apr_status_t serf_ssl_use_default_certificates(
565    serf_ssl_context_t *context);
566
567/**
568 * Allow SNI indicators to be sent to the server.
569 */
570apr_status_t serf_ssl_set_hostname(
571    serf_ssl_context_t *context, const char *hostname);
572
573/**
574 * Return the depth of the certificate.
575 */
576int serf_ssl_cert_depth(
577    const serf_ssl_certificate_t *cert);
578
579/**
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.
582 */
583apr_hash_t *serf_ssl_cert_issuer(
584    const serf_ssl_certificate_t *cert,
585    apr_pool_t *pool);
586
587/**
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.
590 */
591apr_hash_t *serf_ssl_cert_subject(
592    const serf_ssl_certificate_t *cert,
593    apr_pool_t *pool);
594
595/**
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.
598 */
599apr_hash_t *serf_ssl_cert_certificate(
600    const serf_ssl_certificate_t *cert,
601    apr_pool_t *pool);
602
603/**
604 * Export a certificate to base64-encoded, zero-terminated string.
605 * The returned string is allocated in @a pool. Returns NULL on failure.
606 */
607const char *serf_ssl_cert_export(
608    const serf_ssl_certificate_t *cert,
609    apr_pool_t *pool);
610
611/**
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.
615 */
616apr_status_t serf_ssl_load_cert_file(
617    serf_ssl_certificate_t **cert,
618    const char *file_path,
619    apr_pool_t *pool);
620
621/**
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.
625 */
626apr_status_t serf_ssl_trust_cert(
627    serf_ssl_context_t *ssl_ctx,
628    serf_ssl_certificate_t *cert);
629
630/**
631 * Enable or disable SSL compression on a SSL session.
632 * @a enabled = 1 to enable compression, 0 to disable compression.
633 * Default = disabled.
634 */
635apr_status_t serf_ssl_use_compression(
636    serf_ssl_context_t *ssl_ctx,
637    int enabled);
638
639serf_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);
643
644serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get(
645    serf_bucket_t *bucket);
646
647/* ==================================================================== */
648
649
650extern const serf_bucket_type_t serf_bucket_type_ssl_decrypt;
651#define SERF_BUCKET_IS_SSL_DECRYPT(b) SERF_BUCKET_CHECK((b), ssl_decrypt)
652
653serf_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);
657
658serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get(
659    serf_bucket_t *bucket);
660
661
662/* ==================================================================== */
663
664
665extern const serf_bucket_type_t serf_bucket_type_barrier;
666#define SERF_BUCKET_IS_BARRIER(b) SERF_BUCKET_CHECK((b), barrier)
667
668serf_bucket_t *serf_bucket_barrier_create(
669    serf_bucket_t *stream,
670    serf_bucket_alloc_t *allocator);
671
672
673/* ==================================================================== */
674
675extern const serf_bucket_type_t serf_bucket_type_iovec;
676#define SERF_BUCKET_IS_IOVEC(b) SERF_BUCKET_CHECK((b), iovec)
677
678serf_bucket_t *serf_bucket_iovec_create(
679    struct iovec vecs[],
680    int len,
681    serf_bucket_alloc_t *allocator);
682
683
684/* ==================================================================== */
685
686/* ### do we need a PIPE bucket type? they are simple apr_file_t objects */
687
688
689#ifdef __cplusplus
690}
691#endif
692
693#endif	/* !SERF_BUCKET_TYPES_H */
694