Apache2
h2_util.h File Reference
#include <nghttp2/nghttp2.h>
#include <http_protocol.h>
#include "h2.h"
#include "h2_headers.h"
Include dependency graph for h2_util.h:

Go to the source code of this file.

Data Structures

struct  h2_iqueue
 
struct  h2_ngheader
 

Macros

#define H2_HD_MATCH_LIT(l, name, nlen)    ((nlen == sizeof(l) - 1) && !ap_cstr_casecmp(l, name))
 
#define h2_util_bb_log(c, sid, level, tag, bb)
 

Typedefs

typedef struct h2_ihash_t h2_ihash_t
 
typedef int h2_ihash_iter_t(void *ctx, void *val)
 
typedef struct h2_iqueue h2_iqueue
 
typedef int h2_iq_cmp(int i1, int i2, void *ctx)
 
typedef struct h2_fifo h2_fifo
 
typedef h2_fifo_op_t h2_fifo_peek_fn(void *head, void *ctx)
 
typedef struct h2_ififo h2_ififo
 
typedef h2_fifo_op_t h2_ififo_peek_fn(int head, void *ctx)
 
typedef struct h2_ngheader h2_ngheader
 
typedef apr_status_t h2_util_pass_cb(void *ctx, const char *data, apr_off_t len)
 
typedef int h2_bucket_gate(apr_bucket *b)
 

Enumerations

enum  h2_fifo_op_t { H2_FIFO_OP_PULL , H2_FIFO_OP_REPUSH }
 

Functions

size_t h2_util_hex_dump (char *buffer, size_t maxlen, const char *data, size_t datalen)
 
void h2_util_camel_case_header (char *s, size_t len)
 
int h2_util_frame_print (const nghttp2_frame *frame, char *buffer, size_t maxlen)
 
h2_ihash_th2_ihash_create (apr_pool_t *pool, size_t offset_of_int)
 
unsigned int h2_ihash_count (h2_ihash_t *ih)
 
int h2_ihash_empty (h2_ihash_t *ih)
 
void * h2_ihash_get (h2_ihash_t *ih, int id)
 
int h2_ihash_iter (h2_ihash_t *ih, h2_ihash_iter_t *fn, void *ctx)
 
void h2_ihash_add (h2_ihash_t *ih, void *val)
 
void h2_ihash_remove (h2_ihash_t *ih, int id)
 
void h2_ihash_remove_val (h2_ihash_t *ih, void *val)
 
void h2_ihash_clear (h2_ihash_t *ih)
 
size_t h2_ihash_shift (h2_ihash_t *ih, void **buffer, size_t max)
 
h2_iqueueh2_iq_create (apr_pool_t *pool, int capacity)
 
int h2_iq_empty (h2_iqueue *q)
 
int h2_iq_count (h2_iqueue *q)
 
int h2_iq_add (h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx)
 
int h2_iq_append (h2_iqueue *q, int sid)
 
int h2_iq_remove (h2_iqueue *q, int sid)
 
void h2_iq_clear (h2_iqueue *q)
 
void h2_iq_sort (h2_iqueue *q, h2_iq_cmp *cmp, void *ctx)
 
int h2_iq_shift (h2_iqueue *q)
 
size_t h2_iq_mshift (h2_iqueue *q, int *pint, size_t max)
 
int h2_iq_contains (h2_iqueue *q, int sid)
 
apr_status_t h2_fifo_create (h2_fifo **pfifo, apr_pool_t *pool, int capacity)
 
apr_status_t h2_fifo_set_create (h2_fifo **pfifo, apr_pool_t *pool, int capacity)
 
apr_status_t h2_fifo_term (h2_fifo *fifo)
 
int h2_fifo_count (h2_fifo *fifo)
 
apr_status_t h2_fifo_push (h2_fifo *fifo, void *elem)
 
apr_status_t h2_fifo_try_push (h2_fifo *fifo, void *elem)
 
apr_status_t h2_fifo_pull (h2_fifo *fifo, void **pelem)
 
apr_status_t h2_fifo_try_pull (h2_fifo *fifo, void **pelem)
 
