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_UTIL_H
22 #define SERF_BUCKET_UTIL_H
23 
24 /**
25  * @file serf_bucket_util.h
26  * @brief This header defines a set of functions and other utilities
27  * for implementing buckets. It is not needed by users of the bucket
28  * system.
29  */
30 
31 #include "serf.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 
38 /**
39  * Basic bucket creation function.
40  *
41  * This function will create a bucket of @a type, allocating the necessary
42  * memory from @a allocator. The @a data bucket-private information will
43  * be stored into the bucket.
44  */
45 serf_bucket_t *serf_bucket_create(
46     const serf_bucket_type_t *type,
47     serf_bucket_alloc_t *allocator,
48     void *data);
49 
50 /**
51  * Default implementation of the @see read_iovec functionality.
52  *
53  * This function will use the @see read function to get a block of memory,
54  * then return it in the iovec.
55  */
56 apr_status_t serf_default_read_iovec(
57     serf_bucket_t *bucket,
58     apr_size_t requested,
59     int vecs_size,
60     struct iovec *vecs,
61     int *vecs_used);
62 
63 /**
64  * Default implementation of the @see read_for_sendfile functionality.
65  *
66  * This function will use the @see read function to get a block of memory,
67  * then return it as a header. No file will be returned.
68  */
69 apr_status_t serf_default_read_for_sendfile(
70     serf_bucket_t *bucket,
71     apr_size_t requested,
72     apr_hdtr_t *hdtr,
73     apr_file_t **file,
74     apr_off_t *offset,
75     apr_size_t *len);
76 
77 /**
78  * Default implementation of the @see read_bucket functionality.
79  *
80  * This function will always return NULL, indicating that the @a type
81  * of bucket cannot be found within @a bucket.
82  */
83 serf_bucket_t *serf_default_read_bucket(
84     serf_bucket_t *bucket,
85     const serf_bucket_type_t *type);
86 
87 /**
88  * Default implementation of the @see destroy functionality.
89  *
90  * This function will return the @a bucket to its allcoator.
91  */
92 void serf_default_destroy(
93     serf_bucket_t *bucket);
94 
95 
96 /**
97  * Default implementation of the @see destroy functionality.
98  *
99  * This function will return the @a bucket, and the data member to its
100  * allocator.
101  */
102 void serf_default_destroy_and_data(
103     serf_bucket_t *bucket);
104 
105 
106 /**
107  * Allocate @a size bytes of memory using @a allocator.
108  *
109  * Returns NULL of the requested memory size could not be allocated.
110  */
111 void *serf_bucket_mem_alloc(
112     serf_bucket_alloc_t *allocator,
113     apr_size_t size);
114 
115 /**
116  * Allocate @a size bytes of memory using @a allocator and set all of the
117  * memory to 0.
118  *
119  * Returns NULL of the requested memory size could not be allocated.
120  */
121 void *serf_bucket_mem_calloc(
122     serf_bucket_alloc_t *allocator,
123     apr_size_t size);
124 
125 /**
126  * Free the memory at @a block, returning it to @a allocator.
127  */
128 void serf_bucket_mem_free(
129     serf_bucket_alloc_t *allocator,
130     void *block);
131 
132 
133 /**
134  * Analogous to apr_pstrmemdup, using a bucket allocator instead.
135  */
136 char *serf_bstrmemdup(
137     serf_bucket_alloc_t *allocator,
138     const char *str,
139     apr_size_t size);
140 
141 /**
142  * Analogous to apr_pmemdup, using a bucket allocator instead.
143  */
144 void * serf_bmemdup(
145     serf_bucket_alloc_t *allocator,
146     const void *mem,
147     apr_size_t size);
148 
149 /**
150  * Analogous to apr_pstrdup, using a bucket allocator instead.
151  */
152 char * serf_bstrdup(
153     serf_bucket_alloc_t *allocator,
154     const char *str);
155 
156 /**
157  * Analogous to apr_pstrcatv, using a bucket allocator instead.
158  */
159 char * serf_bstrcatv(
160     serf_bucket_alloc_t *allocator,
161     struct iovec *vec,
162     int vecs,
163     apr_size_t *bytes_written);
164 
165 /**
166  * Read data up to a newline.
167  *
168  * @a acceptable contains the allowed forms of a newline, and @a found
169  * will return the particular newline type that was found. If a newline
170  * is not found, then SERF_NEWLINE_NONE will be placed in @a found.
171  *
172  * @a data should contain a pointer to the data to be scanned. @a len
173  * should specify the length of that data buffer. On exit, @a data will
174  * be advanced past the newline, and @a len will specify the remaining
175  * amount of data in the buffer.
176  *
177  * Given this pattern of behavior, the caller should store the initial
178  * value of @a data as the line start. The difference between the
179  * returned value of @a data and the saved start is the length of the
180  * line.
181  *
182  * Note that the newline character(s) will remain within the buffer.
183  * This function scans at a byte level for the newline characters. Thus,
184  * the data buffer may contain NUL characters. As a corollary, this
185  * function only works on 8-bit character encodings.
186  *
187  * If the data is fully consumed (@a len gets set to zero) and a CR
188  * character is found at the end and the CRLF sequence is allowed, then
189  * this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The
190  * caller should take particular consideration for the CRLF sequence
191  * that may be split across data buffer boundaries.
192  */
193 void serf_util_readline(
194     const char **data,
195     apr_size_t *len,
196     int acceptable,
197     int *found);
198 
199 
200 /** The buffer size used within @see serf_databuf_t. */
201 #define SERF_DATABUF_BUFSIZE 8000
202 
203 /** Callback function which is used to refill the data buffer.
204  *
205  * The function takes @a baton, which is the @see read_baton value
206  * from the serf_databuf_t structure. Data should be placed into
207  * a buffer specified by @a buf, which is @a bufsize bytes long.
208  * The amount of data read should be returned in @a len.
209  *
210  * APR_EOF should be returned if no more data is available. APR_EAGAIN
211  * should be returned, rather than blocking. In both cases, @a buf
212  * should be filled in and @a len set, as appropriate.
213  */
214 typedef apr_status_t (*serf_databuf_reader_t)(
215     void *baton,
216     apr_size_t bufsize,
217     char *buf,
218     apr_size_t *len);
219 
220 /**
221  * This structure is used as an intermediate data buffer for some "external"
222  * source of data. It works as a scratch pad area for incoming data to be
223  * stored, and then returned as a ptr/len pair by the bucket read functions.
224  *
225  * This structure should be initialized by calling @see serf_databuf_init.
226  * Users should not bother to zero the structure beforehand.
227  */
228 typedef struct {
229     /** The current data position within the buffer. */
230     const char *current;
231 
232     /** Amount of data remaining in the buffer. */
233     apr_size_t remaining;
234 
235     /** Callback function. */
236     serf_databuf_reader_t read;
237 
238     /** A baton to hold context-specific data. */
239     void *read_baton;
240 
241     /** Records the status from the last @see read operation. */
242     apr_status_t status;
243 
244     /** Holds the data until it can be returned. */
245     char buf[SERF_DATABUF_BUFSIZE];
246 
247 } serf_databuf_t;
248 
249 /**
250  * Initialize the @see serf_databuf_t structure specified by @a databuf.
251  */
252 void serf_databuf_init(
253     serf_databuf_t *databuf);
254 
255 /**
256  * Implement a bucket-style read function from the @see serf_databuf_t
257  * structure given by @a databuf.
258  *
259  * The @a requested, @a data, and @a len fields are interpreted and used
260  * as in the read function of @see serf_bucket_t.
261  */
262 apr_status_t serf_databuf_read(
263     serf_databuf_t *databuf,
264     apr_size_t requested,
265     const char **data,
266     apr_size_t *len);
267 
268 /**
269  * Implement a bucket-style readline function from the @see serf_databuf_t
270  * structure given by @a databuf.
271  *
272  * The @a acceptable, @a found, @a data, and @a len fields are interpreted
273  * and used as in the read function of @see serf_bucket_t.
274  */
275 apr_status_t serf_databuf_readline(
276     serf_databuf_t *databuf,
277     int acceptable,
278     int *found,
279     const char **data,
280     apr_size_t *len);
281 
282 /**
283  * Implement a bucket-style peek function from the @see serf_databuf_t
284  * structure given by @a databuf.
285  *
286  * The @a data, and @a len fields are interpreted and used as in the
287  * peek function of @see serf_bucket_t.
288  */
289 apr_status_t serf_databuf_peek(
290     serf_databuf_t *databuf,
291     const char **data,
292     apr_size_t *len);
293 
294 
295 #ifdef __cplusplus
296 }
297 #endif
298 
299 #endif	/* !SERF_BUCKET_UTIL_H */
300