From: Stefan Eissing Date: Mon, 21 Dec 2015 13:32:20 +0000 (+0000) Subject: subprocess_env vars HTTP2 and H2PUSH supported, export of mod_http2.h with OPTIONALs... X-Git-Tag: 2.5.0-alpha~2512 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f650f5c9428f9e4038acddc6de85ef0980785856;p=apache subprocess_env vars HTTP2 and H2PUSH supported, export of mod_http2.h with OPTIONALs for others to directly look these up, similar to mod_ssl git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1721150 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/mod/mod_http2.xml b/docs/manual/mod/mod_http2.xml index 64156347b2..206744e809 100644 --- a/docs/manual/mod/mod_http2.xml +++ b/docs/manual/mod/mod_http2.xml @@ -803,4 +803,24 @@ H2PushPriority text/css interleaved # weight 256 default +
Environment Variables + +

This module can be configured to provide HTTP/2 related information + as additional environment variables to the SSI and CGI namespace. +

+ + + + + + + + + + + +
Variable Name:Value Type:Description:
HTTPe flag HTTP/2 is being used.
H2PUSH flag HTTP/2 Server Push is enabled for this request and also supported by the client.
+ +
+ diff --git a/modules/http2/config.m4 b/modules/http2/config.m4 index 1a6f89db2d..7021e80228 100644 --- a/modules/http2/config.m4 +++ b/modules/http2/config.m4 @@ -193,6 +193,9 @@ is usually linked shared and requires loading. ], $http2_objs, , most, [ fi ]) +# Ensure that other modules can pick up mod_http2.h +APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) + dnl # end of module specific part APACHE_MODPATH_FINISH diff --git a/modules/http2/h2_h2.c b/modules/http2/h2_h2.c index 2a795ba332..95bb922f37 100644 --- a/modules/http2/h2_h2.c +++ b/modules/http2/h2_h2.c @@ -27,6 +27,7 @@ #include #include +#include "mod_http2.h" #include "h2_private.h" #include "h2_stream.h" @@ -38,6 +39,7 @@ #include "h2_session.h" #include "h2_util.h" #include "h2_h2.h" +#include "mod_http2.h" const char *h2_tls_protos[] = { "h2", NULL @@ -440,7 +442,6 @@ static int cipher_is_blacklisted(const char *cipher, const char **psource) */ static int h2_h2_process_conn(conn_rec* c); static int h2_h2_post_read_req(request_rec *r); -static int h2_h2_fixups(request_rec *r); /******************************************************************************* * Once per lifetime init, retrieve optional functions @@ -571,10 +572,6 @@ void h2_h2_register_hooks(void) * never see the response. */ ap_hook_post_read_request(h2_h2_post_read_req, NULL, NULL, APR_HOOK_REALLY_FIRST); - - /* Setup subprocess env for certain variables - */ - ap_hook_fixups(h2_h2_fixups, NULL,NULL, APR_HOOK_MIDDLE); } int h2_h2_process_conn(conn_rec* c) @@ -707,17 +704,3 @@ static int h2_h2_post_read_req(request_rec *r) return DECLINED; } -static int h2_h2_fixups(request_rec *r) -{ - if (r->connection->master) { - h2_ctx *ctx = h2_ctx_rget(r); - struct h2_task *task = h2_ctx_get_task(ctx); - if (task) { - apr_table_setn(r->subprocess_env, "HTTP2", "on"); - if (task->request->push) { - apr_table_setn(r->subprocess_env, "H2PUSH", "on"); - } - } - } - return DECLINED; -} \ No newline at end of file diff --git a/modules/http2/h2_private.h b/modules/http2/h2_private.h index a6081fc6bb..0ffaf50dc8 100644 --- a/modules/http2/h2_private.h +++ b/modules/http2/h2_private.h @@ -33,4 +33,6 @@ APLOG_USE_MODULE(http2); #define H2_HEADER_PATH_LEN 5 #define H2_CRLF "\r\n" +#define H2_ALEN(a) (sizeof(a)/sizeof((a)[0])) + #endif diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c index 76713c85aa..0fd1d7e333 100644 --- a/modules/http2/h2_util.c +++ b/modules/http2/h2_util.c @@ -895,7 +895,6 @@ typedef struct { } literal; #define H2_DEF_LITERAL(n) { (n), (sizeof(n)-1) } -#define H2_ALEN(a) (sizeof(a)/sizeof((a)[0])) #define H2_LIT_ARGS(a) (a),H2_ALEN(a) static literal IgnoredRequestHeaders[] = { diff --git a/modules/http2/mod_http2.c b/modules/http2/mod_http2.c index b1e79f16a5..8d4cce4346 100644 --- a/modules/http2/mod_http2.c +++ b/modules/http2/mod_http2.c @@ -18,9 +18,10 @@ #include #include +#include #include -#include "mod_h2.h" +#include "mod_http2.h" #include #include "h2_stream.h" @@ -31,6 +32,7 @@ #include "h2_config.h" #include "h2_ctx.h" #include "h2_h2.h" +#include "h2_request.h" #include "h2_switch.h" #include "h2_version.h" @@ -47,6 +49,8 @@ AP_DECLARE_MODULE(http2) = { h2_hooks }; +static int h2_h2_fixups(request_rec *r); + /* The module initialization. Called once as apache hook, before any multi * processing (threaded or not) happens. It is typically at least called twice, * see @@ -106,6 +110,10 @@ static int h2_post_config(apr_pool_t *p, apr_pool_t *plog, return status; } +static char *http2_var_lookup(apr_pool_t *, server_rec *, + conn_rec *, request_rec *, char *name); +static int http2_is_h2(conn_rec *); + /* Runs once per created child process. Perform any process * related initionalization here. */ @@ -117,6 +125,9 @@ static void h2_child_init(apr_pool_t *pool, server_rec *s) ap_log_error(APLOG_MARK, APLOG_ERR, status, s, APLOGNO(02949) "initializing connection handling"); } + + APR_REGISTER_OPTIONAL_FN(http2_is_h2); + APR_REGISTER_OPTIONAL_FN(http2_var_lookup); } /* Install this module into the apache2 infrastructure. @@ -141,6 +152,86 @@ static void h2_hooks(apr_pool_t *pool) h2_alt_svc_register_hooks(); + /* Setup subprocess env for certain variables + */ + ap_hook_fixups(h2_h2_fixups, NULL,NULL, APR_HOOK_MIDDLE); +} + +static char *value_of_HTTP2(apr_pool_t *p, server_rec *s, + conn_rec *c, request_rec *r) +{ + return c && http2_is_h2(c)? "on" : "off"; } +static char *value_of_H2PUSH(apr_pool_t *p, server_rec *s, + conn_rec *c, request_rec *r) +{ + h2_ctx *ctx; + if (r) { + ctx = h2_ctx_rget(r); + if (ctx) { + h2_task *task = h2_ctx_get_task(ctx); + return task && task->request->push? "on" : "off"; + } + } + else if (c) { + ctx = h2_ctx_get(c, 0); + return ctx && h2_session_push_enabled(ctx->session)? "on" : "off"; + } + else if (s) { + const h2_config *cfg = h2_config_sget(s); + return cfg && h2_config_geti(cfg, H2_CONF_PUSH)? "on" : "off"; + } + return "off"; +} + +typedef char *h2_var_lookup(apr_pool_t *p, server_rec *s, + conn_rec *c, request_rec *r); +typedef struct h2_var_def { + const char *name; + h2_var_lookup *lookup; + unsigned int subprocess : 1; /* should be set in r->subprocess_env */ +} h2_var_def; +static h2_var_def H2_VARS[] = { + { "HTTP2", value_of_HTTP2, 1 }, + { "H2PUSH", value_of_H2PUSH, 1 }, +}; + +#ifndef H2_ALEN +#define H2_ALEN(a) (sizeof(a)/sizeof((a)[0])) +#endif + + +static int http2_is_h2(conn_rec *c) +{ + return h2_ctx_get(c->master? c->master : c, 0) != NULL; +} + +static char *http2_var_lookup(apr_pool_t *p, server_rec *s, + conn_rec *c, request_rec *r, char *name) +{ + /* If the # of vars grow, we need to put definitions in a hash */ + for (int i = 0; i < H2_ALEN(H2_VARS); ++i) { + h2_var_def *vdef = &H2_VARS[i]; + if (!strcmp(vdef->name, name)) { + return vdef->lookup(p, s, c, r); + } + } + return ""; +} + +static int h2_h2_fixups(request_rec *r) +{ + if (r->connection->master) { + h2_ctx *ctx = h2_ctx_rget(r); + for (int i = 0; ctx && i < H2_ALEN(H2_VARS); ++i) { + h2_var_def *vdef = &H2_VARS[i]; + if (vdef->subprocess) { + apr_table_setn(r->subprocess_env, vdef->name, + vdef->lookup(r->pool, r->server, r->connection, r)); + } + } + } + return DECLINED; +} diff --git a/modules/http2/mod_h2.h b/modules/http2/mod_http2.h similarity index 54% rename from modules/http2/mod_h2.h rename to modules/http2/mod_http2.h index bb895dd2f1..a8c58f2c6d 100644 --- a/modules/http2/mod_h2.h +++ b/modules/http2/mod_http2.h @@ -13,7 +13,18 @@ * limitations under the License. */ -#ifndef mod_h2_mod_h2_h -#define mod_h2_mod_h2_h +#ifndef mod_http2_mod_http2_h +#define mod_http2_mod_http2_h + +/** The http2_var_lookup() optional function retrieves HTTP2 environment + * variables. */ +APR_DECLARE_OPTIONAL_FN(char *, http2_var_lookup, + (apr_pool_t *, server_rec *, + conn_rec *, request_rec *, + char *)); + +/** An optional function which returns non-zero if the given connection + * or its master connection is using HTTP/2. */ +APR_DECLARE_OPTIONAL_FN(int, http2_is_h2, (conn_rec *)); #endif