apr_status_t h2_fifo_peek (h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx)
 
apr_status_t h2_fifo_try_peek (h2_fifo *fifo, h2_fifo_peek_fn *fn, void *ctx)
 
apr_status_t h2_fifo_remove (h2_fifo *fifo, void *elem)
 
apr_status_t h2_ififo_create (h2_ififo **pfifo, apr_pool_t *pool, int capacity)
 
apr_status_t h2_ififo_set_create (h2_ififo **pfifo, apr_pool_t *pool, int capacity)
 
apr_status_t h2_ififo_term (h2_ififo *fifo)
 
int h2_ififo_count (h2_ififo *fifo)
 
apr_status_t h2_ififo_push (h2_ififo *fifo, int id)
 
apr_status_t h2_ififo_try_push (h2_ififo *fifo, int id)
 
apr_status_t h2_ififo_pull (h2_ififo *fifo, int *pi)
 
apr_status_t h2_ififo_try_pull (h2_ififo *fifo, int *pi)
 
apr_status_t h2_ififo_peek (h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx)
 
apr_status_t h2_ififo_try_peek (h2_ififo *fifo, h2_ififo_peek_fn *fn, void *ctx)
 
apr_status_t h2_ififo_remove (h2_ififo *fifo, int id)
 
unsigned char h2_log2 (int n)
 
apr_size_t h2_util_table_bytes (apr_table_t *t, apr_size_t pair_extra)
 
int h2_ignore_req_trailer (const char *name, size_t len)
 
int h2_ignore_resp_trailer (const char *name, size_t len)
 
int h2_push_policy_determine (apr_table_t *headers, apr_pool_t *p, int push_enabled)
 
apr_size_t h2_util_base64url_decode (const char **decoded, const char *encoded, apr_pool_t *pool)
 
const char * h2_util_base64url_encode (const char *data, apr_size_t len, apr_pool_t *pool)
 
int h2_util_ignore_resp_header (const char *name)
 
apr_status_t h2_res_create_ngtrailer (h2_ngheader **ph, apr_pool_t *p, struct h2_headers *headers)
 
apr_status_t h2_res_create_ngheader (h2_ngheader **ph, apr_pool_t *p, struct h2_headers *headers)
 
apr_status_t h2_req_create_ngheader (h2_ngheader **ph, apr_pool_t *p, const struct h2_request *req)
 
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, size_t max_field_len, int *pwas_added)
 
apr_status_t h2_brigade_concat_length (apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length)
 
apr_status_t h2_brigade_copy_length (apr_bucket_brigade *dest, apr_bucket_brigade *src, apr_off_t length)
 
apr_size_t h2_util_bucket_print (char *buffer, apr_size_t bmax, apr_bucket *b, const char *sep)
 
apr_size_t h2_util_bb_print (char *buffer, apr_size_t bmax, const char *tag, const char *sep, apr_bucket_brigade *bb)
 
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)
 
apr_off_t h2_brigade_mem_size (apr_bucket_brigade *bb)
 
void h2_util_drain_pipe (apr_file_t *pipe)
 
apr_status_t h2_util_wait_on_pipe (apr_file_t *pipe)
 

Macro Definition Documentation

◆ H2_HD_MATCH_LIT

#define H2_HD_MATCH_LIT (   l,
  name,
  nlen 
)     ((nlen == sizeof(l) - 1) && !ap_cstr_casecmp(l, name))

Match a header value against a string constance, case insensitive

◆ h2_util_bb_log

#define h2_util_bb_log (   c,
  sid,
  level,
  tag,
  bb 
)
Value:
if (APLOG_C_IS_LEVEL(c, level)) { \
do { \
char buffer[4 * 1024]; \
const char *line = "(null)"; \
apr_size_t len, bmax = sizeof(buffer)/sizeof(buffer[0]); \
len = h2_util_bb_print(buffer, bmax, (tag), "", (bb)); \
ap_log_cerror(APLOG_MARK, level, 0, (c), "bb_dump(%ld): %s", \
((c)->master? (c)->master->id : (c)->id), (len? buffer : line)); \
} while(0); \
}
#define APLOG_MARK
Definition: http_log.h:283
#define APLOG_C_IS_LEVEL(c, level)
Definition: http_log.h:225
apr_bucket_brigade * bb
Definition: mod_dav.h:555
apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax, const char *tag, const char *sep, apr_bucket_brigade *bb)

