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 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements. See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __mod_h2__h2_util__
18 #define __mod_h2__h2_util__
19 
20 #include <nghttp2/nghttp2.h>
21 
22 /*******************************************************************************
23  * some debugging/format helpers
24  ******************************************************************************/
25 struct h2_request;
26 struct nghttp2_frame;
27 
28 size_t h2_util_hex_dump(char *buffer, size_t maxlen,
29  const char *data, size_t datalen);
30 
31 size_t h2_util_header_print(char *buffer, size_t maxlen,
32  const char *name, size_t namelen,
33  const char *value, size_t valuelen);
34 
35 void h2_util_camel_case_header(char *s, size_t len);
36 
37 int h2_util_frame_print(const nghttp2_frame *frame, char *buffer, size_t maxlen);
38 
39 /*******************************************************************************
40  * ihash - hash for structs with int identifier
41  ******************************************************************************/
42 typedef struct h2_ihash_t h2_ihash_t;
43 typedef int h2_ihash_iter_t(void *ctx, void *val);
44 
50 h2_ihash_t *h2_ihash_create(apr_pool_t *pool, size_t offset_of_int);
51 
52 size_t h2_ihash_count(h2_ihash_t *ih);
53 int h2_ihash_empty(h2_ihash_t *ih);
54 void *h2_ihash_get(h2_ihash_t *ih, int id);
55 
64 int h2_ihash_iter(h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx);
65 
66 void h2_ihash_add(h2_ihash_t *ih, void *val);
67 void h2_ihash_remove(h2_ihash_t *ih, int id);
68 void h2_ihash_remove_val(h2_ihash_t *ih, void *val);
69 void h2_ihash_clear(h2_ihash_t *ih);
70 
71 size_t h2_ihash_shift(h2_ihash_t *ih, void **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 
125 int h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx);
126 
134 int h2_iq_append(h2_iqueue *q, int sid);
135 
143 int h2_iq_remove(h2_iqueue *q, int sid);
144 
148 void h2_iq_clear(h2_iqueue *q);
149 
158 void h2_iq_sort(h2_iqueue *q, h2_iq_cmp *cmp, void *ctx);
159 
167 int h2_iq_shift(h2_iqueue *q);
168 
177 size_t h2_iq_mshift(h2_iqueue *q, int *pint, size_t max);
178 
186 int h2_iq_contains(h2_iqueue *q, int sid);
187 
188 /*******************************************************************************
189  * FIFO queue (void* elements)
190  ******************************************************************************/
191 
196 typedef struct h2_fifo h2_fifo;
197 
202 apr_status_t h2_fifo_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity);
203 
209 apr_status_t h2_fifo_set_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity);
210 
213 
214 int h2_fifo_count(h2_fifo *fifo);
215 
224 apr_status_t h2_fifo_push(h2_fifo *fifo, void *elem);
225 apr_status_t h2_fifo_try_push(h2_fifo *fifo, void *elem);
226 
227 apr_status_t h2_fifo_pull(h2_fifo *fifo, void **pelem);
228 apr_status_t h2_fifo_try_pull(h2_fifo *fifo, void **pelem);
229 
230 typedef enum {
231  H2_FIFO_OP_PULL, /* pull the element from the queue, ie discard it */
232  H2_FIFO_OP_REPUSH, /* pull and immediatley re-push it */
233 } h2_fifo_op_t;
234 
235 typedef h2_fifo_op_t h2_fifo_peek_fn(void *head, void *ctx);
236 
245 apr_status_t h2_fifo_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx);
246 
251 
257 apr_status_t h2_fifo_remove(h2_fifo *fifo, void *elem);
258 
259 /*******************************************************************************
260  * iFIFO queue (int elements)
261  ******************************************************************************/
262 
267 typedef struct h2_ififo h2_ififo;
268 
273 apr_status_t h2_ififo_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity);
274 
280 apr_status_t h2_ififo_set_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity);
281 
284 
285 int h2_ififo_count(h2_ififo *fifo);
286 
295 apr_status_t h2_ififo_push(h2_ififo *fifo, int id);
297 
298 apr_status_t h2_ififo_pull(h2_ififo *fifo, int *pi);
299 apr_status_t h2_ififo_try_pull(h2_ififo *fifo, int *pi);
300 
301 typedef h2_fifo_op_t h2_ififo_peek_fn(int head, void *ctx);
302 
311 apr_status_t h2_ififo_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx);
312 
317 
323 apr_status_t h2_ififo_remove(h2_ififo *fifo, int id);
324 
325 /*******************************************************************************
326  * common helpers
327  ******************************************************************************/
328 /* h2_log2(n) iff n is a power of 2 */
329 unsigned char h2_log2(int n);
330 
340 
342 #define H2_HD_MATCH_LIT(l, name, nlen) \
343  ((nlen == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
344 
345 /*******************************************************************************
346  * HTTP/2 header helpers
347  ******************************************************************************/
348 int h2_req_ignore_header(const char *name, size_t len);
349 int h2_req_ignore_trailer(const char *name, size_t len);
350 int h2_res_ignore_trailer(const char *name, size_t len);
351 
362 int h2_push_policy_determine(apr_table_t *headers, apr_pool_t *p, int push_enabled);
363 
364 /*******************************************************************************
365  * base64 url encoding, different table from normal base64
366  ******************************************************************************/
371 apr_size_t h2_util_base64url_decode(const char **decoded,
372  const char *encoded,
373  apr_pool_t *pool);
374 const char *h2_util_base64url_encode(const char *data,
375  apr_size_t len, apr_pool_t *pool);
376 
377 /*******************************************************************************
378  * nghttp2 helpers
379  ******************************************************************************/
380 
381 #define H2_HD_MATCH_LIT_CS(l, name) \
382  ((strlen(name) == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
383 
384 #define H2_CREATE_NV_LIT_CS(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
385  nv->namelen = sizeof(NAME) - 1; \
386  nv->value = (uint8_t *)VALUE; \
387  nv->valuelen = strlen(VALUE)
388 
389 #define H2_CREATE_NV_CS_LIT(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
390  nv->namelen = strlen(NAME); \
391  nv->value = (uint8_t *)VALUE; \
392  nv->valuelen = sizeof(VALUE) - 1
393 
394 #define H2_CREATE_NV_CS_CS(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
395  nv->namelen = strlen(NAME); \
396  nv->value = (uint8_t *)VALUE; \
397  nv->valuelen = strlen(VALUE)
398 
399 int h2_util_ignore_header(const char *name);
400 
401 struct h2_headers;
402 
403 typedef struct h2_ngheader {
404  nghttp2_nv *nv;
406 } h2_ngheader;
407 
409  struct h2_headers *headers);
411  struct h2_headers *headers);
413  const struct h2_request *req);
414 
416  const char *name, size_t nlen,
417  const char *value, size_t vlen);
418 
419 /*******************************************************************************
420  * h2_request helpers
421  ******************************************************************************/
422 
423 struct h2_request *h2_req_create(int id, apr_pool_t *pool, const char *method,
424  const char *scheme, const char *authority,
425  const char *path, apr_table_t *header,
426  int serialize);
427 
428 /*******************************************************************************
429  * apr brigade helpers
430  ******************************************************************************/
431 
438  apr_off_t length);
439 
446  apr_off_t length);
447 
454 
463  apr_off_t *plen, int *peos);
464 
465 typedef apr_status_t h2_util_pass_cb(void *ctx,
466  const char *data, apr_off_t len);
467 
481  h2_util_pass_cb *cb, void *ctx,
482  apr_off_t *plen, int *peos);
483 
488 apr_size_t h2_util_bucket_print(char *buffer, apr_size_t bmax,
489  apr_bucket *b, const char *sep);
490 
496 apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax,
497  const char *tag, const char *sep,
508 #define h2_util_bb_log(c, sid, level, tag, bb) \
509 do { \
510  char buffer[4 * 1024]; \
511  const char *line = "(null)"; \
512  apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \
513  len = h2_util_bb_print(buffer, bmax, (tag), "", (bb)); \
514  ap_log_cerror(APLOG_MARK, level, 0, (c), "bb_dump(%ld): %s", \
515  ((c)->master? (c)->master->id : (c)->id), (len? buffer : line)); \
516 } while(0)
517 
518 
519 typedef int h2_bucket_gate(apr_bucket *b);
530  apr_bucket_brigade *from,
531  apr_off_t *plen,
532  int *peos,
533  h2_bucket_gate *should_append);
534 
543 
544 #endif /* defined(__mod_h2__h2_util__) */
apr_status_t h2_fifo_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity)
void h2_iq_clear(h2_iqueue *q)
apr_status_t h2_fifo_push(h2_fifo *fifo, void *elem)
size_t apr_size_t
Definition: apr.h:375
apr_status_t h2_ififo_try_push(h2_ififo *fifo, int id)
const char * h2_util_base64url_encode(const char *data, apr_size_t len, apr_pool_t *pool)
nghttp2_nv * nv
Definition: h2_util.h:404
apr_status_t h2_ififo_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity)
apr_status_t h2_fifo_set_create(h2_fifo **pfifo, apr_pool_t *pool, int capacity)
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)
apr_status_t h2_ififo_pull(h2_ififo *fifo, int *pi)
apr_bucket_brigade request_rec apr_pool_t * pool
Definition: mod_dav.h:552
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:133
size_t h2_ihash_count(h2_ihash_t *ih)
apr_status_t h2_fifo_try_push(h2_fifo *fifo, void *elem)
int h2_ihash_empty(h2_ihash_t *ih)
void h2_iq_sort(h2_iqueue *q, h2_iq_cmp *cmp, void *ctx)
struct h2_ififo h2_ififo
Definition: h2_util.h:267
apr_status_t h2_ififo_try_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx)
apr_status_t h2_fifo_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx)
Definition: apr_buckets.h:258
h2_fifo_op_t h2_ififo_peek_fn(int head, void *ctx)
Definition: h2_util.h:301
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:465
void h2_ihash_remove(h2_ihash_t *ih, int id)
apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p, const struct h2_request *req)
apr_status_t h2_fifo_try_peek(h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx)
apr_status_t h2_ififo_interrupt(h2_ififo *fifo)
apr_status_t h2_ififo_peek(h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx)
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)
apr_status_t h2_ififo_push(h2_ififo *fifo, int id)
int nelts
Definition: h2_util.h:79
apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p, struct h2_headers *headers)
const char * method
Definition: h2.h:134
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:552
unsigned int serialize
Definition: h2.h:142
const char * scheme
Definition: h2.h:135
int h2_iq_remove(h2_iqueue *q, int sid)
Definition: apr_buckets.h:224
apr_status_t h2_fifo_remove(h2_fifo *fifo, void *elem)
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:42
apr_status_t h2_fifo_try_pull(h2_fifo *fifo, void **pelem)
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)
int h2_fifo_count(h2_fifo *fifo)
apr_status_t h2_ififo_set_create(h2_ififo **pfifo, apr_pool_t *pool, int capacity)
apr_size_t nvlen
Definition: h2_util.h:405
Definition: h2_util.h:231
apr_status_t h2_ififo_remove(h2_ififo *fifo, int id)
const char * path
Definition: h2.h:137
apr_pool_t * p
int h2_ififo_count(h2_ififo *fifo)
Definition: h2_util.h:403
int h2_iq_shift(h2_iqueue *q)
apr_off_t h2_brigade_mem_size(apr_bucket_brigade *bb)
apr_status_t h2_ififo_term(h2_ififo *fifo)
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
Definition: h2.h:148
apr_size_t h2_util_base64url_decode(const char **decoded, const char *encoded, apr_pool_t *pool)
apr_status_t h2_fifo_interrupt(h2_fifo *fifo)
int h2_bucket_gate(apr_bucket *b)
Definition: h2_util.h:519
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:43
apr_status_t h2_ififo_try_pull(h2_ififo *fifo, int *pi)
int * elts
Definition: h2_util.h:77
struct apr_table_t apr_table_t
Definition: apr_tables.h:56
const char * name
Definition: mod_dav.h:726
int h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx)
Definition: h2_util.h:76
struct apr_pool_t apr_pool_t
Definition: apr_pools.h:60
h2_fifo_op_t h2_fifo_peek_fn(void *head, void *ctx)
Definition: h2_util.h:235
apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool, const char *name, size_t nlen, const char *value, size_t vlen)
void h2_ihash_clear(h2_ihash_t *ih)
int apr_status_t
Definition: apr_errno.h:44
const char * authority
Definition: h2.h:136
void h2_ihash_add(h2_ihash_t *ih, void *val)
h2_fifo_op_t
Definition: h2_util.h:230
apr_status_t h2_util_bb_avail(apr_bucket_brigade *bb, apr_off_t *plen, int *peos)
apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p, struct h2_headers *headers)
apr_status_t h2_fifo_term(h2_fifo *fifo)
struct h2_ngheader h2_ngheader
h2_ihash_t * h2_ihash_create(apr_pool_t *pool, size_t offset_of_int)
struct h2_fifo h2_fifo
Definition: h2_util.h:196
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)
Definition: h2_util.h:232
apr_status_t h2_fifo_pull(h2_fifo *fifo, void **pelem)
unsigned char h2_log2(int n)
int h2_iq_append(h2_iqueue *q, int sid)
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