Mercurial > hg > nginx
comparison src/http/v2/ngx_http_v2_module.c @ 6246:257b51c37c5a
The HTTP/2 implementation (RFC 7240, 7241).
The SPDY support is removed, as it's incompatible with the new module.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Fri, 11 Sep 2015 20:13:06 +0300 |
parents | |
children | 2cd019520210 |
comparison
equal
deleted
inserted
replaced
6245:3cf25d33886a | 6246:257b51c37c5a |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Nginx, Inc. | |
4 * Copyright (C) Valentin V. Bartenev | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 #include <ngx_http_v2_module.h> | |
12 | |
13 | |
14 static ngx_int_t ngx_http_v2_add_variables(ngx_conf_t *cf); | |
15 | |
16 static ngx_int_t ngx_http_v2_variable(ngx_http_request_t *r, | |
17 ngx_http_variable_value_t *v, uintptr_t data); | |
18 | |
19 static ngx_int_t ngx_http_v2_module_init(ngx_cycle_t *cycle); | |
20 | |
21 static void *ngx_http_v2_create_main_conf(ngx_conf_t *cf); | |
22 static char *ngx_http_v2_init_main_conf(ngx_conf_t *cf, void *conf); | |
23 static void *ngx_http_v2_create_srv_conf(ngx_conf_t *cf); | |
24 static char *ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent, | |
25 void *child); | |
26 static void *ngx_http_v2_create_loc_conf(ngx_conf_t *cf); | |
27 static char *ngx_http_v2_merge_loc_conf(ngx_conf_t *cf, void *parent, | |
28 void *child); | |
29 | |
30 static char *ngx_http_v2_recv_buffer_size(ngx_conf_t *cf, void *post, | |
31 void *data); | |
32 static char *ngx_http_v2_pool_size(ngx_conf_t *cf, void *post, void *data); | |
33 static char *ngx_http_v2_streams_index_mask(ngx_conf_t *cf, void *post, | |
34 void *data); | |
35 static char *ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data); | |
36 static char *ngx_http_v2_spdy_deprecated(ngx_conf_t *cf, ngx_command_t *cmd, | |
37 void *conf); | |
38 | |
39 | |
40 static ngx_conf_post_t ngx_http_v2_recv_buffer_size_post = | |
41 { ngx_http_v2_recv_buffer_size }; | |
42 static ngx_conf_post_t ngx_http_v2_pool_size_post = | |
43 { ngx_http_v2_pool_size }; | |
44 static ngx_conf_post_t ngx_http_v2_streams_index_mask_post = | |
45 { ngx_http_v2_streams_index_mask }; | |
46 static ngx_conf_post_t ngx_http_v2_chunk_size_post = | |
47 { ngx_http_v2_chunk_size }; | |
48 | |
49 | |
50 static ngx_command_t ngx_http_v2_commands[] = { | |
51 | |
52 { ngx_string("http2_recv_buffer_size"), | |
53 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
54 ngx_conf_set_size_slot, | |
55 NGX_HTTP_MAIN_CONF_OFFSET, | |
56 offsetof(ngx_http_v2_main_conf_t, recv_buffer_size), | |
57 &ngx_http_v2_recv_buffer_size_post }, | |
58 | |
59 { ngx_string("http2_pool_size"), | |
60 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
61 ngx_conf_set_size_slot, | |
62 NGX_HTTP_SRV_CONF_OFFSET, | |
63 offsetof(ngx_http_v2_srv_conf_t, pool_size), | |
64 &ngx_http_v2_pool_size_post }, | |
65 | |
66 { ngx_string("http2_max_concurrent_streams"), | |
67 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
68 ngx_conf_set_num_slot, | |
69 NGX_HTTP_SRV_CONF_OFFSET, | |
70 offsetof(ngx_http_v2_srv_conf_t, concurrent_streams), | |
71 NULL }, | |
72 | |
73 { ngx_string("http2_max_field_size"), | |
74 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
75 ngx_conf_set_size_slot, | |
76 NGX_HTTP_SRV_CONF_OFFSET, | |
77 offsetof(ngx_http_v2_srv_conf_t, max_field_size), | |
78 NULL }, | |
79 | |
80 { ngx_string("http2_max_header_size"), | |
81 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
82 ngx_conf_set_size_slot, | |
83 NGX_HTTP_SRV_CONF_OFFSET, | |
84 offsetof(ngx_http_v2_srv_conf_t, max_header_size), | |
85 NULL }, | |
86 | |
87 { ngx_string("http2_streams_index_size"), | |
88 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
89 ngx_conf_set_num_slot, | |
90 NGX_HTTP_SRV_CONF_OFFSET, | |
91 offsetof(ngx_http_v2_srv_conf_t, streams_index_mask), | |
92 &ngx_http_v2_streams_index_mask_post }, | |
93 | |
94 { ngx_string("http2_recv_timeout"), | |
95 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
96 ngx_conf_set_msec_slot, | |
97 NGX_HTTP_SRV_CONF_OFFSET, | |
98 offsetof(ngx_http_v2_srv_conf_t, recv_timeout), | |
99 NULL }, | |
100 | |
101 { ngx_string("http2_idle_timeout"), | |
102 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
103 ngx_conf_set_msec_slot, | |
104 NGX_HTTP_SRV_CONF_OFFSET, | |
105 offsetof(ngx_http_v2_srv_conf_t, idle_timeout), | |
106 NULL }, | |
107 | |
108 { ngx_string("http2_chunk_size"), | |
109 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
110 ngx_conf_set_size_slot, | |
111 NGX_HTTP_LOC_CONF_OFFSET, | |
112 offsetof(ngx_http_v2_loc_conf_t, chunk_size), | |
113 &ngx_http_v2_chunk_size_post }, | |
114 | |
115 { ngx_string("spdy_recv_buffer_size"), | |
116 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
117 ngx_http_v2_spdy_deprecated, | |
118 NGX_HTTP_MAIN_CONF_OFFSET, | |
119 0, | |
120 NULL }, | |
121 | |
122 { ngx_string("spdy_pool_size"), | |
123 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
124 ngx_http_v2_spdy_deprecated, | |
125 NGX_HTTP_SRV_CONF_OFFSET, | |
126 0, | |
127 NULL }, | |
128 | |
129 { ngx_string("spdy_max_concurrent_streams"), | |
130 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
131 ngx_http_v2_spdy_deprecated, | |
132 NGX_HTTP_SRV_CONF_OFFSET, | |
133 0, | |
134 NULL }, | |
135 | |
136 { ngx_string("spdy_streams_index_size"), | |
137 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
138 ngx_http_v2_spdy_deprecated, | |
139 NGX_HTTP_SRV_CONF_OFFSET, | |
140 0, | |
141 NULL }, | |
142 | |
143 { ngx_string("spdy_recv_timeout"), | |
144 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
145 ngx_http_v2_spdy_deprecated, | |
146 NGX_HTTP_SRV_CONF_OFFSET, | |
147 0, | |
148 NULL }, | |
149 | |
150 { ngx_string("spdy_keepalive_timeout"), | |
151 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
152 ngx_http_v2_spdy_deprecated, | |
153 NGX_HTTP_SRV_CONF_OFFSET, | |
154 0, | |
155 NULL }, | |
156 | |
157 { ngx_string("spdy_headers_comp"), | |
158 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
159 ngx_http_v2_spdy_deprecated, | |
160 NGX_HTTP_SRV_CONF_OFFSET, | |
161 0, | |
162 NULL }, | |
163 | |
164 { ngx_string("spdy_chunk_size"), | |
165 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
166 ngx_http_v2_spdy_deprecated, | |
167 NGX_HTTP_LOC_CONF_OFFSET, | |
168 0, | |
169 NULL }, | |
170 | |
171 ngx_null_command | |
172 }; | |
173 | |
174 | |
175 static ngx_http_module_t ngx_http_v2_module_ctx = { | |
176 ngx_http_v2_add_variables, /* preconfiguration */ | |
177 NULL, /* postconfiguration */ | |
178 | |
179 ngx_http_v2_create_main_conf, /* create main configuration */ | |
180 ngx_http_v2_init_main_conf, /* init main configuration */ | |
181 | |
182 ngx_http_v2_create_srv_conf, /* create server configuration */ | |
183 ngx_http_v2_merge_srv_conf, /* merge server configuration */ | |
184 | |
185 ngx_http_v2_create_loc_conf, /* create location configuration */ | |
186 ngx_http_v2_merge_loc_conf /* merge location configuration */ | |
187 }; | |
188 | |
189 | |
190 ngx_module_t ngx_http_v2_module = { | |
191 NGX_MODULE_V1, | |
192 &ngx_http_v2_module_ctx, /* module context */ | |
193 ngx_http_v2_commands, /* module directives */ | |
194 NGX_HTTP_MODULE, /* module type */ | |
195 NULL, /* init master */ | |
196 ngx_http_v2_module_init, /* init module */ | |
197 NULL, /* init process */ | |
198 NULL, /* init thread */ | |
199 NULL, /* exit thread */ | |
200 NULL, /* exit process */ | |
201 NULL, /* exit master */ | |
202 NGX_MODULE_V1_PADDING | |
203 }; | |
204 | |
205 | |
206 static ngx_http_variable_t ngx_http_v2_vars[] = { | |
207 | |
208 { ngx_string("http2"), NULL, | |
209 ngx_http_v2_variable, 0, 0, 0 }, | |
210 | |
211 { ngx_null_string, NULL, NULL, 0, 0, 0 } | |
212 }; | |
213 | |
214 | |
215 static ngx_int_t | |
216 ngx_http_v2_add_variables(ngx_conf_t *cf) | |
217 { | |
218 ngx_http_variable_t *var, *v; | |
219 | |
220 for (v = ngx_http_v2_vars; v->name.len; v++) { | |
221 var = ngx_http_add_variable(cf, &v->name, v->flags); | |
222 if (var == NULL) { | |
223 return NGX_ERROR; | |
224 } | |
225 | |
226 var->get_handler = v->get_handler; | |
227 var->data = v->data; | |
228 } | |
229 | |
230 return NGX_OK; | |
231 } | |
232 | |
233 | |
234 static ngx_int_t | |
235 ngx_http_v2_variable(ngx_http_request_t *r, | |
236 ngx_http_variable_value_t *v, uintptr_t data) | |
237 { | |
238 | |
239 if (r->stream) { | |
240 #if (NGX_HTTP_SSL) | |
241 | |
242 if (r->connection->ssl) { | |
243 v->len = sizeof("h2") - 1; | |
244 v->valid = 1; | |
245 v->no_cacheable = 0; | |
246 v->not_found = 0; | |
247 v->data = (u_char *) "h2"; | |
248 | |
249 return NGX_OK; | |
250 } | |
251 | |
252 #endif | |
253 v->len = sizeof("h2c") - 1; | |
254 v->valid = 1; | |
255 v->no_cacheable = 0; | |
256 v->not_found = 0; | |
257 v->data = (u_char *) "h2c"; | |
258 | |
259 return NGX_OK; | |
260 } | |
261 | |
262 *v = ngx_http_variable_null_value; | |
263 | |
264 return NGX_OK; | |
265 } | |
266 | |
267 | |
268 static ngx_int_t | |
269 ngx_http_v2_module_init(ngx_cycle_t *cycle) | |
270 { | |
271 return NGX_OK; | |
272 } | |
273 | |
274 | |
275 static void * | |
276 ngx_http_v2_create_main_conf(ngx_conf_t *cf) | |
277 { | |
278 ngx_http_v2_main_conf_t *h2mcf; | |
279 | |
280 h2mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_main_conf_t)); | |
281 if (h2mcf == NULL) { | |
282 return NULL; | |
283 } | |
284 | |
285 h2mcf->recv_buffer_size = NGX_CONF_UNSET_SIZE; | |
286 | |
287 return h2mcf; | |
288 } | |
289 | |
290 | |
291 static char * | |
292 ngx_http_v2_init_main_conf(ngx_conf_t *cf, void *conf) | |
293 { | |
294 ngx_http_v2_main_conf_t *h2mcf = conf; | |
295 | |
296 ngx_conf_init_size_value(h2mcf->recv_buffer_size, 256 * 1024); | |
297 | |
298 return NGX_CONF_OK; | |
299 } | |
300 | |
301 | |
302 static void * | |
303 ngx_http_v2_create_srv_conf(ngx_conf_t *cf) | |
304 { | |
305 ngx_http_v2_srv_conf_t *h2scf; | |
306 | |
307 h2scf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_srv_conf_t)); | |
308 if (h2scf == NULL) { | |
309 return NULL; | |
310 } | |
311 | |
312 h2scf->pool_size = NGX_CONF_UNSET_SIZE; | |
313 | |
314 h2scf->concurrent_streams = NGX_CONF_UNSET_UINT; | |
315 | |
316 h2scf->max_field_size = NGX_CONF_UNSET_SIZE; | |
317 h2scf->max_header_size = NGX_CONF_UNSET_SIZE; | |
318 | |
319 h2scf->streams_index_mask = NGX_CONF_UNSET_UINT; | |
320 | |
321 h2scf->recv_timeout = NGX_CONF_UNSET_MSEC; | |
322 h2scf->idle_timeout = NGX_CONF_UNSET_MSEC; | |
323 | |
324 return h2scf; | |
325 } | |
326 | |
327 | |
328 static char * | |
329 ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) | |
330 { | |
331 ngx_http_v2_srv_conf_t *prev = parent; | |
332 ngx_http_v2_srv_conf_t *conf = child; | |
333 | |
334 ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096); | |
335 | |
336 ngx_conf_merge_uint_value(conf->concurrent_streams, | |
337 prev->concurrent_streams, 128); | |
338 | |
339 ngx_conf_merge_size_value(conf->max_field_size, prev->max_field_size, | |
340 4096); | |
341 ngx_conf_merge_size_value(conf->max_header_size, prev->max_header_size, | |
342 16384); | |
343 | |
344 ngx_conf_merge_uint_value(conf->streams_index_mask, | |
345 prev->streams_index_mask, 32 - 1); | |
346 | |
347 ngx_conf_merge_msec_value(conf->recv_timeout, | |
348 prev->recv_timeout, 30000); | |
349 ngx_conf_merge_msec_value(conf->idle_timeout, | |
350 prev->idle_timeout, 180000); | |
351 | |
352 return NGX_CONF_OK; | |
353 } | |
354 | |
355 | |
356 static void * | |
357 ngx_http_v2_create_loc_conf(ngx_conf_t *cf) | |
358 { | |
359 ngx_http_v2_loc_conf_t *h2lcf; | |
360 | |
361 h2lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_loc_conf_t)); | |
362 if (h2lcf == NULL) { | |
363 return NULL; | |
364 } | |
365 | |
366 h2lcf->chunk_size = NGX_CONF_UNSET_SIZE; | |
367 | |
368 return h2lcf; | |
369 } | |
370 | |
371 | |
372 static char * | |
373 ngx_http_v2_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
374 { | |
375 ngx_http_v2_loc_conf_t *prev = parent; | |
376 ngx_http_v2_loc_conf_t *conf = child; | |
377 | |
378 ngx_conf_merge_size_value(conf->chunk_size, prev->chunk_size, 8 * 1024); | |
379 | |
380 return NGX_CONF_OK; | |
381 } | |
382 | |
383 | |
384 static char * | |
385 ngx_http_v2_recv_buffer_size(ngx_conf_t *cf, void *post, void *data) | |
386 { | |
387 size_t *sp = data; | |
388 | |
389 if (*sp <= 2 * NGX_HTTP_V2_STATE_BUFFER_SIZE) { | |
390 return "value is too small"; | |
391 } | |
392 | |
393 return NGX_CONF_OK; | |
394 } | |
395 | |
396 | |
397 static char * | |
398 ngx_http_v2_pool_size(ngx_conf_t *cf, void *post, void *data) | |
399 { | |
400 size_t *sp = data; | |
401 | |
402 if (*sp < NGX_MIN_POOL_SIZE) { | |
403 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
404 "the pool size must be no less than %uz", | |
405 NGX_MIN_POOL_SIZE); | |
406 | |
407 return NGX_CONF_ERROR; | |
408 } | |
409 | |
410 if (*sp % NGX_POOL_ALIGNMENT) { | |
411 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
412 "the pool size must be a multiple of %uz", | |
413 NGX_POOL_ALIGNMENT); | |
414 | |
415 return NGX_CONF_ERROR; | |
416 } | |
417 | |
418 return NGX_CONF_OK; | |
419 } | |
420 | |
421 | |
422 static char * | |
423 ngx_http_v2_streams_index_mask(ngx_conf_t *cf, void *post, void *data) | |
424 { | |
425 ngx_uint_t *np = data; | |
426 | |
427 ngx_uint_t mask; | |
428 | |
429 mask = *np - 1; | |
430 | |
431 if (*np == 0 || (*np & mask)) { | |
432 return "must be a power of two"; | |
433 } | |
434 | |
435 *np = mask; | |
436 | |
437 return NGX_CONF_OK; | |
438 } | |
439 | |
440 | |
441 static char * | |
442 ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data) | |
443 { | |
444 size_t *sp = data; | |
445 | |
446 if (*sp == 0) { | |
447 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
448 "the http2 chunk size cannot be zero"); | |
449 | |
450 return NGX_CONF_ERROR; | |
451 } | |
452 | |
453 if (*sp > NGX_HTTP_V2_MAX_FRAME_SIZE) { | |
454 *sp = NGX_HTTP_V2_MAX_FRAME_SIZE; | |
455 } | |
456 | |
457 return NGX_CONF_OK; | |
458 } | |
459 | |
460 | |
461 static char * | |
462 ngx_http_v2_spdy_deprecated(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
463 { | |
464 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | |
465 "invalid directive \"%V\": ngx_http_spdy_module " | |
466 "was superseded by ngx_http_v2_module", &cmd->name); | |
467 | |
468 return NGX_CONF_OK; | |
469 } |