Logs the bucket brigade (which bucket types with what length) to the log at the given level.

Parameters
cthe connection to log for
sidthe stream identifier this brigade belongs to
levelthe log level (as in APLOG_*)
taga short message text about the context
bbthe brigade to log

Typedef Documentation

◆ h2_bucket_gate

typedef int h2_bucket_gate(apr_bucket *b)

◆ h2_fifo

typedef struct h2_fifo h2_fifo

A thread-safe FIFO queue with some extra bells and whistles, if you do not need anything special, better use 'apr_queue'.

◆ h2_fifo_peek_fn

typedef h2_fifo_op_t h2_fifo_peek_fn(void *head, void *ctx)

◆ h2_ififo

typedef struct h2_ififo h2_ififo

A thread-safe FIFO queue with some extra bells and whistles, if you do not need anything special, better use 'apr_queue'.

◆ h2_ififo_peek_fn

typedef h2_fifo_op_t h2_ififo_peek_fn(int head, void *ctx)

◆ h2_ihash_iter_t

typedef int h2_ihash_iter_t(void *ctx, void *val)

◆ h2_ihash_t

typedef struct h2_ihash_t h2_ihash_t

◆ h2_iq_cmp

typedef int h2_iq_cmp(int i1, int i2, void *ctx)

Comparator for two int to determine their order.

Parameters
i1first int to compare
i2second int to compare
ctxprovided user data
Returns
value is the same as for strcmp() and has the effect: == 0: s1 and s2 are treated equal in ordering < 0: s1 should be sorted before s2 > 0: s2 should be sorted before s1

◆ h2_iqueue

typedef struct h2_iqueue h2_iqueue

◆ h2_ngheader

typedef struct h2_ngheader h2_ngheader

◆ h2_util_pass_cb

typedef apr_status_t h2_util_pass_cb(void *ctx, const char *data, apr_off_t len)

Enumeration Type Documentation

◆ h2_fifo_op_t

Enumerator
H2_FIFO_OP_PULL 
H2_FIFO_OP_REPUSH 

Function Documentation

◆ h2_append_brigade()

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 
)

Transfer buckets from one brigade to another with a limit on the maximum amount of bytes transferred. Does no setaside magic, lifetime of brigades must fit.

Parameters
tobrigade to transfer buckets to
frombrigades to remove buckets from
plenmaximum bytes to transfer, actual bytes transferred
peosif an EOS bucket was transferred

◆ h2_brigade_concat_length()

apr_status_t h2_brigade_concat_length ( apr_bucket_brigade dest,
apr_bucket_brigade src,
apr_off_t  length 
)

Concatenate at most length bytes from src to dest brigade, splitting buckets if necessary and reading buckets of indeterminate length.

◆ h2_brigade_copy_length()

apr_status_t h2_brigade_copy_length ( apr_bucket_brigade dest,
apr_bucket_brigade src,
apr_off_t  length 
)

Copy at most length bytes from src to dest brigade, splitting buckets if necessary and reading buckets of indeterminate length.

◆ h2_brigade_mem_size()

apr_off_t h2_brigade_mem_size ( apr_bucket_brigade bb)

Get an approximnation of the memory footprint of the given brigade. This varies from apr_brigade_length as

  • no buckets are ever read
  • only buckets known to allocate memory (HEAP+POOL) are counted
  • the bucket struct itself is counted

◆ h2_fifo_count()

int h2_fifo_count ( h2_fifo fifo)

◆ h2_fifo_create()

apr_status_t h2_fifo_create ( h2_fifo **  pfifo,
apr_pool_t pool,
int  capacity 
)

Create a FIFO queue that can hold up to capacity elements. Elements can appear several times.

◆ h2_fifo_peek()

apr_status_t h2_fifo_peek ( h2_fifo fifo,
h2_fifo_peek_fn fn,
void *  ctx 
)

