Apache2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
h2_util.h
Go to the documentation of this file.
1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
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 __mod_h2__h2_util__
17 #define __mod_h2__h2_util__
18 
19 #include <nghttp2/nghttp2.h>
20 
21 /*******************************************************************************
22  * some debugging/format helpers
23  ******************************************************************************/
24 struct h2_request;
25 struct nghttp2_frame;
26 
27 size_t h2_util_hex_dump(char *buffer, size_t maxlen,
28  const char *data, size_t datalen);
29 
30 size_t h2_util_header_print(char *buffer, size_t maxlen,
31  const char *name, size_t namelen,
32  const char *value, size_t valuelen);
33 
34 void h2_util_camel_case_header(char *s, size_t len);
35 
36 int h2_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen);
37 
38 /*******************************************************************************
39  * ihash - hash for structs with int identifier
40  ******************************************************************************/
41 typedef struct h2_ihash_t h2_ihash_t;
42 typedef int h2_ihash_iter_t(void *ctx, void *val);
43 
49 h2_ihash_t *h2_ihash_create(apr_pool_t *pool, size_t offset_of_int);
50 
51 size_t h2_ihash_count(h2_ihash_t *ih);
52 int h2_ihash_empty(h2_ihash_t *ih);
53 void *h2_ihash_get(h2_ihash_t *ih, int id);
54 
63 int h2_ihash_iter(h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx);
64 
65 void h2_ihash_add(h2_ihash_t *ih, void *val);
66 void h2_ihash_remove(h2_ihash_t *ih, int id);
67 void h2_ihash_remove_val(h2_ihash_t *ih, void *val);
68 void h2_ihash_clear(h2_ihash_t *ih);
69 
70 size_t h2_ihash_shift(h2_ihash_t *ih, void **buffer, size_t max);
71 size_t h2_ihash_ishift(h2_ihash_t *ih, int *buffer, size_t max);
72 
73 /*******************************************************************************
74  * iqueue - sorted list of int with user defined ordering
75  ******************************************************************************/
76 typedef struct h2_iqueue {
77  int *elts;
78  int head;
79  int nelts;
80  int nalloc;
82 } h2_iqueue;
83 
95 typedef int h2_iq_cmp(int i1, int i2, void *ctx);
96 
102 h2_iqueue *h2_iq_create(apr_pool_t *pool, int capacity);
103 
108 int h2_iq_empty(h2_iqueue *q);
109 
114 int h2_iq_count(h2_iqueue *q);
115 
124 void h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx);
125 
132 void h2_iq_append(h2_iqueue *q, int sid);
133 
141 int h2_iq_remove(h2_iqueue *q, int sid);
142 
146 void h2_iq_clear(h2_iqueue *q);
147 
156 void h2_iq_sort(h2_iqueue *q, h2_iq_cmp *cmp, void *ctx);
157 
165 int h2_iq_shift(h2_iqueue *q);
166 
175 size_t h2_iq_mshift(h2_iqueue *q, int *pint, size_t max);
176 
184 int h2_iq_contains(h2_iqueue *q, int sid);
185 
186 /*******************************************************************************
187  * common helpers
188  ******************************************************************************/
189 /* h2_log2(n) iff n is a power of 2 */
190 unsigned char h2_log2(int n);
191 
201 
206 int h2_util_contains_token(apr_pool_t *pool, const char *s, const char *token);
207 
208 const char *h2_util_first_token_match(apr_pool_t *pool, const char *s,
209  const char *tokens[], apr_size_t len);
210 
212 #define H2_HD_MATCH_LIT(l, name, nlen) \
213  ((nlen == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
214 
215 /*******************************************************************************
216  * HTTP/2 header helpers
217  ******************************************************************************/
218 int h2_req_ignore_header(const char *name, size_t len);
219 int h2_req_ignore_trailer(const char *name, size_t len);
220 int h2_res_ignore_trailer(const char *name, size_t len);
221 
232 int h2_push_policy_determine(apr_table_t *headers, apr_pool_t *p, int push_enabled);
233 
234 /*******************************************************************************
235  * base64 url encoding, different table from normal base64
236  ******************************************************************************/
241 apr_size_t h2_util_base64url_decode(const char **decoded,
242  const char *encoded,
243  apr_pool_t *pool);
244 const char *h2_util_base64url_encode(const char *data,
245  apr_size_t len, apr_pool_t *pool);
246 
247 /*******************************************************************************
248  * nghttp2 helpers
249  ******************************************************************************/
250 
251 #define H2_HD_MATCH_LIT_CS(l, name) \
252  ((strlen(name) == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
253 
254 #define H2_CREATE_NV_LIT_CS(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
255  nv->namelen = sizeof(NAME) - 1; \
256  nv->value = (uint8_t *)VALUE; \
257  nv->valuelen = strlen(VALUE)
258 
259 #define H2_CREATE_NV_CS_LIT(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
260  nv->namelen = strlen(NAME); \
261  nv->value = (uint8_t *)VALUE; \
262  nv->valuelen = sizeof(VALUE) - 1
263 
264 #define H2_CREATE_NV_CS_CS(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
265  nv->namelen = strlen(NAME); \
266  nv->value = (uint8_t *)VALUE; \
267  nv->valuelen = strlen(VALUE)
268 
269 int h2_util_ignore_header(const char *name);
270 
271 typedef struct h2_ngheader {
272  nghttp2_nv *nv;
274 } h2_ngheader;
275 
278  int http_status,
279  apr_table_t *header);
281  const struct h2_request *req);
282 
284  const char *name, size_t nlen,
285  const char *value, size_t vlen);
286 
287 /*******************************************************************************
288  * h2_request helpers
289  ******************************************************************************/
290 
291 struct h2_request *h2_req_create(int id, apr_pool_t *pool, const char *method,
292  const char *scheme, const char *authority,
293  const char *path, apr_table_t *header,
294  int serialize);
295 
296 /*******************************************************************************
297  * apr brigade helpers
298  ******************************************************************************/
299 
306  apr_off_t length);
307 
314  apr_off_t length);
315 
322 
331  apr_off_t *plen, int *peos);
332 
333 typedef apr_status_t h2_util_pass_cb(void *ctx,
334  const char *data, apr_off_t len);
335 
349  h2_util_pass_cb *cb, void *ctx,
350  apr_off_t *plen, int *peos);
351 
356 apr_size_t h2_util_bucket_print(char *buffer, apr_size_t bmax,
357  apr_bucket *b, const char *sep);
358 
364 apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax,
365  const char *tag, const char *sep,
376 #define h2_util_bb_log(c, sid, level, tag, bb) \
377 do { \
378  char buffer[4 * 1024]; \
379  const char *line = "(null)"; \
380  apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \
381  len = h2_util_bb_print(buffer, bmax, (tag), "", (bb)); \
382  ap_log_cerror(APLOG_MARK, level, 0, (c), "bb_dump(%s): %s", \
383  (c)->log_id, (len? buffer : line)); \
384 } while(0)
385 
386 
387 typedef int h2_bucket_gate(apr_bucket *b);
398  apr_bucket_brigade *from,
399  apr_off_t *plen,
400  int *peos,
401  h2_bucket_gate *should_append);
402 
411 
412 #endif /* defined(__mod_h2__h2_util__) */
const char * h2_util_first_token_match(apr_pool_t *pool, const char *s, const char *tokens[], apr_size_t len)
void h2_iq_clear(h2_iqueue *q)
size_t apr_size_t
Definition: apr.h:375
const char * h2_util_base64url_encode(const char *data, apr_size_t len, apr_pool_t *pool)
nghttp2_nv * nv
Definition: h2_util.h:272
int h2_req_ignore_header(const char *name, size_t len)
apr_status_t h2_brigade_copy_length(apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length)
int h2_util_has_eos(apr_bucket_brigade *bb, apr_off_t len)
int h2_req_ignore_trailer(const char *name, size_t len)
void * h2_ihash_get(h2_ihash_t *ih, int id)
void h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx)
size_t h2_ihash_ishift(h2_ihash_t *ih, int *buffer, size_t max)
apr_bucket_brigade request_rec apr_pool_t * pool
Definition: mod_dav.h:556
size_t h2_iq_mshift(h2_iqueue *q, int *pint, size_t max)
int h2_res_ignore_trailer(const char *name, size_t len)
int h2_iq_count(h2_iqueue *q)
Definition: h2.h:118
size_t h2_ihash_count(h2_ihash_t *ih)
int h2_ihash_empty(h2_ihash_t *ih)
void h2_iq_sort(h2_iqueue *q, h2_iq_cmp *cmp, void *ctx)
Definition: apr_buckets.h:258
void h2_ihash_remove_val(h2_ihash_t *ih, void *val)
apr_status_t h2_util_pass_cb(void *ctx, const char *data, apr_off_t len)
Definition: h2_util.h:333
void h2_ihash_remove(h2_ihash_t *ih, int id)
apr_status_t h2_append_brigade(apr_bucket_brigade *to, apr_bucket_brigade *from, apr_off_t *plen, int *peos, h2_bucket_gate *should_append)
void h2_util_camel_case_header(char *s, size_t len)
apr_status_t h2_util_bb_readx(apr_bucket_brigade *bb, h2_util_pass_cb *cb, void *ctx, apr_off_t *plen, int *peos)
int nelts
Definition: h2_util.h:79
apr_status_t h2_headers_add_h1(apr_table_t *headers, apr_pool_t *pool, const char *name, size_t nlen, const char *value, size_t vlen)
const char * method
Definition: h2.h:119
apr_size_t h2_util_bucket_print(char *buffer, apr_size_t bmax, apr_bucket *b, const char *sep)
apr_bucket_brigade * bb
Definition: mod_dav.h:556
unsigned int serialize
Definition: h2.h:127
const char * scheme
Definition: h2.h:120
int h2_iq_remove(h2_iqueue *q, int sid)
Definition: apr_buckets.h:224
h2_iqueue * h2_iq_create(apr_pool_t *pool, int capacity)
dav_error * src
Definition: mod_dav.h:186
size_t h2_util_hex_dump(char *buffer, size_t maxlen, const char *data, size_t datalen)
int h2_ihash_iter(h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx)
int h2_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen)
int h2_push_policy_determine(apr_table_t *headers, apr_pool_t *p, int push_enabled)
struct h2_ihash_t h2_ihash_t
Definition: h2_util.h:41
int h2_util_ignore_header(const char *name)
apr_pool_t * pool
Definition: h2_util.h:81
int h2_iq_contains(h2_iqueue *q, int sid)
size_t h2_util_header_print(char *buffer, size_t maxlen, const char *name, size_t namelen, const char *value, size_t valuelen)
apr_size_t nvlen
Definition: h2_util.h:273
const char * path
Definition: h2.h:122
apr_pool_t * p
Definition: h2_util.h:271
int h2_iq_shift(h2_iqueue *q)
apr_off_t h2_brigade_mem_size(apr_bucket_brigade *bb)
struct h2_request * h2_req_create(int id, apr_pool_t *pool, const char *method, const char *scheme, const char *authority, const char *path, apr_table_t *header, int serialize)
int nalloc
Definition: h2_util.h:80
apr_size_t h2_util_base64url_decode(const char **decoded, const char *encoded, apr_pool_t *pool)
int h2_bucket_gate(apr_bucket *b)
Definition: h2_util.h:387
apr_status_t h2_brigade_concat_length(apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length)
struct h2_iqueue h2_iqueue
int h2_iq_cmp(int i1, int i2, void *ctx)
Definition: h2_util.h:95
int h2_ihash_iter_t(void *ctx, void *val)
Definition: h2_util.h:42
int * elts
Definition: h2_util.h:77
struct apr_table_t apr_table_t
Definition: apr_tables.h:56
h2_ngheader * h2_util_ngheader_make_res(apr_pool_t *p, int http_status, apr_table_t *header)
const char * name
Definition: mod_dav.h:730
Definition: h2_util.h:76
struct apr_pool_t apr_pool_t
Definition: apr_pools.h:60
void h2_ihash_clear(h2_ihash_t *ih)
int apr_status_t
Definition: apr_errno.h:44
const char * authority
Definition: h2.h:121
void h2_ihash_add(h2_ihash_t *ih, void *val)
apr_status_t h2_util_bb_avail(apr_bucket_brigade *bb, apr_off_t *plen, int *peos)
struct h2_ngheader h2_ngheader
h2_ihash_t * h2_ihash_create(apr_pool_t *pool, size_t offset_of_int)
apr_size_t h2_util_table_bytes(apr_table_t *t, apr_size_t pair_extra)
size_t h2_ihash_shift(h2_ihash_t *ih, void **buffer, size_t max)
unsigned char h2_log2(int n)
h2_ngheader * h2_util_ngheader_make(apr_pool_t *p, apr_table_t *header)
int h2_util_contains_token(apr_pool_t *pool, const char *s, const char *token)
off_t apr_off_t
Definition: apr.h:377
apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax, const char *tag, const char *sep, apr_bucket_brigade *bb)
int h2_iq_empty(h2_iqueue *q)
int head
Definition: h2_util.h:78
h2_ngheader * h2_util_ngheader_make_req(apr_pool_t *p, const struct h2_request *req)
void h2_iq_append(h2_iqueue *q, int sid)