Apache HTTPD
mod_http2.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <apr_optional.h>
18#include <apr_optional_hooks.h>
19#include <apr_strings.h>
20#include <apr_time.h>
21#include <apr_want.h>
22
23#include <httpd.h>
24#include <http_protocol.h>
25#include <http_request.h>
26#include <http_log.h>
27#include <mpm_common.h>
28
29#include "mod_http2.h"
30
31#include <nghttp2/nghttp2.h>
32#include "h2_stream.h"
33#include "h2_c1.h"
34#include "h2_c2.h"
35#include "h2_session.h"
36#include "h2_config.h"
37#include "h2_conn_ctx.h"
38#include "h2_protocol.h"
39#include "h2_mplx.h"
40#include "h2_push.h"
41#include "h2_request.h"
42#include "h2_switch.h"
43#include "h2_version.h"
44#include "h2_bucket_beam.h"
45#include "h2_ws.h"
46
47
48static void h2_hooks(apr_pool_t *pool);
49
52 h2_config_create_dir, /* func to create per dir config */
53 h2_config_merge_dir, /* func to merge per dir config */
54 h2_config_create_svr, /* func to create per server config */
55 h2_config_merge_svr, /* func to merge per server config */
56 h2_cmds, /* command handlers */
58#if defined(AP_MODULE_FLAG_NONE)
60#endif
61};
62
63static int h2_h2_fixups(request_rec *r);
64
65typedef struct {
66 unsigned int change_prio : 1;
67 unsigned int sha256 : 1;
68 unsigned int inv_headers : 1;
69 unsigned int dyn_windows : 1;
70} features;
71
73static int mpm_warned;
74
75/* The module initialization. Called once as apache hook, before any multi
76 * processing (threaded or not) happens. It is typically at least called twice,
77 * see
78 * http://wiki.apache.org/httpd/ModuleLife
79 * Since the first run is just a "practise" run, we want to initialize for real
80 * only on the second try. This defeats the purpose of the first dry run a bit,
81 * since apache wants to verify that a new configuration actually will work.
82 * So if we have trouble with the configuration, this will only be detected
83 * when the server has already switched.
84 * On the other hand, when we initialize lib nghttp2, all possible crazy things
85 * might happen and this might even eat threads. So, better init on the real
86 * invocation, for now at least.
87 */
89 apr_pool_t *ptemp, server_rec *s)
90{
91 void *data = NULL;
92 const char *mod_h2_init_key = "mod_http2_init_counter";
93 nghttp2_info *ngh2;
95
96 (void)plog;(void)ptemp;
97#ifdef H2_NG2_CHANGE_PRIO
99#endif
100#ifdef H2_OPENSSL
101 myfeats.sha256 = 1;
102#endif
103#ifdef H2_NG2_INVALID_HEADER_CB
105#endif
106#ifdef H2_NG2_LOCAL_WIN_SIZE
108#endif
109
110 apr_pool_userdata_get(&data, mod_h2_init_key, s->process->pool);
111 if ( data == NULL ) {
113 "initializing post config dry run");
114 apr_pool_userdata_set((const void *)1, mod_h2_init_key,
115 apr_pool_cleanup_null, s->process->pool);
116 return APR_SUCCESS;
117 }
118
119 ngh2 = nghttp2_version(0);
121 "mod_http2 (v%s, feats=%s%s%s%s, nghttp2 %s), initializing...",
123 myfeats.change_prio? "CHPRIO" : "",
124 myfeats.sha256? "+SHA256" : "",
125 myfeats.inv_headers? "+INVHD" : "",
126 myfeats.dyn_windows? "+DWINS" : "",
127 ngh2? ngh2->version_str : "unknown");
128
129 if (!h2_mpm_supported() && !mpm_warned) {
130 mpm_warned = 1;
132 "The mpm module (%s) is not supported by mod_http2. The mpm determines "
133 "how things are processed in your server. HTTP/2 has more demands in "
134 "this regard and the currently selected mpm will just not do. "
135 "This is an advisory warning. Your server will continue to work, but "
136 "the HTTP/2 protocol will be inactive.",
138 }
139
141 if (status == APR_SUCCESS) {
143 }
144
145 return status;
146}
147
148static char *http2_var_lookup(apr_pool_t *, server_rec *,
149 conn_rec *, request_rec *, char *name);
150static int http2_is_h2(conn_rec *);
151
152static void http2_get_num_workers(server_rec *s, int *minw, int *maxw)
153{
155
157}
158
159/* Runs once per created child process. Perform any process
160 * related initionalization here.
161 */
163{
164 apr_status_t rv;
165
166 /* Set up our connection processing */
168 if (APR_SUCCESS == rv) {
170 }
171 if (APR_SUCCESS != rv) {
173 APLOGNO(02949) "initializing connection handling");
174 }
175}
176
177/* Install this module into the apache2 infrastructure.
178 */
180{
181 static const char *const mod_ssl[] = { "mod_ssl.c", NULL};
182
186
187 ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, "installing hooks");
188
189 /* Run once after configuration is set, but before mpm children initialize.
190 */
192
193 /* Run once after a child process has been created.
194 */
196#if AP_MODULE_MAGIC_AT_LEAST(20120211, 110)
198#endif
199
204
205 /* Setup subprocess env for certain variables
206 */
208}
209
210static const char *val_HTTP2(apr_pool_t *p, server_rec *s,
212{
213 return ctx? "on" : "off";
214}
215
216static const char *val_H2_PUSH(apr_pool_t *p, server_rec *s,
219{
220 if (conn_ctx) {
221 if (r) {
222 if (conn_ctx->stream_id) {
223 const h2_stream *stream = h2_mplx_c2_stream_get(conn_ctx->mplx, conn_ctx->stream_id);
224 if (stream && stream->push_policy != H2_PUSH_NONE) {
225 return "on";
226 }
227 }
228 }
229 else if (c && h2_session_push_enabled(conn_ctx->session)) {
230 return "on";
231 }
232 }
233 else if (s) {
235 return "on";
236 }
237 }
238 return "off";
239}
240
241static const char *val_H2_PUSHED(apr_pool_t *p, server_rec *s,
244{
245 if (conn_ctx) {
246 if (conn_ctx->stream_id && !H2_STREAM_CLIENT_INITIATED(conn_ctx->stream_id)) {
247 return "PUSHED";
248 }
249 }
250 return "";
251}
252
256{
257 if (conn_ctx) {
258 if (conn_ctx->stream_id && !H2_STREAM_CLIENT_INITIATED(conn_ctx->stream_id)) {
259 const h2_stream *stream = h2_mplx_c2_stream_get(conn_ctx->mplx, conn_ctx->stream_id);
260 if (stream) {
261 return apr_itoa(p, stream->initiated_on);
262 }
263 }
264 }
265 return "";
266}
267
270{
271 if (c) {
273 if (conn_ctx) {
274 return conn_ctx->stream_id == 0? conn_ctx->id
275 : apr_psprintf(p, "%s-%d", conn_ctx->id, conn_ctx->stream_id);
276 }
277 }
278 return "";
279}
280
283{
284 const char *cp = val_H2_STREAM_TAG(p, s, c, r, ctx);
285 if (cp && (cp = ap_strrchr_c(cp, '-'))) {
286 return ++cp;
287 }
288 return NULL;
289}
290
291typedef const char *h2_var_lookup(apr_pool_t *p, server_rec *s,
293typedef struct h2_var_def {
294 const char *name;
296 unsigned int subprocess : 1; /* should be set in r->subprocess_env */
298
299static h2_var_def H2_VARS[] = {
300 { "HTTP2", val_HTTP2, 1 },
301 { "H2PUSH", val_H2_PUSH, 1 },
302 { "H2_PUSH", val_H2_PUSH, 1 },
303 { "H2_PUSHED", val_H2_PUSHED, 1 },
304 { "H2_PUSHED_ON", val_H2_PUSHED_ON, 1 },
305 { "H2_STREAM_ID", val_H2_STREAM_ID, 1 },
306 { "H2_STREAM_TAG", val_H2_STREAM_TAG, 1 },
307};
308
309#ifndef H2_ALEN
310#define H2_ALEN(a) (sizeof(a)/sizeof((a)[0]))
311#endif
312
313
315{
316 return h2_conn_ctx_get(c->master? c->master : c) != NULL;
317}
318
320 conn_rec *c, request_rec *r, char *name)
321{
322 unsigned int i;
323 /* If the # of vars grow, we need to put definitions in a hash */
324 for (i = 0; i < H2_ALEN(H2_VARS); ++i) {
326 if (!strcmp(vdef->name, name)) {
328 h2_conn_ctx_get(c->master? c->master : c));
329 return (char *)vdef->lookup(p, s, c, r, ctx);
330 }
331 }
332 return (char*)"";
333}
334
336{
337 if (r->connection->master) {
339 unsigned int i;
340
341 for (i = 0; ctx && i < H2_ALEN(H2_VARS); ++i) {
343 if (vdef->subprocess) {
345 vdef->lookup(r->pool, r->server, r->connection,
346 r, ctx));
347 }
348 }
349 }
350 return DECLINED;
351}
APR-UTIL registration of functions exported by modules.
Apache optional hook functions.
APR Strings library.
APR Time Library.
APR Standard Headers Support.
#define AP_MODULE_FLAG_ALWAYS_MERGE
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:105
#define AP_DECLARE_MODULE(foo)
request_rec * r
void ap_hook_child_init(ap_HOOK_child_init_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:167
#define DECLINED
Definition httpd.h:457
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_INFO
Definition http_log.h:70
#define APLOG_ERR
Definition http_log.h:67
#define ap_log_error
Definition http_log.h:370
#define APLOG_MARK
Definition http_log.h:283
#define ap_log_perror
Definition http_log.h:412
#define APLOG_WARNING
Definition http_log.h:68
#define APLOG_TRACE1
Definition http_log.h:72
#define APLOG_DEBUG
Definition http_log.h:71
void ap_hook_fixups(ap_HOOK_fixups_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition request.c:87
void ap_hook_child_stopping(ap_HOOK_child_stopping_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition mpm_common.c:118
apr_brigade_flush void * ctx
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define APR_REGISTER_OPTIONAL_FN(name)
#define STANDARD20_MODULE_STUFF
#define ap_strrchr_c(s, c)
Definition httpd.h:2357
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
apr_vformatter_buff_t * c
Definition apr_lib.h:175
const char * s
Definition apr_strings.h:95
int int status
apr_int64_t apr_time_t
Definition apr_time.h:45
@ H2_PUSH_NONE
Definition h2.h:115
#define H2_ALEN(a)
Definition h2.h:98
#define H2_STREAM_CLIENT_INITIATED(id)
Definition h2.h:96
void h2_c1_child_stopping(apr_pool_t *pool, int graceful)
Definition h2_c1.c:79
void h2_c1_register_hooks(void)
Definition h2_c1.c:308
apr_status_t h2_c1_child_init(apr_pool_t *pool, server_rec *s)
Definition h2_c1.c:55
static const char *const mod_ssl[]
Definition h2_c1.c:305
void h2_c2_register_hooks(void)
Definition h2_c2.c:917
int h2_mpm_supported(void)
Definition h2_c2.c:125
apr_status_t h2_c2_child_init(apr_pool_t *pool, server_rec *s)
Definition h2_c2.c:131
const char * h2_conn_mpm_name(void)
Definition h2_c2.c:119
void * h2_config_create_dir(apr_pool_t *pool, char *x)
Definition h2_config.c:229
void * h2_config_create_svr(apr_pool_t *pool, server_rec *s)
Definition h2_config.c:139
const command_rec h2_cmds[]
Definition h2_config.c:1027
void * h2_config_merge_svr(apr_pool_t *pool, void *basev, void *addv)
Definition h2_config.c:224
int h2_config_geti(request_rec *r, server_rec *s, h2_config_var_t var)
Definition h2_config.c:516
void h2_get_workers_config(server_rec *s, int *pminw, int *pmaxw, apr_time_t *pidle_limit)
Definition h2_config.c:1007
void * h2_config_merge_dir(apr_pool_t *pool, void *basev, void *addv)
Definition h2_config.c:243
@ H2_CONF_PUSH
Definition h2_config.h:38
#define h2_conn_ctx_get(c)
Definition h2_conn_ctx.h:78
static apr_pool_t * pchild
Definition h2_mplx.c:74
const h2_stream * h2_mplx_c2_stream_get(h2_mplx *m, int stream_id)
Definition h2_mplx.c:562
apr_status_t h2_protocol_init(apr_pool_t *pool, server_rec *s)
int h2_session_push_enabled(h2_session *session)
void h2_switch_register_hooks(void)
Definition h2_switch.c:228
apr_status_t h2_switch_init(apr_pool_t *pool, server_rec *s)
Definition h2_switch.c:44
#define MOD_HTTP2_VERSION
Definition h2_version.h:30
void h2_ws_register_hooks(void)
Definition h2_ws.c:357
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
static int h2_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
Definition mod_http2.c:88
static const char * val_H2_STREAM_TAG(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
Definition mod_http2.c:268
static int h2_h2_fixups(request_rec *r)
Definition mod_http2.c:335
static int mpm_warned
Definition mod_http2.c:73
static void http2_get_num_workers(server_rec *s, int *minw, int *maxw)
Definition mod_http2.c:152
static const char * val_H2_PUSHED_ON(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, h2_conn_ctx_t *conn_ctx)
Definition mod_http2.c:253
static const char * val_HTTP2(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
Definition mod_http2.c:210
const char * h2_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
Definition mod_http2.c:291
static void h2_child_init(apr_pool_t *pchild, server_rec *s)
Definition mod_http2.c:162
static const char * val_H2_PUSHED(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, h2_conn_ctx_t *conn_ctx)
Definition mod_http2.c:241
static void h2_hooks(apr_pool_t *pool)
Definition mod_http2.c:179
static const char * val_H2_STREAM_ID(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, h2_conn_ctx_t *ctx)
Definition mod_http2.c:281
static char * http2_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *name)
Definition mod_http2.c:319
static features myfeats
Definition mod_http2.c:72
static int http2_is_h2(conn_rec *)
Definition mod_http2.c:314
static h2_var_def H2_VARS[]
Definition mod_http2.c:299
static const char * val_H2_PUSH(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, h2_conn_ctx_t *conn_ctx)
Definition mod_http2.c:216
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
Multi-Processing Modules functions.
char * name
Structure to store things which are per connection.
Definition httpd.h:1152
conn_rec * master
Definition httpd.h:1248
unsigned int change_prio
Definition mod_http2.c:66
unsigned int dyn_windows
Definition mod_http2.c:69
unsigned int inv_headers
Definition mod_http2.c:68
unsigned int sha256
Definition mod_http2.c:67
unsigned int push_policy
Definition h2_stream.h:114
int initiated_on
Definition h2_stream.h:83
unsigned int subprocess
Definition mod_http2.c:296
const char * name
Definition mod_http2.c:294
h2_var_lookup * lookup
Definition mod_http2.c:295
A structure that represents the current request.
Definition httpd.h:845
apr_pool_t * pool
Definition httpd.h:847
conn_rec * connection
Definition httpd.h:849
apr_table_t * subprocess_env
Definition httpd.h:983
server_rec * server
Definition httpd.h:851
A structure to store information for each virtual server.
Definition httpd.h:1322