Call given function on the head of the queue, once it exists, and perform the returned operation on it. The queue will hold its lock during this time, so no other operations on the queue are possible.

Parameters
fifothe queue to peek at
fnthe function to call on the head, once available
ctxcontext to pass in call to function

◆ h2_fifo_pull()

apr_status_t h2_fifo_pull ( h2_fifo fifo,
void **  pelem 
)

◆ h2_fifo_push()

apr_status_t h2_fifo_push ( h2_fifo fifo,
void *  elem 
)

Push en element into the queue. Blocks if there is no capacity left.

Parameters
fifothe FIFO queue
elemthe element to push
Returns
APR_SUCCESS on push, APR_EAGAIN on try_push on a full queue, APR_EEXIST when in set mode and elem already there.

◆ h2_fifo_remove()

apr_status_t h2_fifo_remove ( h2_fifo fifo,
void *  elem 
)

Remove the elem from the queue, will remove multiple appearances.

Parameters
elemthe element to remove
Returns
APR_SUCCESS iff > 0 elems were removed, APR_EAGAIN otherwise.

◆ h2_fifo_set_create()

apr_status_t h2_fifo_set_create ( h2_fifo **  pfifo,
apr_pool_t pool,
int  capacity 
)

Create a FIFO set that can hold up to capacity elements. Elements only appear once. Pushing an element already present does not change the queue and is successful.

◆ h2_fifo_term()

apr_status_t h2_fifo_term ( h2_fifo fifo)

◆ h2_fifo_try_peek()

apr_status_t h2_fifo_try_peek ( h2_fifo fifo,
h2_fifo_peek_fn fn,
void *  ctx 
)

Non-blocking version of h2_fifo_peek.

◆ h2_fifo_try_pull()

apr_status_t h2_fifo_try_pull ( h2_fifo fifo,
void **  pelem 
)

◆ h2_fifo_try_push()

apr_status_t h2_fifo_try_push ( h2_fifo fifo,
void *  elem 
)

◆ h2_ififo_count()

int h2_ififo_count ( h2_ififo fifo)

◆ h2_ififo_create()

apr_status_t h2_ififo_create ( h2_ififo **  pfifo,
apr_pool_t pool,
int  capacity 
)

Create a FIFO queue that can hold up to capacity int. ints can appear several times.

◆ h2_ififo_peek()

apr_status_t h2_ififo_peek ( h2_ififo fifo,
h2_ififo_peek_fn fn,
void *  ctx 
)

Call given function on the head of the queue, once it exists, and perform the returned operation on it. The queue will hold its lock during this time, so no other operations on the queue are possible.

Parameters
fifothe queue to peek at
fnthe function to call on the head, once available
ctxcontext to pass in call to function

◆ h2_ififo_pull()

apr_status_t h2_ififo_pull ( h2_ififo fifo,
int pi 
)

◆ h2_ififo_push()

apr_status_t h2_ififo_push ( h2_ififo fifo,
int  id 
)

Push an int into the queue. Blocks if there is no capacity left.

Parameters
fifothe FIFO queue
idthe int to push
Returns
APR_SUCCESS on push, APR_EAGAIN on try_push on a full queue, APR_EEXIST when in set mode and elem already there.

◆ h2_ififo_remove()

apr_status_t h2_ififo_remove ( h2_ififo fifo,
int  id 
)

Remove the integer from the queue, will remove multiple appearances.

Parameters
idthe integer to remove
Returns
APR_SUCCESS iff > 0 ints were removed, APR_EAGAIN otherwise.

◆ h2_ififo_set_create()

apr_status_t h2_ififo_set_create ( h2_ififo **  pfifo,
apr_pool_t pool,
int  capacity 
)

Create a FIFO set that can hold up to capacity integers. Ints only appear once. Pushing an int already present does not change the queue and is successful.

◆ h2_ififo_term()

apr_status_t h2_ififo_term ( h2_ififo fifo)

◆ h2_ififo_try_peek()

apr_status_t h2_ififo_try_peek ( h2_ififo fifo,
h2_ififo_peek_fn fn,
void *  ctx 
)

Non-blocking version of h2_fifo_peek.

