summaryrefslogtreecommitdiffstats
path: root/modules/http2/h2_util.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--modules/http2/h2_util.h161
1 files changed, 68 insertions, 93 deletions
diff --git a/modules/http2/h2_util.h b/modules/http2/h2_util.h
index 1eb262d..d2e6548 100644
--- a/modules/http2/h2_util.h
+++ b/modules/http2/h2_util.h
@@ -18,6 +18,10 @@
#define __mod_h2__h2_util__
#include <nghttp2/nghttp2.h>
+#include <http_protocol.h>
+
+#include "h2.h"
+#include "h2_headers.h"
/*******************************************************************************
* some debugging/format helpers
@@ -28,10 +32,6 @@ struct nghttp2_frame;
size_t h2_util_hex_dump(char *buffer, size_t maxlen,
const char *data, size_t datalen);
-size_t h2_util_header_print(char *buffer, size_t maxlen,
- const char *name, size_t namelen,
- const char *value, size_t valuelen);
-
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);
@@ -49,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);
+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);
@@ -96,13 +96,13 @@ 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
+ * @param capacity the initial capacity of the queue
*/
h2_iqueue *h2_iq_create(apr_pool_t *pool, int capacity);
/**
- * Return != 0 iff there are no tasks in the queue.
+ * Return != 0 iff there are no ints in the queue.
* @param q the queue to check
*/
int h2_iq_empty(h2_iqueue *q);
@@ -134,11 +134,10 @@ int h2_iq_add(h2_iqueue *q, int sid, h2_iq_cmp *cmp, void *ctx);
int h2_iq_append(h2_iqueue *q, int sid);
/**
- * Remove the stream id from the queue. Return != 0 iff task
- * was found in queue.
- * @param q the task queue
+ * Remove the int from the queue. Return != 0 iff it was found.
+ * @param q the queue
* @param sid the stream id to remove
- * @return != 0 iff task was found in queue
+ * @return != 0 iff int was found in queue
*/
int h2_iq_remove(h2_iqueue *q, int sid);
@@ -148,7 +147,7 @@ int h2_iq_remove(h2_iqueue *q, int sid);
void h2_iq_clear(h2_iqueue *q);
/**
- * Sort the stream idqueue again. Call if the task ordering
+ * Sort the stream idqueue again. Call if the int ordering
* has changed.
*
* @param q the queue to sort
@@ -169,7 +168,7 @@ int h2_iq_shift(h2_iqueue *q);
/**
* Get the first max ids from the queue. All these ids will be removed.
*
- * @param q the queue to get the first task from
+ * @param q the queue to get the first ids from
* @param pint the int array to receive the values
* @param max the maximum number of ids to shift
* @return the actual number of ids shifted
@@ -179,7 +178,7 @@ size_t h2_iq_mshift(h2_iqueue *q, int *pint, size_t max);
/**
* Determine if int is in the queue already
*
- * @parm q the queue
+ * @param q the queue
* @param sid the integer id to check for
* @return != 0 iff sid is already in the queue
*/
@@ -209,7 +208,6 @@ 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);
-apr_status_t h2_fifo_interrupt(h2_fifo *fifo);
int h2_fifo_count(h2_fifo *fifo);
@@ -229,7 +227,7 @@ apr_status_t h2_fifo_try_pull(h2_fifo *fifo, void **pelem);
typedef enum {
H2_FIFO_OP_PULL, /* pull the element from the queue, ie discard it */
- H2_FIFO_OP_REPUSH, /* pull and immediatley re-push it */
+ H2_FIFO_OP_REPUSH, /* pull and immediately re-push it */
} h2_fifo_op_t;
typedef h2_fifo_op_t h2_fifo_peek_fn(void *head, void *ctx);
@@ -280,7 +278,6 @@ 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);
-apr_status_t h2_ififo_interrupt(h2_ififo *fifo);
int h2_ififo_count(h2_ififo *fifo);
@@ -345,9 +342,8 @@ apr_size_t h2_util_table_bytes(apr_table_t *t, apr_size_t pair_extra);
/*******************************************************************************
* HTTP/2 header helpers
******************************************************************************/
-int h2_req_ignore_header(const char *name, size_t len);
-int h2_req_ignore_trailer(const char *name, size_t len);
-int h2_res_ignore_trailer(const char *name, size_t len);
+int h2_ignore_req_trailer(const char *name, size_t len);
+int h2_ignore_resp_trailer(const char *name, size_t len);
/**
* Set the push policy for the given request. Takes request headers into
@@ -378,52 +374,37 @@ const char *h2_util_base64url_encode(const char *data,
* nghttp2 helpers
******************************************************************************/
-#define H2_HD_MATCH_LIT_CS(l, name) \
- ((strlen(name) == sizeof(l) - 1) && !apr_strnatcasecmp(l, name))
-
-#define H2_CREATE_NV_LIT_CS(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
- nv->namelen = sizeof(NAME) - 1; \
- nv->value = (uint8_t *)VALUE; \
- nv->valuelen = strlen(VALUE)
-
-#define H2_CREATE_NV_CS_LIT(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
- nv->namelen = strlen(NAME); \
- nv->value = (uint8_t *)VALUE; \
- nv->valuelen = sizeof(VALUE) - 1
-
-#define H2_CREATE_NV_CS_CS(nv, NAME, VALUE) nv->name = (uint8_t *)NAME; \
- nv->namelen = strlen(NAME); \
- nv->value = (uint8_t *)VALUE; \
- nv->valuelen = strlen(VALUE)
-
-int h2_util_ignore_header(const char *name);
-
-struct h2_headers;
+int h2_util_ignore_resp_header(const char *name);
typedef struct h2_ngheader {
nghttp2_nv *nv;
apr_size_t nvlen;
} h2_ngheader;
+#if AP_HAS_RESPONSE_BUCKETS
+apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p,
+ ap_bucket_headers *headers);
+apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
+ ap_bucket_response *response);
+apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
+ const struct h2_request *req);
+#else
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);
+#endif
+/**
+ * Add a HTTP/2 header and return the table key if it really was added
+ * and not ignored.
+ */
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);
-
-/*******************************************************************************
- * h2_request helpers
- ******************************************************************************/
-
-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);
+ const char *value, size_t vlen,
+ size_t max_field_len, int *pwas_added);
/*******************************************************************************
* apr brigade helpers
@@ -445,43 +426,10 @@ 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);
-
-/**
- * Check how many bytes of the desired amount are available and if the
- * end of stream is reached by that amount.
- * @param bb the brigade to check
- * @param plen the desired length and, on return, the available length
- * @param on return, if eos has been reached
- */
-apr_status_t h2_util_bb_avail(apr_bucket_brigade *bb,
- apr_off_t *plen, int *peos);
-
-typedef apr_status_t h2_util_pass_cb(void *ctx,
+typedef apr_status_t h2_util_pass_cb(void *ctx,
const char *data, apr_off_t len);
/**
- * Read at most *plen bytes from the brigade and pass them into the
- * given callback. If cb is NULL, just return the amount of data that
- * could have been read.
- * If an EOS was/would be encountered, set *peos != 0.
- * @param bb the brigade to read from
- * @param cb the callback to invoke for the read data
- * @param ctx optional data passed to callback
- * @param plen inout, as input gives the maximum number of bytes to read,
- * on return specifies the actual/would be number of bytes
- * @param peos != 0 iff an EOS bucket was/would be encountered.
- */
-apr_status_t h2_util_bb_readx(apr_bucket_brigade *bb,
- h2_util_pass_cb *cb, void *ctx,
- apr_off_t *plen, int *peos);
-
-/**
* Print a bucket's meta data (type and length) to the buffer.
* @return number of characters printed
*/
@@ -506,14 +454,16 @@ apr_size_t h2_util_bb_print(char *buffer, apr_size_t bmax,
* @param bb the brigade to log
*/
#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): %s", \
- ((c)->master? (c)->master->id : (c)->id), (len? buffer : line)); \
-} while(0)
+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); \
+}
typedef int h2_bucket_gate(apr_bucket *b);
@@ -541,4 +491,29 @@ apr_status_t h2_append_brigade(apr_bucket_brigade *to,
*/
apr_off_t h2_brigade_mem_size(apr_bucket_brigade *bb);
+/**
+ * Drain a pipe used for notification.
+ */
+void h2_util_drain_pipe(apr_file_t *pipe);
+
+/**
+ * Wait on data arriving on a pipe.
+ */
+apr_status_t h2_util_wait_on_pipe(apr_file_t *pipe);
+
+
+#if AP_HAS_RESPONSE_BUCKETS
+/**
+ * Give an estimate of the length of the header fields,
+ * without compression or other formatting decorations.
+ */
+apr_size_t headers_length_estimate(ap_bucket_headers *hdrs);
+
+/**
+ * Give an estimate of the length of the response meta data size,
+ * without compression or other formatting decorations.
+ */
+apr_size_t response_length_estimate(ap_bucket_response *resp);
+#endif /* AP_HAS_RESPONSE_BUCKETS */
+
#endif /* defined(__mod_h2__h2_util__) */