summaryrefslogtreecommitdiff
path: root/modules/http2/h2_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/http2/h2_config.c')
-rw-r--r--modules/http2/h2_config.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/modules/http2/h2_config.c b/modules/http2/h2_config.c
index f6dd1065db..670833ec12 100644
--- a/modules/http2/h2_config.c
+++ b/modules/http2/h2_config.c
@@ -70,6 +70,7 @@ typedef struct h2_config {
int push_diary_size; /* # of entries in push diary */
int copy_files; /* if files shall be copied vs setaside on output */
apr_array_header_t *push_list; /* list of h2_push_res configurations */
+ apr_table_t *early_headers; /* HTTP headers for a 103 response */
int early_hints; /* support status code 103 */
int padding_bits;
int padding_always;
@@ -83,6 +84,7 @@ typedef struct h2_dir_config {
int h2_upgrade; /* Allow HTTP/1 upgrade to h2/h2c */
int h2_push; /* if HTTP/2 server push is enabled */
apr_array_header_t *push_list; /* list of h2_push_res configurations */
+ apr_table_t *early_headers; /* HTTP headers for a 103 response */
int early_hints; /* support status code 103 */
apr_interval_time_t stream_timeout;/* beam timeout */
} h2_dir_config;
@@ -106,6 +108,7 @@ static h2_config defconf = {
256, /* push diary size */
0, /* copy files across threads */
NULL, /* push list */
+ NULL, /* early headers */
0, /* early hints, http status 103 */
0, /* padding bits */
1, /* padding always */
@@ -119,6 +122,7 @@ static h2_dir_config defdconf = {
-1, /* HTTP/1 Upgrade support */
-1, /* HTTP/2 server push enabled */
NULL, /* push list */
+ NULL, /* early headers */
-1, /* early hints, http status 103 */
-1, /* beam timeout */
};
@@ -150,6 +154,7 @@ void *h2_config_create_svr(apr_pool_t *pool, server_rec *s)
conf->push_diary_size = DEF_VAL;
conf->copy_files = DEF_VAL;
conf->push_list = NULL;
+ conf->early_headers = NULL;
conf->early_hints = DEF_VAL;
conf->padding_bits = DEF_VAL;
conf->padding_always = DEF_VAL;
@@ -194,6 +199,12 @@ static void *h2_config_merge(apr_pool_t *pool, void *basev, void *addv)
else {
n->push_list = add->push_list? add->push_list : base->push_list;
}
+ if (add->early_headers && base->early_headers) {
+ n->early_headers = apr_table_overlay(pool, add->early_headers, base->early_headers);
+ }
+ else {
+ n->early_headers = add->early_headers? add->early_headers : base->early_headers;
+ }
n->early_hints = H2_CONFIG_GET(add, base, early_hints);
n->padding_bits = H2_CONFIG_GET(add, base, padding_bits);
n->padding_always = H2_CONFIG_GET(add, base, padding_always);
@@ -236,6 +247,12 @@ void *h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv)
else {
n->push_list = add->push_list? add->push_list : base->push_list;
}
+ if (add->early_headers && base->early_headers) {
+ n->early_headers = apr_table_overlay(pool, add->early_headers, base->early_headers);
+ }
+ else {
+ n->early_headers = add->early_headers? add->early_headers : base->early_headers;
+ }
n->early_hints = H2_CONFIG_GET(add, base, early_hints);
n->stream_timeout = H2_CONFIG_GET(add, base, stream_timeout);
return n;
@@ -511,6 +528,18 @@ apr_array_header_t *h2_config_push_list(request_rec *r)
return sconf? sconf->push_list : NULL;
}
+apr_table_t *h2_config_early_headers(request_rec *r)
+{
+ const h2_config *sconf;
+ const h2_dir_config *conf = h2_config_rget(r);
+
+ if (conf && conf->early_headers) {
+ return conf->early_headers;
+ }
+ sconf = h2_config_sget(r->server);
+ return sconf? sconf->early_headers : NULL;
+}
+
const struct h2_priority *h2_cconfig_get_priority(conn_rec *c, const char *content_type)
{
const h2_config *conf = h2_config_get(c);
@@ -832,6 +861,37 @@ static const char *h2_conf_add_push_res(cmd_parms *cmd, void *dirconf,
return NULL;
}
+static const char *h2_conf_add_early_hint(cmd_parms *cmd, void *dirconf,
+ const char *name, const char *value)
+{
+ apr_table_t *hds, **phds;
+
+ if(!name || !*name)
+ return "Early Hint header name must not be empty";
+ if(!value)
+ return "Early Hint header value must not be empty";
+ while (apr_isspace(*value))
+ ++value;
+ if(!*value)
+ return "Early Hint header value must not be empty/only space";
+ if (*ap_scan_http_field_content(value))
+ return "Early Hint header value contains invalid characters";
+
+ if (cmd->path) {
+ phds = &((h2_dir_config*)dirconf)->early_headers;
+ }
+ else {
+ phds = &(h2_config_sget(cmd->server))->early_headers;
+ }
+ hds = *phds;
+ if (!hds) {
+ *phds = hds = apr_table_make(cmd->pool, 10);
+ }
+ apr_table_add(hds, name, value);
+
+ return NULL;
+}
+
static const char *h2_conf_set_early_hints(cmd_parms *cmd,
void *dirconf, const char *value)
{
@@ -959,6 +1019,8 @@ const command_rec h2_cmds[] = {
RSRC_CONF, "set stream timeout"),
AP_INIT_TAKE1("H2MaxDataFrameLen", h2_conf_set_max_data_frame_len, NULL,
RSRC_CONF, "maximum number of bytes in a single HTTP/2 DATA frame"),
+ AP_INIT_TAKE2("H2EarlyHint", h2_conf_add_early_hint, NULL,
+ OR_FILEINFO|OR_AUTHCFG, "add a a 'Link:' header for a 103 Early Hints response."),
AP_END_CMD
};