◆ h2_ififo_try_pull()

apr_status_t h2_ififo_try_pull ( h2_ififo fifo,
int pi 
)

◆ h2_ififo_try_push()

apr_status_t h2_ififo_try_push ( h2_ififo fifo,
int  id 
)

◆ h2_ignore_req_trailer()

int h2_ignore_req_trailer ( const char *  name,
size_t  len 
)

◆ h2_ignore_resp_trailer()

int h2_ignore_resp_trailer ( const char *  name,
size_t  len 
)

◆ h2_ihash_add()

void h2_ihash_add ( h2_ihash_t ih,
void *  val 
)

◆ h2_ihash_clear()

void h2_ihash_clear ( h2_ihash_t ih)

◆ h2_ihash_count()

unsigned int h2_ihash_count ( h2_ihash_t ih)

◆ h2_ihash_create()

h2_ihash_t* h2_ihash_create ( apr_pool_t pool,
size_t  offset_of_int 
)

Create a hash for structures that have an identifying int member.

Parameters
poolthe pool to use
offset_of_intthe offsetof() the int member in the struct

◆ h2_ihash_empty()

int h2_ihash_empty ( h2_ihash_t ih)

◆ h2_ihash_get()

void* h2_ihash_get ( h2_ihash_t ih,
int  id 
)

◆ h2_ihash_iter()

int h2_ihash_iter ( h2_ihash_t ih,
h2_ihash_iter_t fn,
void *  ctx 
)

Iterate over the hash members (without defined order) and invoke fn for each member until 0 is returned.

Parameters
ihthe hash to iterate over
fnthe function to invoke on each member
ctxuser supplied data passed into each iteration call
Returns
0 if one iteration returned 0, otherwise != 0

◆ h2_ihash_remove()

void h2_ihash_remove ( h2_ihash_t ih,
int  id 
)

◆ h2_ihash_remove_val()

void h2_ihash_remove_val ( h2_ihash_t ih,
void *  val 
)

◆ h2_ihash_shift()

size_t h2_ihash_shift ( h2_ihash_t ih,
void **  buffer,
size_t  max 
)

◆ h2_iq_add()

int h2_iq_add ( h2_iqueue q,
int  sid,
h2_iq_cmp cmp,
void *  ctx 
)

Add a stream id to the queue.

Parameters
qthe queue to append the id to
sidthe stream id to add
cmpthe comparator for sorting
ctxuser data for comparator
Returns
!= 0 iff id was not already there

◆ h2_iq_append()

int h2_iq_append ( h2_iqueue q,
int  sid 
)

Append the id to the queue if not already present.

Parameters
qthe queue to append the id to
sidthe id to append
Returns
!= 0 iff id was not already there

◆ h2_iq_clear()

void h2_iq_clear ( h2_iqueue q)

Remove all entries in the queue.

◆ h2_iq_contains()

int h2_iq_contains ( h2_iqueue q,
int  sid 
)

Determine if int is in the queue already

Parameters
qthe queue
sidthe integer id to check for
Returns
!= 0 iff sid is already in the queue

◆ h2_iq_count()

int h2_iq_count ( h2_iqueue q)

Return the number of int in the queue.

Parameters
qthe queue to get size on

◆ h2_iq_create()

h2_iqueue* h2_iq_create ( apr_pool_t pool,
int  capacity 
)

Allocate a new queue from the pool and initialize.

Parameters
poolthe memory pool
capacitythe initial capacity of the queue

◆ h2_iq_empty()

int h2_iq_empty ( h2_iqueue q)

Return != 0 iff there are no ints in the queue.

Parameters
qthe queue to check

◆ h2_iq_mshift()

size_t h2_iq_mshift ( h2_iqueue q,
int pint,
size_t  max 
)

Get the first max ids from the queue. All these ids will be removed.

Parameters
qthe queue to get the first ids from
pintthe int array to receive the values
maxthe maximum number of ids to shift
Returns
the actual number of ids shifted

◆ h2_iq_remove()

int h2_iq_remove ( h2_iqueue q,
int  sid 
)

Remove the int from the queue. Return != 0 iff it was found.

