summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorStefan Eissing <icing@apache.org>2015-11-25 17:12:38 +0000
committerStefan Eissing <icing@apache.org>2015-11-25 17:12:38 +0000
commitc0c8b29bc6382303bc31d951ccf2ed46814e1067 (patch)
treeadf6c36f77f7e0d06eb31fa32958add68282ae3c /modules
parentde648ac7749fe94c38cb85088feb069a11c48e3c (diff)
downloadhttpd-c0c8b29bc6382303bc31d951ccf2ed46814e1067.tar.gz
merged mod_http2 1.0.8 from trunk
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1716493 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/http2/h2_alt_svc.c2
-rw-r--r--modules/http2/h2_config.c121
-rw-r--r--modules/http2/h2_config.h19
-rw-r--r--modules/http2/h2_conn.c13
-rw-r--r--modules/http2/h2_conn.h5
-rw-r--r--modules/http2/h2_conn_io.c6
-rw-r--r--modules/http2/h2_conn_io.h6
-rw-r--r--modules/http2/h2_ctx.h12
-rw-r--r--modules/http2/h2_h2.c8
-rw-r--r--modules/http2/h2_mplx.c5
-rw-r--r--modules/http2/h2_mplx.h1
-rw-r--r--modules/http2/h2_push.c12
-rw-r--r--modules/http2/h2_push.h2
-rw-r--r--modules/http2/h2_request.c10
-rw-r--r--modules/http2/h2_request.h7
-rw-r--r--modules/http2/h2_session.c110
-rw-r--r--modules/http2/h2_session.h7
-rw-r--r--modules/http2/h2_stream.c20
-rw-r--r--modules/http2/h2_stream.h11
-rw-r--r--modules/http2/h2_switch.c2
-rw-r--r--modules/http2/h2_task.c13
-rw-r--r--modules/http2/h2_task.h3
-rw-r--r--modules/http2/h2_version.h4
23 files changed, 260 insertions, 139 deletions
diff --git a/modules/http2/h2_alt_svc.c b/modules/http2/h2_alt_svc.c
index d18ae5f20d..6bc3cd0dff 100644
--- a/modules/http2/h2_alt_svc.c
+++ b/modules/http2/h2_alt_svc.c
@@ -74,7 +74,7 @@ h2_alt_svc *h2_alt_svc_parse(const char *s, apr_pool_t *pool) {
static int h2_alt_svc_handler(request_rec *r)
{
h2_ctx *ctx;
- h2_config *cfg;
+ const h2_config *cfg;
int i;
if (r->connection->keepalives > 0) {
diff --git a/modules/http2/h2_config.c b/modules/http2/h2_config.c
index 7dc0b20d20..11f9b0a609 100644
--- a/modules/http2/h2_config.c
+++ b/modules/http2/h2_config.c
@@ -15,6 +15,9 @@
#include <assert.h>
+#include <apr_hash.h>
+#include <apr_lib.h>
+
#include <httpd.h>
#include <http_core.h>
#include <http_config.h>
@@ -43,7 +46,7 @@ static h2_config defconf = {
H2_INITIAL_WINDOW_SIZE, /* window_size */
-1, /* min workers */
-1, /* max workers */
- 10, /* max workers idle secs */
+ 10 * 60, /* max workers idle secs */
64 * 1024, /* stream max mem size */
NULL, /* no alt-svcs */
-1, /* alt-svc max age */
@@ -55,6 +58,7 @@ static h2_config defconf = {
1024*1024, /* TLS warmup size */
1, /* TLS cooldown secs */
1, /* HTTP/2 server push enabled */
+ NULL, /* map of content-type to priorities */
};
static int files_per_session = 0;
@@ -111,6 +115,7 @@ static void *h2_config_create(apr_pool_t *pool,
conf->tls_warmup_size = DEF_VAL;
conf->tls_cooldown_secs = DEF_VAL;
conf->h2_push = DEF_VAL;
+ conf->priorities = NULL;
return conf;
}
@@ -155,16 +160,22 @@ void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv)
n->tls_warmup_size = H2_CONFIG_GET(add, base, tls_warmup_size);
n->tls_cooldown_secs = H2_CONFIG_GET(add, base, tls_cooldown_secs);
n->h2_push = H2_CONFIG_GET(add, base, h2_push);
+ if (add->priorities && base->priorities) {
+ n->priorities = apr_hash_overlay(pool, add->priorities, base->priorities);
+ }
+ else {
+ n->priorities = add->priorities? add->priorities : base->priorities;
+ }
return n;
}
-int h2_config_geti(h2_config *conf, h2_config_var_t var)
+int h2_config_geti(const h2_config *conf, h2_config_var_t var)
{
return (int)h2_config_geti64(conf, var);
}
-apr_int64_t h2_config_geti64(h2_config *conf, h2_config_var_t var)
+apr_int64_t h2_config_geti64(const h2_config *conf, h2_config_var_t var)
{
int n;
switch(var) {
@@ -207,7 +218,7 @@ apr_int64_t h2_config_geti64(h2_config *conf, h2_config_var_t var)
}
}
-h2_config *h2_config_sget(server_rec *s)
+const h2_config *h2_config_sget(server_rec *s)
{
h2_config *cfg = (h2_config *)ap_get_module_config(s->module_config,
&http2_module);
@@ -215,11 +226,21 @@ h2_config *h2_config_sget(server_rec *s)
return cfg;
}
+const struct h2_priority *h2_config_get_priority(const h2_config *conf,
+ const char *content_type)
+{
+ if (content_type && conf->priorities) {
+ size_t len = strcspn(content_type, "; \t");
+ h2_priority *prio = apr_hash_get(conf->priorities, content_type, len);
+ return prio? prio : apr_hash_get(conf->priorities, "*", 1);
+ }
+ return NULL;
+}
static const char *h2_conf_set_max_streams(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->h2_max_streams = (int)apr_atoi64(value);
(void)arg;
if (cfg->h2_max_streams < 1) {
@@ -231,7 +252,7 @@ static const char *h2_conf_set_max_streams(cmd_parms *parms,
static const char *h2_conf_set_window_size(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->h2_window_size = (int)apr_atoi64(value);
(void)arg;
if (cfg->h2_window_size < 1024) {
@@ -243,7 +264,7 @@ static const char *h2_conf_set_window_size(cmd_parms *parms,
static const char *h2_conf_set_min_workers(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->min_workers = (int)apr_atoi64(value);
(void)arg;
if (cfg->min_workers < 1) {
@@ -255,7 +276,7 @@ static const char *h2_conf_set_min_workers(cmd_parms *parms,
static const char *h2_conf_set_max_workers(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->max_workers = (int)apr_atoi64(value);
(void)arg;
if (cfg->max_workers < 1) {
@@ -267,7 +288,7 @@ static const char *h2_conf_set_max_workers(cmd_parms *parms,
static const char *h2_conf_set_max_worker_idle_secs(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->max_worker_idle_secs = (int)apr_atoi64(value);
(void)arg;
if (cfg->max_worker_idle_secs < 1) {
@@ -279,7 +300,7 @@ static const char *h2_conf_set_max_worker_idle_secs(cmd_parms *parms,
static const char *h2_conf_set_stream_max_mem_size(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->stream_max_mem_size = (int)apr_atoi64(value);
@@ -294,7 +315,7 @@ static const char *h2_add_alt_svc(cmd_parms *parms,
void *arg, const char *value)
{
if (value && strlen(value)) {
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
h2_alt_svc *as = h2_alt_svc_parse(value, parms->pool);
if (!as) {
return "unable to parse alt-svc specifier";
@@ -311,7 +332,7 @@ static const char *h2_add_alt_svc(cmd_parms *parms,
static const char *h2_conf_set_alt_svc_max_age(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->alt_svc_max_age = (int)apr_atoi64(value);
(void)arg;
return NULL;
@@ -320,7 +341,7 @@ static const char *h2_conf_set_alt_svc_max_age(cmd_parms *parms,
static const char *h2_conf_set_session_extra_files(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
apr_int64_t max = (int)apr_atoi64(value);
if (max < 0) {
return "value must be a non-negative number";
@@ -333,7 +354,7 @@ static const char *h2_conf_set_session_extra_files(cmd_parms *parms,
static const char *h2_conf_set_serialize_headers(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
if (!strcasecmp(value, "On")) {
cfg->serialize_headers = 1;
return NULL;
@@ -350,7 +371,7 @@ static const char *h2_conf_set_serialize_headers(cmd_parms *parms,
static const char *h2_conf_set_direct(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
if (!strcasecmp(value, "On")) {
cfg->h2_direct = 1;
return NULL;
@@ -367,7 +388,7 @@ static const char *h2_conf_set_direct(cmd_parms *parms,
static const char *h2_conf_set_push(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
if (!strcasecmp(value, "On")) {
cfg->h2_push = 1;
return NULL;
@@ -381,10 +402,64 @@ static const char *h2_conf_set_push(cmd_parms *parms,
return "value must be On or Off";
}
+static const char *h2_conf_add_push_priority(cmd_parms *cmd, void *_cfg,
+ const char *ctype, const char *sdependency,
+ const char *sweight)
+{
+ h2_config *cfg = (h2_config *)h2_config_sget(cmd->server);
+ const char *sdefweight = "16"; /* default AFTER weight */
+ h2_dependency dependency;
+ h2_priority *priority;
+ int weight;
+
+ if (!strlen(ctype)) {
+ return "1st argument must be a mime-type, like 'text/css' or '*'";
+ }
+
+ if (!sweight) {
+ /* 2 args only, but which one? */
+ if (apr_isdigit(sdependency[0])) {
+ sweight = sdependency;
+ sdependency = "AFTER"; /* default dependency */
+ }
+ }
+
+ if (!strcasecmp("AFTER", sdependency)) {
+ dependency = H2_DEPENDANT_AFTER;
+ }
+ else if (!strcasecmp("BEFORE", sdependency)) {
+ dependency = H2_DEPENDANT_BEFORE;
+ sdefweight = "256"; /* default BEFORE weight */
+ }
+ else if (!strcasecmp("INTERLEAVED", sdependency)) {
+ dependency = H2_DEPENDANT_INTERLEAVED;
+ sdefweight = "256"; /* default INTERLEAVED weight */
+ }
+ else {
+ return "dependency must be one of 'After', 'Before' or 'Interleaved'";
+ }
+
+ weight = (int)apr_atoi64(sweight? sweight : sdefweight);
+ if (weight < NGHTTP2_MIN_WEIGHT) {
+ return apr_psprintf(cmd->pool, "weight must be a number >= %d",
+ NGHTTP2_MIN_WEIGHT);
+ }
+
+ priority = apr_pcalloc(cmd->pool, sizeof(*priority));
+ priority->dependency = dependency;
+ priority->weight = weight;
+
+ if (!cfg->priorities) {
+ cfg->priorities = apr_hash_make(cmd->pool);
+ }
+ apr_hash_set(cfg->priorities, ctype, strlen(ctype), priority);
+ return NULL;
+}
+
static const char *h2_conf_set_modern_tls_only(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
if (!strcasecmp(value, "On")) {
cfg->modern_tls_only = 1;
return NULL;
@@ -401,7 +476,7 @@ static const char *h2_conf_set_modern_tls_only(cmd_parms *parms,
static const char *h2_conf_set_upgrade(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
if (!strcasecmp(value, "On")) {
cfg->h2_upgrade = 1;
return NULL;
@@ -418,7 +493,7 @@ static const char *h2_conf_set_upgrade(cmd_parms *parms,
static const char *h2_conf_set_tls_warmup_size(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->tls_warmup_size = apr_atoi64(value);
(void)arg;
return NULL;
@@ -427,7 +502,7 @@ static const char *h2_conf_set_tls_warmup_size(cmd_parms *parms,
static const char *h2_conf_set_tls_cooldown_secs(cmd_parms *parms,
void *arg, const char *value)
{
- h2_config *cfg = h2_config_sget(parms->server);
+ h2_config *cfg = (h2_config *)h2_config_sget(parms->server);
cfg->tls_cooldown_secs = (int)apr_atoi64(value);
(void)arg;
return NULL;
@@ -469,18 +544,20 @@ const command_rec h2_cmds[] = {
RSRC_CONF, "seconds of idle time on TLS before shrinking writes"),
AP_INIT_TAKE1("H2Push", h2_conf_set_push, NULL,
RSRC_CONF, "off to disable HTTP/2 server push"),
+ AP_INIT_TAKE23("H2PushPriority", h2_conf_add_push_priority, NULL,
+ RSRC_CONF, "define priority of PUSHed resources per content type"),
AP_END_CMD
};
-h2_config *h2_config_rget(request_rec *r)
+const h2_config *h2_config_rget(request_rec *r)
{
h2_config *cfg = (h2_config *)ap_get_module_config(r->per_dir_config,
&http2_module);
return cfg? cfg : h2_config_sget(r->server);
}
-h2_config *h2_config_get(conn_rec *c)
+const h2_config *h2_config_get(conn_rec *c)
{
h2_ctx *ctx = h2_ctx_get(c);
diff --git a/modules/http2/h2_config.h b/modules/http2/h2_config.h
index 7d2ed0fa28..3d85ec247d 100644
--- a/modules/http2/h2_config.h
+++ b/modules/http2/h2_config.h
@@ -41,6 +41,9 @@ typedef enum {
H2_CONF_PUSH,
} h2_config_var_t;
+struct apr_hash_t;
+struct h2_priority;
+
/* Apache httpd module configuration for h2. */
typedef struct h2_config {
const char *name;
@@ -61,6 +64,7 @@ typedef struct h2_config {
apr_int64_t tls_warmup_size; /* Amount of TLS data to send before going full write size */
int tls_cooldown_secs; /* Seconds of idle time before going back to small TLS records */
int h2_push; /* if HTTP/2 server push is enabled */
+ struct apr_hash_t *priorities;/* map of content-type to h2_priority records */
} h2_config;
@@ -68,18 +72,21 @@ void *h2_config_create_dir(apr_pool_t *pool, char *x);
void *h2_config_create_svr(apr_pool_t *pool, server_rec *s);
void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv);
-apr_status_t h2_config_apply_header(h2_config *config, request_rec *r);
+apr_status_t h2_config_apply_header(const h2_config *config, request_rec *r);
extern const command_rec h2_cmds[];
-h2_config *h2_config_get(conn_rec *c);
-h2_config *h2_config_sget(server_rec *s);
-h2_config *h2_config_rget(request_rec *r);
+const h2_config *h2_config_get(conn_rec *c);
+const h2_config *h2_config_sget(server_rec *s);
+const h2_config *h2_config_rget(request_rec *r);
-int h2_config_geti(h2_config *conf, h2_config_var_t var);
-apr_int64_t h2_config_geti64(h2_config *conf, h2_config_var_t var);
+int h2_config_geti(const h2_config *conf, h2_config_var_t var);
+apr_int64_t h2_config_geti64(const h2_config *conf, h2_config_var_t var);
void h2_config_init(apr_pool_t *pool);
+const struct h2_priority *h2_config_get_priority(const h2_config *conf,
+ const char *content_type);
+
#endif /* __mod_h2__h2_config_h__ */
diff --git a/modules/http2/h2_conn.c b/modules/http2/h2_conn.c
index 6fec75ea9a..cf44fd7c1f 100644
--- a/modules/http2/h2_conn.c
+++ b/modules/http2/h2_conn.c
@@ -69,7 +69,7 @@ static void check_modules(void)
apr_status_t h2_conn_child_init(apr_pool_t *pool, server_rec *s)
{
- h2_config *config = h2_config_sget(s);
+ const h2_config *config = h2_config_sget(s);
apr_status_t status = APR_SUCCESS;
int minw = h2_config_geti(config, H2_CONF_MIN_WORKERS);
int maxw = h2_config_geti(config, H2_CONF_MAX_WORKERS);
@@ -131,11 +131,11 @@ static module *h2_conn_mpm_module(void) {
return mpm_module;
}
-apr_status_t h2_conn_process(conn_rec *c, request_rec *r)
+apr_status_t h2_conn_process(conn_rec *c, request_rec *r, server_rec *s)
{
apr_status_t status;
h2_session *session;
- h2_config *config;
+ const h2_config *config;
int rv;
if (!workers) {
@@ -146,12 +146,15 @@ apr_status_t h2_conn_process(conn_rec *c, request_rec *r)
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "h2_conn_process start");
+ if (!s && r) {
+ s = r->server;
+ }
+
+ config = s? h2_config_sget(s) : h2_config_get(c);
if (r) {
- config = h2_config_rget(r);
session = h2_session_rcreate(r, config, workers);
}
else {
- config = h2_config_get(c);
session = h2_session_create(c, config, workers);
}
diff --git a/modules/http2/h2_conn.h b/modules/http2/h2_conn.h
index 84cf8d83c4..917a57e039 100644
--- a/modules/http2/h2_conn.h
+++ b/modules/http2/h2_conn.h
@@ -24,9 +24,10 @@ struct h2_task;
* and the connection will close.
*
* @param c the connection HTTP/2 is starting on
- * @param r the upgrad requestion that still awaits an answer, optional
+ * @param r the upgrade request that still awaits an answer, optional
+ * @param s the server selected by request or, if NULL, connection
*/
-apr_status_t h2_conn_process(conn_rec *c, request_rec *r);
+apr_status_t h2_conn_process(conn_rec *c, request_rec *r, server_rec *s);
/* Initialize this child process for h2 connection work,
* to be called once during child init before multi processing
diff --git a/modules/http2/h2_conn_io.c b/modules/http2/h2_conn_io.c
index 485a8bd47e..a67d025fa8 100644
--- a/modules/http2/h2_conn_io.c
+++ b/modules/http2/h2_conn_io.c
@@ -45,10 +45,10 @@
#define WRITE_BUFFER_SIZE (8*WRITE_SIZE_MAX)
-apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, apr_pool_t *pool)
+apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c,
+ const h2_config *cfg,
+ apr_pool_t *pool)
{
- h2_config *cfg = h2_config_get(c);
-
io->connection = c;
io->input = apr_brigade_create(pool, c->bucket_alloc);
io->output = apr_brigade_create(pool, c->bucket_alloc);
diff --git a/modules/http2/h2_conn_io.h b/modules/http2/h2_conn_io.h
index a0dd0d0e5c..f051c6c3d9 100644
--- a/modules/http2/h2_conn_io.h
+++ b/modules/http2/h2_conn_io.h
@@ -16,6 +16,8 @@
#ifndef __mod_h2__h2_conn_io__
#define __mod_h2__h2_conn_io__
+struct h2_config;
+
/* h2_io is the basic handler of a httpd connection. It keeps two brigades,
* one for input, one for output and works with the installed connection
* filters.
@@ -42,7 +44,9 @@ typedef struct {
int unflushed;
} h2_conn_io;
-apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c, apr_pool_t *pool);
+apr_status_t h2_conn_io_init(h2_conn_io *io, conn_rec *c,
+ const struct h2_config *cfg,
+ apr_pool_t *pool);
int h2_conn_io_is_buffered(h2_conn_io *io);
diff --git a/modules/http2/h2_ctx.h b/modules/http2/h2_ctx.h
index e4bc7506ae..7f8f2b5949 100644
--- a/modules/http2/h2_ctx.h
+++ b/modules/http2/h2_ctx.h
@@ -28,12 +28,12 @@ struct h2_config;
* - those created by ourself to perform work on HTTP/2 streams
*/
typedef struct h2_ctx {
- int is_h2; /* h2 engine is used */
- const char *protocol; /* the protocol negotiated */
- struct h2_task *task; /* the h2_task executing or NULL */
- const char *hostname; /* hostname negotiated via SNI, optional */
- server_rec *server; /* httpd server config selected. */
- struct h2_config *config; /* effective config in this context */
+ int is_h2; /* h2 engine is used */
+ const char *protocol; /* the protocol negotiated */
+ struct h2_task *task; /* the h2_task executing or NULL */
+ const char *hostname; /* hostname negotiated via SNI, optional */
+ server_rec *server; /* httpd server config selected. */
+ const struct h2_config *config; /* effective config in this context */
} h2_ctx;
h2_ctx *h2_ctx_get(const conn_rec *c);
diff --git a/modules/http2/h2_h2.c b/modules/http2/h2_h2.c
index e48e64e8a4..3b62dbf1c8 100644
--- a/modules/http2/h2_h2.c
+++ b/modules/http2/h2_h2.c
@@ -469,7 +469,7 @@ int h2_h2_is_tls(conn_rec *c)
int h2_is_acceptable_connection(conn_rec *c, int require_all)
{
int is_tls = h2_h2_is_tls(c);
- h2_config *cfg = h2_config_get(c);
+ const h2_config *cfg = h2_config_get(c);
if (is_tls && h2_config_geti(cfg, H2_CONF_MODERN_TLS_ONLY) > 0) {
/* Check TLS connection for modern TLS parameters, as defined in
@@ -526,7 +526,7 @@ int h2_is_acceptable_connection(conn_rec *c, int require_all)
int h2_allows_h2_direct(conn_rec *c)
{
- h2_config *cfg = h2_config_get(c);
+ const h2_config *cfg = h2_config_get(c);
int h2_direct = h2_config_geti(cfg, H2_CONF_DIRECT);
if (h2_direct < 0) {
@@ -544,7 +544,7 @@ int h2_allows_h2_direct(conn_rec *c)
int h2_allows_h2_upgrade(conn_rec *c)
{
- h2_config *cfg = h2_config_get(c);
+ const h2_config *cfg = h2_config_get(c);
int h2_upgrade = h2_config_geti(cfg, H2_CONF_UPGRADE);
return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(c));
@@ -651,7 +651,7 @@ int h2_h2_process_conn(conn_rec* c)
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
"h2_h2, connection, h2 active");
- return h2_conn_process(c, NULL);
+ return h2_conn_process(c, NULL, ctx->server);
}
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
diff --git a/modules/http2/h2_mplx.c b/modules/http2/h2_mplx.c
index 6f2a512465..c4efed6276 100644
--- a/modules/http2/h2_mplx.c
+++ b/modules/http2/h2_mplx.c
@@ -102,10 +102,11 @@ static void h2_mplx_destroy(h2_mplx *m)
* their HTTP/1 cousins, the separate allocator seems to work better
* than protecting a shared h2_session one with an own lock.
*/
-h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent, h2_workers *workers)
+h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *parent,
+ const h2_config *conf,
+ h2_workers *workers)
{
apr_status_t status = APR_SUCCESS;
- h2_config *conf = h2_config_get(c);
apr_allocator_t *allocator = NULL;
h2_mplx *m;
AP_DEBUG_ASSERT(conf);
diff --git a/modules/http2/h2_mplx.h b/modules/http2/h2_mplx.h
index c570e91fd4..f145428ff3 100644
--- a/modules/http2/h2_mplx.h
+++ b/modules/http2/h2_mplx.h
@@ -88,6 +88,7 @@ struct h2_mplx {
* Implicitly has reference count 1.
*/
h2_mplx *h2_mplx_create(conn_rec *c, apr_pool_t *master,
+ const struct h2_config *conf,
struct h2_workers *workers);
/**
diff --git a/modules/http2/h2_push.c b/modules/http2/h2_push.c
index 65b2b7b625..b80ffb9081 100644
--- a/modules/http2/h2_push.c
+++ b/modules/http2/h2_push.c
@@ -282,7 +282,6 @@ static int add_push(link_ctx *ctx)
path = apr_uri_unparse(ctx->pool, &uri, APR_URI_UNP_OMITSITEPART);
push = apr_pcalloc(ctx->pool, sizeof(*push));
- push->initiating_id = ctx->req->id;
headers = apr_table_make(ctx->pool, 5);
apr_table_do(set_header, headers, ctx->req->headers,
@@ -290,20 +289,13 @@ static int add_push(link_ctx *ctx)
"Cache-Control",
"Accept-Language",
NULL);
- /* TODO: which headers do we add here?
- */
-
- req = h2_request_createn(0, ctx->pool,
- ctx->req->method,
- ctx->req->scheme,
+ req = h2_request_createn(0, ctx->pool, ctx->req->config,
+ "GET", ctx->req->scheme,
ctx->req->authority,
path, headers);
h2_request_end_headers(req, ctx->pool, 1);
push->req = req;
- push->prio.dependency = H2_DEPENDANT_AFTER;
- push->prio.weight = NGHTTP2_DEFAULT_WEIGHT;
-
if (!ctx->pushes) {
ctx->pushes = apr_array_make(ctx->pool, 5, sizeof(h2_push*));
}
diff --git a/modules/http2/h2_push.h b/modules/http2/h2_push.h
index b98a2f73e1..871548cee3 100644
--- a/modules/http2/h2_push.h
+++ b/modules/http2/h2_push.h
@@ -20,9 +20,7 @@ struct h2_response;
struct h2_ngheader;
typedef struct h2_push {
- int initiating_id;
const struct h2_request *req;
- h2_priority prio;
} h2_push;
diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c
index e1a371f6a4..bce58593c1 100644
--- a/modules/http2/h2_request.c
+++ b/modules/http2/h2_request.c
@@ -30,18 +30,22 @@
#include <scoreboard.h>
#include "h2_private.h"
+#include "h2_config.h"
#include "h2_mplx.h"
#include "h2_request.h"
#include "h2_task.h"
#include "h2_util.h"
-h2_request *h2_request_create(int id, apr_pool_t *pool)
+h2_request *h2_request_create(int id, apr_pool_t *pool,
+ const struct h2_config *config)
{
- return h2_request_createn(id, pool, NULL, NULL, NULL, NULL, NULL);
+ return h2_request_createn(id, pool, config,
+ NULL, NULL, NULL, NULL, NULL);
}
h2_request *h2_request_createn(int id, apr_pool_t *pool,
+ const struct h2_config *config,
const char *method, const char *scheme,
const char *authority, const char *path,
apr_table_t *header)
@@ -49,6 +53,7 @@ h2_request *h2_request_createn(int id, apr_pool_t *pool,
h2_request *req = apr_pcalloc(pool, sizeof(h2_request));
req->id = id;
+ req->config = config;
req->method = method;
req->scheme = scheme;
req->authority = authority;
@@ -137,6 +142,7 @@ apr_status_t h2_request_rwrite(h2_request *req, request_rec *r)
{
apr_status_t status;
+ req->config = h2_config_rget(r);
req->method = r->method;
req->scheme = (r->parsed_uri.scheme? r->parsed_uri.scheme
: ap_http_scheme(r));
diff --git a/modules/http2/h2_request.h b/modules/http2/h2_request.h
index 69d24f38a2..9e74492cd9 100644
--- a/modules/http2/h2_request.h
+++ b/modules/http2/h2_request.h
@@ -20,6 +20,7 @@
* format that will be fed to various httpd input filters to finally
* become a request_rec to be handled by soemone.
*/
+struct h2_config;
struct h2_to_h1;
struct h2_mplx;
struct h2_task;
@@ -42,11 +43,15 @@ struct h2_request {
apr_off_t content_length;
int chunked;
int eoh;
+
+ const struct h2_config *config;
};
-h2_request *h2_request_create(int id, apr_pool_t *pool);
+h2_request *h2_request_create(int id, apr_pool_t *pool,
+ const struct h2_config *config);
h2_request *h2_request_createn(int id, apr_pool_t *pool,
+ const struct h2_config *config,
const char *method, const char *scheme,
const char *authority, const char *path,
apr_table_t *headers);
diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c
index 91a3d9465c..ca1d87824d 100644
--- a/modules/http2/h2_session.c
+++ b/modules/http2/h2_session.c
@@ -550,6 +550,22 @@ static int on_send_data_cb(nghttp2_session *ngh2,
return h2_session_status_from_apr_status(status);
}
+static int on_frame_send_cb(nghttp2_session *ngh2,
+ const nghttp2_frame *frame,
+ void *user_data)
+{
+ h2_session *session = user_data;
+ if (APLOGctrace1(session->c)) {
+ char buffer[256];
+
+ frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c,
+ "h2_session(%ld): frame_send %s",
+ session->id, buffer);
+ }
+ return 0;
+}
+
#define NGH2_SET_CALLBACK(callbacks, name, fn)\
nghttp2_session_callbacks_set_##name##_callback(callbacks, fn)
@@ -571,7 +587,8 @@ static apr_status_t init_callbacks(conn_rec *c, nghttp2_session_callbacks **pcb)
NGH2_SET_CALLBACK(*pcb, on_begin_headers, on_begin_headers_cb);
NGH2_SET_CALLBACK(*pcb, on_header, on_header_cb);
NGH2_SET_CALLBACK(*pcb, send_data, on_send_data_cb);
-
+ NGH2_SET_CALLBACK(*pcb, on_frame_send, on_frame_send_cb);
+
return APR_SUCCESS;
}
@@ -625,7 +642,7 @@ static void *session_realloc(void *p, size_t size, void *ctx)
static h2_session *h2_session_create_int(conn_rec *c,
request_rec *r,
- h2_config *config,
+ const h2_config *config,
h2_workers *workers)
{
nghttp2_session_callbacks *callbacks = NULL;
@@ -646,6 +663,7 @@ static h2_session *h2_session_create_int(conn_rec *c,
session->id = c->id;
session->c = c;
session->r = r;
+ session->config = config;
session->pool = pool;
apr_pool_pre_cleanup_register(pool, session, session_pool_cleanup);
@@ -661,9 +679,9 @@ static h2_session *h2_session_create_int(conn_rec *c,
session->streams = h2_stream_set_create(session->pool, session->max_stream_count);
session->workers = workers;
- session->mplx = h2_mplx_create(c, session->pool, workers);
+ session->mplx = h2_mplx_create(c, session->pool, config, workers);
- h2_conn_io_init(&session->io, c, session->pool);
+ h2_conn_io_init(&session->io, c, config, session->pool);
session->bbtmp = apr_brigade_create(session->pool, c->bucket_alloc);
status = init_callbacks(c, &callbacks);
@@ -718,13 +736,13 @@ static h2_session *h2_session_create_int(conn_rec *c,
return session;
}
-h2_session *h2_session_create(conn_rec *c, h2_config *config,
+h2_session *h2_session_create(conn_rec *c, const h2_config *config,
h2_workers *workers)
{
return h2_session_create_int(c, NULL, config, workers);
}
-h2_session *h2_session_rcreate(request_rec *r, h2_config *config,
+h2_session *h2_session_rcreate(request_rec *r, const h2_config *config,
h2_workers *workers)
{
return h2_session_create_int(r->connection, r, config, workers);
@@ -851,7 +869,6 @@ apr_status_t h2_session_abort(h2_session *session, apr_status_t reason, int rv)
apr_status_t h2_session_start(h2_session *session, int *rv)
{
apr_status_t status = APR_SUCCESS;
- h2_config *config;
nghttp2_settings_entry settings[3];
size_t slen;
int i;
@@ -859,15 +876,11 @@ apr_status_t h2_session_start(h2_session *session, int *rv)
AP_DEBUG_ASSERT(session);
/* Start the conversation by submitting our SETTINGS frame */
*rv = 0;
- config = h2_config_get(session->c);
if (session->r) {
const char *s, *cs;
apr_size_t dlen;
h2_stream * stream;
- /* better for vhost matching */
- config = h2_config_rget(session->r);
-
/* 'h2c' mode: we should have a 'HTTP2-Settings' header with
* base64 encoded client settings. */
s = apr_table_get(session->r->headers_in, "HTTP2-Settings");
@@ -921,7 +934,7 @@ apr_status_t h2_session_start(h2_session *session, int *rv)
settings[slen].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
settings[slen].value = (uint32_t)session->max_stream_count;
++slen;
- i = h2_config_geti(config, H2_CONF_WIN_SIZE);
+ i = h2_config_geti(session->config, H2_CONF_WIN_SIZE);
if (i != H2_INITIAL_WINDOW_SIZE) {
settings[slen].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
settings[slen].value = i;
@@ -1167,7 +1180,7 @@ static apr_status_t submit_response(h2_session *session, h2_stream *stream)
nghttp2_data_provider provider;
h2_response *response = stream->response;
h2_ngheader *ngh;
- h2_priority *prio;
+ const h2_priority *prio;
memset(&provider, 0, sizeof(provider));
provider.source.fd = stream->id;
@@ -1203,7 +1216,7 @@ static apr_status_t submit_response(h2_session *session, h2_stream *stream)
*/
if (!rv
&& !stream->initiated_on
- && h2_config_geti(h2_config_get(session->c), H2_CONF_PUSH)
+ && h2_config_geti(session->config, H2_CONF_PUSH)
&& H2_HTTP_2XX(response->http_status)
&& h2_session_push_enabled(session)) {
@@ -1243,26 +1256,24 @@ struct h2_stream *h2_session_push(h2_session *session, h2_stream *is,
int nid;
ngh = h2_util_ngheader_make_req(is->pool, push->req);
- nid = nghttp2_submit_push_promise(session->ngh2, 0, push->initiating_id,
+ nid = nghttp2_submit_push_promise(session->ngh2, 0, is->id,
ngh->nv, ngh->nvlen, NULL);
if (nid <= 0) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
"h2_stream(%ld-%d): submitting push promise fail: %s",
- session->id, push->initiating_id,
- nghttp2_strerror(nid));
+ session->id, is->id, nghttp2_strerror(nid));
return NULL;
}
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
- "h2_stream(%ld-%d): promised new stream %d for %s %s",
- session->id, push->initiating_id, nid,
- push->req->method, push->req->path);
+ "h2_stream(%ld-%d): promised new stream %d for %s %s on %d",
+ session->id, is->id, nid,
+ push->req->method, push->req->path, is->id);
stream = h2_session_open_stream(session, nid);
if (stream) {
h2_stream_set_h2_request(stream, is->id, push->req);
- h2_stream_set_priority(stream, &push->prio);
status = stream_schedule(session, stream, 1);
if (status != APR_SUCCESS) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, session->c,
@@ -1275,7 +1286,7 @@ struct h2_stream *h2_session_push(h2_session *session, h2_stream *is,
else {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
"h2_stream(%ld-%d): failed to create stream obj %d",
- session->id, push->initiating_id, nid);
+ session->id, is->id, nid);
}
if (!stream) {
@@ -1295,7 +1306,7 @@ static int valid_weight(float f)
}
apr_status_t h2_session_set_prio(h2_session *session, h2_stream *stream,
- h2_priority *prio)
+ const h2_priority *prio)
{
apr_status_t status = APR_SUCCESS;
#ifdef H2_NG2_CHANGE_PRIO
@@ -1336,7 +1347,7 @@ apr_status_t h2_session_set_prio(h2_session *session, h2_stream *stream,
*/
ptype = "INTERLEAVED";
w_parent = nghttp2_stream_get_weight(s_parent);
- w = valid_weight(w_parent * ((float)NGHTTP2_MAX_WEIGHT / prio->weight));
+ w = valid_weight(w_parent * ((float)prio->weight / NGHTTP2_MAX_WEIGHT));
nghttp2_priority_spec_init(&ps, id_grandpa, w, 0);
break;
@@ -1347,7 +1358,8 @@ apr_status_t h2_session_set_prio(h2_session *session, h2_stream *stream,
* stream as child with MAX_WEIGHT.
*/
ptype = "BEFORE";
- nghttp2_priority_spec_init(&ps, stream->id, NGHTTP2_MAX_WEIGHT, 0);
+ w_parent = nghttp2_stream_get_weight(s_parent);
+ nghttp2_priority_spec_init(&ps, stream->id, w_parent, 0);
rv = nghttp2_session_change_stream_priority(session->ngh2, id_parent, &ps);
if (rv < 0) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c,
@@ -1357,8 +1369,8 @@ apr_status_t h2_session_set_prio(h2_session *session, h2_stream *stream,
return APR_EGENERAL;
}
id_grandpa = nghttp2_stream_get_stream_id(s_grandpa);
- w_parent = nghttp2_stream_get_weight(s_parent);
- nghttp2_priority_spec_init(&ps, id_grandpa, valid_weight(w_parent), 0);
+ w = valid_weight(w_parent * ((float)prio->weight / NGHTTP2_MAX_WEIGHT));
+ nghttp2_priority_spec_init(&ps, id_grandpa, w, 0);
break;
case H2_DEPENDANT_AFTER:
@@ -1508,12 +1520,43 @@ apr_status_t h2_session_process(h2_session *session)
apr_interval_time_t wait_micros = 0;
static const int MAX_WAIT_MICROS = 200 * 1000;
int got_streams = 0;
+ h2_stream *stream;
while (!session->aborted && (nghttp2_session_want_read(session->ngh2)
|| nghttp2_session_want_write(session->ngh2))) {
int have_written = 0;
int have_read = 0;
+ got_streams = !h2_stream_set_is_empty(session->streams);
+ if (got_streams) {
+ h2_session_resume_streams_with_data(session);
+
+ if (h2_stream_set_has_unsubmitted(session->streams)) {
+ /* If we have responses ready, submit them now. */
+ while ((stream = h2_mplx_next_submit(session->mplx, session->streams))) {
+ status = submit_response(session, stream);
+ if (status == APR_SUCCESS
+ && nghttp2_session_want_write(session->ngh2)) {
+ int rv;
+
+ rv = nghttp2_session_send(session->ngh2);
+ if (rv != 0) {
+ ap_log_cerror( APLOG_MARK, APLOG_DEBUG, 0, session->c,
+ "h2_session: send: %s", nghttp2_strerror(rv));
+ if (nghttp2_is_fatal(rv)) {
+ h2_session_abort(session, status, rv);
+ goto end_process;
+ }
+ }
+ else {
+ have_written = 1;
+ wait_micros = 0;
+ }
+ }
+ }
+ }
+ }
+
/* Send data as long as we have it and window sizes allow. We are
* a server after all.
*/
@@ -1629,9 +1672,7 @@ apr_status_t h2_session_process(h2_session *session)
}
got_streams = !h2_stream_set_is_empty(session->streams);
- if (got_streams) {
- h2_stream *stream;
-
+ if (got_streams) {
if (session->reprioritize) {
h2_mplx_reprioritize(session->mplx, stream_pri_cmp, session);
session->reprioritize = 0;
@@ -1657,15 +1698,6 @@ apr_status_t h2_session_process(h2_session *session)
h2_conn_io_flush(&session->io);
}
}
-
- h2_session_resume_streams_with_data(session);
-
- if (h2_stream_set_has_unsubmitted(session->streams)) {
- /* If we have responses ready, submit them now. */
- while ((stream = h2_mplx_next_submit(session->mplx, session->streams))) {
- status = submit_response(session, stream);
- }
- }
}
if (have_written) {
diff --git a/modules/http2/h2_session.h b/modules/http2/h2_session.h
index 16767fb785..00347c93e4 100644
--- a/modules/http2/h2_session.h
+++ b/modules/http2/h2_session.h
@@ -59,6 +59,7 @@ struct h2_session {
conn_rec *c; /* the connection this session serves */
request_rec *r; /* the request that started this in case
* of 'h2c', NULL otherwise */
+ const struct h2_config *config; /* Relevant config for this session */
int aborted; /* this session is being aborted */
int reprioritize; /* scheduled streams priority needs to
* be re-evaluated */
@@ -94,7 +95,7 @@ struct h2_session {
* @param workers the worker pool to use
* @return the created session
*/
-h2_session *h2_session_create(conn_rec *c, struct h2_config *cfg,
+h2_session *h2_session_create(conn_rec *c, const struct h2_config *cfg,
struct h2_workers *workers);
/**
@@ -105,7 +106,7 @@ h2_session *h2_session_create(conn_rec *c, struct h2_config *cfg,
* @param workers the worker pool to use
* @return the created session
*/
-h2_session *h2_session_rcreate(request_rec *r, struct h2_config *cfg,
+h2_session *h2_session_rcreate(request_rec *r, const struct h2_config *cfg,
struct h2_workers *workers);
/**
@@ -198,7 +199,7 @@ struct h2_stream *h2_session_push(h2_session *session,
apr_status_t h2_session_set_prio(h2_session *session,
struct h2_stream *stream,
- struct h2_priority *prio);
+ const struct h2_priority *prio);
#endif /* defined(__mod_h2__h2_session__) */
diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c
index c9f88a27b6..58f722bc64 100644
--- a/modules/http2/h2_stream.c
+++ b/modules/http2/h2_stream.c
@@ -25,6 +25,7 @@
#include "h2_private.h"
#include "h2_conn.h"
+#include "h2_config.h"
#include "h2_h2.h"
#include "h2_mplx.h"
#include "h2_push.h"
@@ -159,7 +160,7 @@ h2_stream *h2_stream_open(int id, apr_pool_t *pool, h2_session *session)
{
h2_stream *stream = h2_stream_create(id, pool, session);
set_state(stream, H2_STREAM_ST_OPEN);
- stream->request = h2_request_create(id, pool);
+ stream->request = h2_request_create(id, pool, session->config);
stream->bbout = apr_brigade_create(stream->pool,
stream->session->c->bucket_alloc);
@@ -669,14 +670,15 @@ apr_table_t *h2_stream_get_trailers(h2_stream *stream)
return stream->response? stream->response->trailers : NULL;
}
-void h2_stream_set_priority(h2_stream *stream, h2_priority *prio)
+const h2_priority *h2_stream_get_priority(h2_stream *stream)
{
- stream->prio = apr_pcalloc(stream->pool, sizeof(*prio));
- memcpy(stream->prio, prio, sizeof(*prio));
-}
-
-h2_priority *h2_stream_get_priority(h2_stream *stream)
-{
- return stream->prio;
+ if (stream->initiated_on && stream->response) {
+ const char *ctype = apr_table_get(stream->response->headers, "content-type");
+ if (ctype) {
+ /* FIXME: Not good enough, config needs to come from request->server */
+ return h2_config_get_priority(stream->session->config, ctype);
+ }
+ }
+ return NULL;
}
diff --git a/modules/http2/h2_stream.h b/modules/http2/h2_stream.h
index 8de3ecbacf..7b3eb3e7bc 100644
--- a/modules/http2/h2_stream.h
+++ b/modules/http2/h2_stream.h
@@ -70,8 +70,6 @@ struct h2_stream {
apr_bucket_brigade *bbout; /* output DATA */
apr_off_t data_frames_sent; /* # of DATA frames sent out for this stream */
-
- struct h2_priority *prio; /* priority information to set before submit */
};
@@ -306,13 +304,6 @@ apr_table_t *h2_stream_get_trailers(h2_stream *stream);
/**
* Get priority information set for this stream.
*/
-struct h2_priority *h2_stream_get_priority(h2_stream *stream);
-
-/**
- * Set the priority information to use on the submit of the stream.
- * @param stream the stream to set priority on
- * @param prio the priority information
- */
-void h2_stream_set_priority(h2_stream *stream, struct h2_priority *prio);
+const struct h2_priority *h2_stream_get_priority(h2_stream *stream);
#endif /* defined(__mod_h2__h2_stream__) */
diff --git a/modules/http2/h2_switch.c b/modules/http2/h2_switch.c
index c107db8e73..49e5440624 100644
--- a/modules/http2/h2_switch.c
+++ b/modules/http2/h2_switch.c
@@ -154,7 +154,7 @@ static int h2_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
ap_remove_input_filter_byhandle(r->input_filters, "reqtimeout");
/* Ok, start an h2_conn on this one. */
- status = h2_conn_process(r->connection, r);
+ status = h2_conn_process(r->connection, r, r->server);
if (status != DONE) {
/* Nothing really to do about this. */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
diff --git a/modules/http2/h2_task.c b/modules/http2/h2_task.c
index fee406e1bb..55bcec7293 100644
--- a/modules/http2/h2_task.c
+++ b/modules/http2/h2_task.c
@@ -147,13 +147,13 @@ h2_task *h2_task_create(long session_id, const h2_request *req,
return NULL;
}
- task->id = apr_psprintf(pool, "%ld-%d", session_id, req->id);
+ task->id = apr_psprintf(pool, "%ld-%d", session_id, req->id);
task->stream_id = req->id;
- task->pool = pool;
- task->mplx = mplx;
- task->c = h2_conn_create(mplx->c, task->pool);
+ task->pool = pool;
+ task->mplx = mplx;
+ task->c = h2_conn_create(mplx->c, task->pool);
- task->request = req;
+ task->request = req;
task->input_eos = eos;
return task;
@@ -168,11 +168,10 @@ apr_status_t h2_task_destroy(h2_task *task)
apr_status_t h2_task_do(h2_task *task, h2_worker *worker)
{
apr_status_t status = APR_SUCCESS;
- h2_config *cfg = h2_config_get(task->mplx->c);
AP_DEBUG_ASSERT(task);
- task->serialize_headers = h2_config_geti(cfg, H2_CONF_SER_HEADERS);
+ task->serialize_headers = h2_config_geti(task->request->config, H2_CONF_SER_HEADERS);
status = h2_worker_setup_task(worker, task);
diff --git a/modules/http2/h2_task.h b/modules/http2/h2_task.h
index 7cf0f20de2..1cc32d647c 100644
--- a/modules/http2/h2_task.h
+++ b/modules/http2/h2_task.h
@@ -66,7 +66,8 @@ struct h2_task {
};
h2_task *h2_task_create(long session_id, const struct h2_request *req,
- apr_pool_t *pool, struct h2_mplx *mplx, int eos);
+ apr_pool_t *pool, struct h2_mplx *mplx,
+ int eos);
apr_status_t h2_task_destroy(h2_task *task);
diff --git a/modules/http2/h2_version.h b/modules/http2/h2_version.h
index 950e43ff4a..cf05c0dc35 100644
--- a/modules/http2/h2_version.h
+++ b/modules/http2/h2_version.h
@@ -20,7 +20,7 @@
* @macro
* Version number of the h2 module as c string
*/
-#define MOD_HTTP2_VERSION "1.0.7"
+#define MOD_HTTP2_VERSION "1.0.8"
/**
* @macro
@@ -28,7 +28,7 @@
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
-#define MOD_HTTP2_VERSION_NUM 0x010007
+#define MOD_HTTP2_VERSION_NUM 0x010008
#endif /* mod_h2_h2_version_h */