]> granicus.if.org Git - apache/commitdiff
subprocess_env vars HTTP2 and H2PUSH supported, export of mod_http2.h with OPTIONALs...
authorStefan Eissing <icing@apache.org>
Mon, 21 Dec 2015 13:32:20 +0000 (13:32 +0000)
committerStefan Eissing <icing@apache.org>
Mon, 21 Dec 2015 13:32:20 +0000 (13:32 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1721150 13f79535-47bb-0310-9956-ffa450edef68

docs/manual/mod/mod_http2.xml
modules/http2/config.m4
modules/http2/h2_h2.c
modules/http2/h2_private.h
modules/http2/h2_util.c
modules/http2/mod_http2.c
modules/http2/mod_http2.h [moved from modules/http2/mod_h2.h with 54% similarity]

index 64156347b2d4d4d0f6f95b8f652f67b5b5d0e562..206744e809c39a865fa48262275504d9f0cee99c 100644 (file)
@@ -803,4 +803,24 @@ H2PushPriority text/css   interleaved      # weight 256 default
         </usage>
     </directivesynopsis>
 
+    <section id="envvars"><title>Environment Variables</title>
+        
+        <p>This module can be configured to provide HTTP/2 related information
+            as additional environment variables to the SSI and CGI namespace.
+        </p>
+        
+        <table border="1">
+            <columnspec><column width=".3"/><column width=".2"/><column width=".5"/>
+            </columnspec>
+            <tr>
+                <th><a name="table3">Variable Name:</a></th>
+                <th>Value Type:</th>
+                <th>Description:</th>
+            </tr>
+            <tr><td><code>HTTPe</code></td>                         <td>flag</td>      <td>HTTP/2 is being used.</td></tr>
+            <tr><td><code>H2PUSH</code></td>                        <td>flag</td>      <td>HTTP/2 Server Push is enabled for this request and also supported by the client.</td></tr>
+        </table>
+        
+    </section>
+
 </modulesynopsis>
index 1a6f89db2d0b98dbb90dbf3b2d19bad288bbd5b1..7021e80228d4738378dda9a6d64c684b5c4100c9 100644 (file)
@@ -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
 
index 2a795ba332ccca0f753f0441264c287cf7854e23..95bb922f37e18b1885b76cec32e812cdc8e5aaca 100644 (file)
@@ -27,6 +27,7 @@
 #include <http_request.h>
 #include <http_log.h>
 
+#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
index a6081fc6bbb2d5859c5ae85172d20c1fd8484554..0ffaf50dc8ddd4ac3eda6a9b661bf4dc7c08af4b 100644 (file)
@@ -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
index 76713c85aa6c52e32aa3e76bb3e0fb5e1975ce5f..0fd1d7e333a198dd1636bb50ad1e581bb8fea6cd 100644 (file)
@@ -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[] = {
index b1e79f16a5797e7fc1b2f8e3a444834e0a5fe6ad..8d4cce43466ae487a5ab39c757d16c7d5d3e939e 100644 (file)
 #include <apr_want.h>
 
 #include <httpd.h>
+#include <http_request.h>
 #include <http_log.h>
 
-#include "mod_h2.h"
+#include "mod_http2.h"
 
 #include <nghttp2/nghttp2.h>
 #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;
+}
similarity index 54%
rename from modules/http2/mod_h2.h
rename to modules/http2/mod_http2.h
index bb895dd2f1972e6024bba8be72c3104d1663815e..a8c58f2c6d06395d13c6319f8ee8206ef4c04e8a 100644 (file)
  * 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