diff options
Diffstat (limited to 'modules/http2/h2_util.h')
| -rw-r--r-- | modules/http2/h2_util.h | 209 |
1 files changed, 152 insertions, 57 deletions
diff --git a/modules/http2/h2_util.h b/modules/http2/h2_util.h index 4ca2f9b6..7cae0ac0 100644 --- a/modules/http2/h2_util.h +++ b/modules/http2/h2_util.h @@ -16,6 +16,8 @@ #ifndef __mod_h2__h2_util__ #define __mod_h2__h2_util__ +#include <nghttp2/nghttp2.h> + /******************************************************************************* * some debugging/format helpers ******************************************************************************/ @@ -47,7 +49,7 @@ typedef int h2_ihash_iter_t(void *ctx, void *val); h2_ihash_t *h2_ihash_create(apr_pool_t *pool, size_t offset_of_int); size_t h2_ihash_count(h2_ihash_t *ih); -int h2_ihash_is_empty(h2_ihash_t *ih); +int h2_ihash_empty(h2_ihash_t *ih); void *h2_ihash_get(h2_ihash_t *ih, int id); /** @@ -56,14 +58,104 @@ void *h2_ihash_get(h2_ihash_t *ih, int id); * @param ih the hash to iterate over * @param fn the function to invoke on each member * @param ctx user supplied data passed into each iteration call - * @param 0 if one iteration returned 0, otherwise != 0 + * @return 0 if one iteration returned 0, otherwise != 0 */ 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); +size_t h2_ihash_ishift(h2_ihash_t *ih, int *buffer, size_t max); + +/******************************************************************************* + * iqueue - sorted list of int with user defined ordering + ******************************************************************************/ +typedef struct h2_iqueue { + int *elts; + int head; + int nelts; + int nalloc; + apr_pool_t *pool; +} h2_iqueue; + +/** + * Comparator for two int to determine their order. + * + * @param i1 first int to compare + * @param i2 second int to compare + * @param ctx provided user data + * @return 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 + */ +typedef int h2_iq_cmp(int i1, int i2, void *ctx); + +/** + * Allocate a new queue from the pool and initialize. + * @param id the identifier of the queue + * @param pool the memory pool + */ +h2_iqueue *h2_iq_create(apr_pool_t *pool, int capacity); + +/** + * Return != 0 iff there are no tasks in the queue. + * @param q the queue to check + */ +int h2_iq_empty(h2_iqueue *q); + +/** + * Return the number of int in the queue. + * @param q the queue to get size on + */ +int h2_iq_count(h2_iqueue *q); + +/** + * Add a stream id to the queue. + * + * @param q the queue to append the task to + * @param sid the stream id to add + * @param cmp the comparator for sorting + * @param ctx user data for comparator + */ +void h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx); + +/** + * Remove the stream id from the queue. Return != 0 iff task + * was found in queue. + * @param q the task queue + * @param sid the stream id to remove + * @return != 0 iff task was found in queue + */ +int h2_iq_remove(h2_iqueue *q, int sid); + +/** + * Remove all entries in the queue. + */ +void h2_iq_clear(h2_iqueue *q); + +/** + * Sort the stream idqueue again. Call if the task ordering + * has changed. + * + * @param q the queue to sort + * @param cmp the comparator for sorting + * @param ctx user data for the comparator + */ +void h2_iq_sort(h2_iqueue *q, h2_iq_cmp *cmp, void *ctx); + +/** + * Get the first stream id from the queue or NULL if the queue is empty. + * The task will be removed. + * + * @param q the queue to get the first task from + * @return the first stream id of the queue, 0 if empty + */ +int h2_iq_shift(h2_iqueue *q); + /******************************************************************************* * common helpers ******************************************************************************/ @@ -161,44 +253,51 @@ h2_ngheader *h2_util_ngheader_make_res(apr_pool_t *p, h2_ngheader *h2_util_ngheader_make_req(apr_pool_t *p, const struct h2_request *req); +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); + +/******************************************************************************* + * h2_request helpers + ******************************************************************************/ + +struct h2_request *h2_req_createn(int id, apr_pool_t *pool, const char *method, + const char *scheme, const char *authority, + const char *path, apr_table_t *header, + int serialize); +struct h2_request *h2_req_create(int id, apr_pool_t *pool, int serialize); + +apr_status_t h2_req_make(struct h2_request *req, apr_pool_t *pool, + const char *method, const char *scheme, + const char *authority, const char *path, + apr_table_t *headers); + /******************************************************************************* * apr brigade helpers ******************************************************************************/ + /** - * Moves data from one brigade into another. If maxlen > 0, it only - * moves up to maxlen bytes into the target brigade, making bucket splits - * if needed. - * @param to the brigade to move the data to - * @param from the brigade to get the data from - * @param maxlen of bytes to move, <= 0 for all - * @param pfile_buckets_allowed how many file buckets may be moved, - * may be 0 or NULL - * @param msg message for use in logging + * Concatenate at most length bytes from src to dest brigade, splitting + * buckets if necessary and reading buckets of indeterminate length. */ -apr_status_t h2_util_move(apr_bucket_brigade *to, apr_bucket_brigade *from, - apr_off_t maxlen, apr_size_t *pfile_buckets_allowed, - const char *msg); - +apr_status_t h2_brigade_concat_length(apr_bucket_brigade *dest, + apr_bucket_brigade *src, + apr_off_t length); + /** - * Copies buckets from one brigade into another. If maxlen > 0, it only - * copies up to maxlen bytes into the target brigade, making bucket splits - * if needed. - * @param to the brigade to copy the data to - * @param from the brigade to get the data from - * @param maxlen of bytes to copy, <= 0 for all - * @param msg message for use in logging + * Copy at most length bytes from src to dest brigade, splitting + * buckets if necessary and reading buckets of indeterminate length. */ -apr_status_t h2_util_copy(apr_bucket_brigade *to, apr_bucket_brigade *from, - apr_off_t maxlen, const char *msg); - +apr_status_t h2_brigade_copy_length(apr_bucket_brigade *dest, + apr_bucket_brigade *src, + apr_off_t length); + /** * Return != 0 iff there is a FLUSH or EOS bucket in the brigade. * @param bb the brigade to check on * @return != 0 iff brigade holds FLUSH or EOS bucket (or both) */ int h2_util_has_eos(apr_bucket_brigade *bb, apr_off_t len); -int h2_util_bb_has_data(apr_bucket_brigade *bb); -int h2_util_bb_has_data_or_eos(apr_bucket_brigade *bb); /** * Check how many bytes of the desired amount are available and if the @@ -230,43 +329,39 @@ apr_status_t h2_util_bb_readx(apr_bucket_brigade *bb, apr_off_t *plen, int *peos); /** + * Print a bucket's meta data (type and length) to the buffer. + * @return number of characters printed + */ +apr_size_t h2_util_bucket_print(char *buffer, apr_size_t bmax, + apr_bucket *b, const char *sep); + +/** + * Prints the brigade bucket types and lengths into the given buffer + * up to bmax. + * @return number of characters printed + */ +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. * @param c the connection to log for - * @param stream_id the stream identifier this brigade belongs to + * @param sid the stream identifier this brigade belongs to * @param level the log level (as in APLOG_*) * @param tag a short message text about the context * @param bb the brigade to log */ -void h2_util_bb_log(conn_rec *c, int stream_id, int level, - const char *tag, apr_bucket_brigade *bb); +#define h2_util_bb_log(c, sid, level, tag, bb) \ +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-%d): %s", \ + (c)->id, (int)(sid), (len? buffer : line)); \ +} while(0) -/** - * Transfer buckets from one brigade to another with a limit on the - * maximum amount of bytes transfered. Sets aside the buckets to - * pool p. - * @param to brigade to transfer buckets to - * @param from brigades to remove buckets from - * @param p pool that buckets should be setaside to - * @param plen maximum bytes to transfer, actual bytes transferred - * @param peos if an EOS bucket was transferred - */ -apr_status_t h2_ltransfer_brigade(apr_bucket_brigade *to, - apr_bucket_brigade *from, - apr_pool_t *p, - apr_off_t *plen, - int *peos); - -/** - * Transfer all buckets from one brigade to another. Sets aside the buckets to - * pool p. - * @param to brigade to transfer buckets to - * @param from brigades to remove buckets from - * @param p pool that buckets should be setaside to - */ -apr_status_t h2_transfer_brigade(apr_bucket_brigade *to, - apr_bucket_brigade *from, - apr_pool_t *p); /** * Transfer buckets from one brigade to another with a limit on the |
