From 5b907366de3490111a6ae44ddd1f4f33fb0b6662 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Wed, 23 Nov 2016 18:20:10 +0000 Subject: [PATCH] Merge of r1771001,1771015 from trunk: mod_http2: new directive H2EarlyHints git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1771018 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ docs/manual/mod/mod_http2.xml | 27 +++++++++++++++++++++++++++ modules/http2/h2_config.c | 26 +++++++++++++++++++++++++- modules/http2/h2_config.h | 2 ++ modules/http2/h2_session.c | 8 ++++++++ modules/http2/h2_version.h | 4 ++-- 6 files changed, 67 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 2861e58575..0f4e175b81 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.24 + *) mod_http2: new directive 'H2EarlyHints' to enable sending of HTTP status + 103 interim responses. Disabled by default. [Stefan Eissing] + *) mod_ssl: Fix quick renegotiation (OptRenegotiaton) with no intermediate in the client certificate chain. PR 55786. [Yann Ylavic] diff --git a/docs/manual/mod/mod_http2.xml b/docs/manual/mod/mod_http2.xml index 02134bbe9f..b7dcc959be 100644 --- a/docs/manual/mod/mod_http2.xml +++ b/docs/manual/mod/mod_http2.xml @@ -972,4 +972,31 @@ H2TLSCoolDownSecs 0 + + H2EarlyHints + Determine sending of 103 status codes + H2EarlyHints on|off + H2EarlyHints off + + server config + virtual host + + Available in version 2.4.24 and later. + + +

+ This setting controls if HTTP status 103 interim responses are + forwarded to the client or not. By default, this is currently + not the case since a range of clients still have trouble with + unexpected interim responses. +

+

+ When set to on, PUSH resources announced with + H2PushResource will trigger an interim 103 response + before the final response. The 103 response will carry Link + headers that advise the preload of such resources. +

+
+
+ diff --git a/modules/http2/h2_config.c b/modules/http2/h2_config.c index dec859705a..669d20e75c 100644 --- a/modules/http2/h2_config.c +++ b/modules/http2/h2_config.c @@ -62,7 +62,8 @@ static h2_config defconf = { NULL, /* map of content-type to priorities */ 256, /* push diary size */ 0, /* copy files across threads */ - NULL /* push list */ + NULL, /* push list */ + 0, /* early hints, http status 103 */ }; void h2_config_init(apr_pool_t *pool) @@ -97,6 +98,7 @@ static void *h2_config_create(apr_pool_t *pool, conf->push_diary_size = DEF_VAL; conf->copy_files = DEF_VAL; conf->push_list = NULL; + conf->early_hints = DEF_VAL; return conf; } @@ -148,6 +150,7 @@ 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; } + n->early_hints = H2_CONFIG_GET(add, base, early_hints); return n; } @@ -203,6 +206,8 @@ apr_int64_t h2_config_geti64(const h2_config *conf, h2_config_var_t var) return H2_CONFIG_GET(conf, &defconf, push_diary_size); case H2_CONF_COPY_FILES: return H2_CONFIG_GET(conf, &defconf, copy_files); + case H2_CONF_EARLY_HINTS: + return H2_CONFIG_GET(conf, &defconf, early_hints); default: return DEF_VAL; } @@ -588,6 +593,23 @@ static const char *h2_conf_add_push_res(cmd_parms *cmd, void *dirconf, return NULL; } +static const char *h2_conf_set_early_hints(cmd_parms *parms, + void *arg, const char *value) +{ + h2_config *cfg = (h2_config *)h2_config_sget(parms->server); + if (!strcasecmp(value, "On")) { + cfg->early_hints = 1; + return NULL; + } + else if (!strcasecmp(value, "Off")) { + cfg->early_hints = 0; + return NULL; + } + + (void)arg; + return "value must be On or Off"; +} + #define AP_END_CMD AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL) const command_rec h2_cmds[] = { @@ -631,6 +653,8 @@ const command_rec h2_cmds[] = { OR_FILEINFO, "on to perform copy of file data"), AP_INIT_TAKE123("H2PushResource", h2_conf_add_push_res, NULL, OR_FILEINFO, "add a resource to be pushed in this location/on this server."), + AP_INIT_TAKE1("H2EarlyHints", h2_conf_set_early_hints, NULL, + RSRC_CONF, "on to enable interim status 103 responses"), AP_END_CMD }; diff --git a/modules/http2/h2_config.h b/modules/http2/h2_config.h index 08bde3b740..1f2fe309d0 100644 --- a/modules/http2/h2_config.h +++ b/modules/http2/h2_config.h @@ -41,6 +41,7 @@ typedef enum { H2_CONF_PUSH, H2_CONF_PUSH_DIARY_SIZE, H2_CONF_COPY_FILES, + H2_CONF_EARLY_HINTS, } h2_config_var_t; struct apr_hash_t; @@ -77,6 +78,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 */ + int early_hints; /* support status code 103 */ } h2_config; diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c index 7225201bfc..0a29a3b18c 100644 --- a/modules/http2/h2_session.c +++ b/modules/http2/h2_session.c @@ -1501,6 +1501,14 @@ static apr_status_t on_stream_headers(h2_session *session, h2_stream *stream, apr_itoa(stream->pool, connFlowOut)); } + if (headers->status == 103 + && !h2_config_geti(session->config, H2_CONF_EARLY_HINTS)) { + /* suppress sending this to the client, it might have triggered + * pushes and served its purpose nevertheless */ + rv = 0; + goto leave; + } + ngh = h2_util_ngheader_make_res(stream->pool, headers->status, hout); rv = nghttp2_submit_response(session->ngh2, stream->id, ngh->nv, ngh->nvlen, pprovider); diff --git a/modules/http2/h2_version.h b/modules/http2/h2_version.h index 27a298b3b9..f272c3c71f 100644 --- a/modules/http2/h2_version.h +++ b/modules/http2/h2_version.h @@ -26,7 +26,7 @@ * @macro * Version number of the http2 module as c string */ -#define MOD_HTTP2_VERSION "1.8.1" +#define MOD_HTTP2_VERSION "1.8.2" /** * @macro @@ -34,7 +34,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 0x010801 +#define MOD_HTTP2_VERSION_NUM 0x010802 #endif /* mod_h2_h2_version_h */ -- 2.40.0