Parameters
qthe queue
sidthe stream id to remove
Returns
!= 0 iff int was found in queue

◆ h2_iq_shift()

int h2_iq_shift ( h2_iqueue q)

Get the first id from the queue or 0 if the queue is empty. The id is being removed.

Parameters
qthe queue to get the first id from
Returns
the first id of the queue, 0 if empty

◆ h2_iq_sort()

void h2_iq_sort ( h2_iqueue q,
h2_iq_cmp cmp,
void *  ctx 
)

Sort the stream idqueue again. Call if the int ordering has changed.

Parameters
qthe queue to sort
cmpthe comparator for sorting
ctxuser data for the comparator

◆ h2_log2()

unsigned char h2_log2 ( int  n)

◆ h2_push_policy_determine()

int h2_push_policy_determine ( apr_table_t headers,
apr_pool_t p,
int  push_enabled 
)

Set the push policy for the given request. Takes request headers into account, see draft https://tools.ietf.org/html/draft-ruellan-http-accept-push-policy-00 for details.

Parameters
headersthe http headers to inspect
pthe pool to use
push_enabledif HTTP/2 server push is generally enabled for this request
Returns
the push policy desired

◆ h2_req_add_header()

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,
size_t  max_field_len,
int pwas_added 
)

Add a HTTP/2 header and return the table key if it really was added and not ignored.

◆ h2_req_create_ngheader()

apr_status_t h2_req_create_ngheader ( h2_ngheader **  ph,
apr_pool_t p,
const struct h2_request req 
)

◆ h2_res_create_ngheader()

apr_status_t h2_res_create_ngheader ( h2_ngheader **  ph,
apr_pool_t p,
struct h2_headers headers 
)

◆ h2_res_create_ngtrailer()

apr_status_t h2_res_create_ngtrailer ( h2_ngheader **  ph,
apr_pool_t p,
struct h2_headers headers 
)

◆ h2_util_base64url_decode()

apr_size_t h2_util_base64url_decode ( const char **  decoded,
const char *  encoded,
apr_pool_t pool 
)

I always wanted to write my own base64url decoder...not. See https://tools.ietf.org/html/rfc4648#section-5 for description.

◆ h2_util_base64url_encode()

const char* h2_util_base64url_encode ( const char *  data,
apr_size_t  len,
apr_pool_t pool 
)

◆ h2_util_bb_print()

apr_size_t h2_util_bb_print ( char *  buffer,
apr_size_t  bmax,
const char *  tag,
const char *  sep,
apr_bucket_brigade bb 
)

Prints the brigade bucket types and lengths into the given buffer up to bmax.

Returns
number of characters printed

◆ h2_util_bucket_print()

apr_size_t h2_util_bucket_print ( char *  buffer,
apr_size_t  bmax,
apr_bucket b,
const char *  sep 
)

Print a bucket's meta data (type and length) to the buffer.

Returns
number of characters printed

◆ h2_util_camel_case_header()

void h2_util_camel_case_header ( char *  s,
size_t  len 
)

◆ h2_util_drain_pipe()

void h2_util_drain_pipe ( apr_file_t pipe)

Drain a pipe used for notification.

◆ h2_util_frame_print()

int h2_util_frame_print ( const nghttp2_frame *  frame,
char *  buffer,
size_t  maxlen 
)

◆ h2_util_hex_dump()

size_t h2_util_hex_dump ( char *  buffer,
size_t  maxlen,
const char *  data,
size_t  datalen 
)

◆ h2_util_ignore_resp_header()

int h2_util_ignore_resp_header ( const char *  name)

◆ h2_util_table_bytes()

apr_size_t h2_util_table_bytes ( apr_table_t t,
apr_size_t  pair_extra 
)

Count the bytes that all key/value pairs in a table have in length (exlucding terminating 0s), plus additional extra per pair.

Parameters
tthe table to inspect
pair_extrathe extra amount to add per pair
Returns
the number of bytes all key/value pairs have

◆ h2_util_wait_on_pipe()

apr_status_t h2_util_wait_on_pipe ( apr_file_t pipe)

Wait on data arriving on a pipe.