Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Nginx, Inc.
0004  * Copyright (C) Valentin V. Bartenev
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_http.h>
0011 #include <ngx_http_v2_module.h>
0012 
0013 
0014 static ngx_int_t ngx_http_v2_add_variables(ngx_conf_t *cf);
0015 
0016 static ngx_int_t ngx_http_v2_variable(ngx_http_request_t *r,
0017     ngx_http_variable_value_t *v, uintptr_t data);
0018 
0019 static ngx_int_t ngx_http_v2_module_init(ngx_cycle_t *cycle);
0020 
0021 static void *ngx_http_v2_create_main_conf(ngx_conf_t *cf);
0022 static char *ngx_http_v2_init_main_conf(ngx_conf_t *cf, void *conf);
0023 static void *ngx_http_v2_create_srv_conf(ngx_conf_t *cf);
0024 static char *ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent,
0025     void *child);
0026 static void *ngx_http_v2_create_loc_conf(ngx_conf_t *cf);
0027 static char *ngx_http_v2_merge_loc_conf(ngx_conf_t *cf, void *parent,
0028     void *child);
0029 
0030 static char *ngx_http_v2_recv_buffer_size(ngx_conf_t *cf, void *post,
0031     void *data);
0032 static char *ngx_http_v2_pool_size(ngx_conf_t *cf, void *post, void *data);
0033 static char *ngx_http_v2_preread_size(ngx_conf_t *cf, void *post, void *data);
0034 static char *ngx_http_v2_streams_index_mask(ngx_conf_t *cf, void *post,
0035     void *data);
0036 static char *ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data);
0037 static char *ngx_http_v2_spdy_deprecated(ngx_conf_t *cf, ngx_command_t *cmd,
0038     void *conf);
0039 
0040 
0041 static ngx_conf_post_t  ngx_http_v2_recv_buffer_size_post =
0042     { ngx_http_v2_recv_buffer_size };
0043 static ngx_conf_post_t  ngx_http_v2_pool_size_post =
0044     { ngx_http_v2_pool_size };
0045 static ngx_conf_post_t  ngx_http_v2_preread_size_post =
0046     { ngx_http_v2_preread_size };
0047 static ngx_conf_post_t  ngx_http_v2_streams_index_mask_post =
0048     { ngx_http_v2_streams_index_mask };
0049 static ngx_conf_post_t  ngx_http_v2_chunk_size_post =
0050     { ngx_http_v2_chunk_size };
0051 
0052 
0053 static ngx_command_t  ngx_http_v2_commands[] = {
0054 
0055     { ngx_string("http2_recv_buffer_size"),
0056       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
0057       ngx_conf_set_size_slot,
0058       NGX_HTTP_MAIN_CONF_OFFSET,
0059       offsetof(ngx_http_v2_main_conf_t, recv_buffer_size),
0060       &ngx_http_v2_recv_buffer_size_post },
0061 
0062     { ngx_string("http2_pool_size"),
0063       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0064       ngx_conf_set_size_slot,
0065       NGX_HTTP_SRV_CONF_OFFSET,
0066       offsetof(ngx_http_v2_srv_conf_t, pool_size),
0067       &ngx_http_v2_pool_size_post },
0068 
0069     { ngx_string("http2_max_concurrent_streams"),
0070       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0071       ngx_conf_set_num_slot,
0072       NGX_HTTP_SRV_CONF_OFFSET,
0073       offsetof(ngx_http_v2_srv_conf_t, concurrent_streams),
0074       NULL },
0075 
0076     { ngx_string("http2_max_requests"),
0077       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0078       ngx_conf_set_num_slot,
0079       NGX_HTTP_SRV_CONF_OFFSET,
0080       offsetof(ngx_http_v2_srv_conf_t, max_requests),
0081       NULL },
0082 
0083     { ngx_string("http2_max_field_size"),
0084       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0085       ngx_conf_set_size_slot,
0086       NGX_HTTP_SRV_CONF_OFFSET,
0087       offsetof(ngx_http_v2_srv_conf_t, max_field_size),
0088       NULL },
0089 
0090     { ngx_string("http2_max_header_size"),
0091       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0092       ngx_conf_set_size_slot,
0093       NGX_HTTP_SRV_CONF_OFFSET,
0094       offsetof(ngx_http_v2_srv_conf_t, max_header_size),
0095       NULL },
0096 
0097     { ngx_string("http2_body_preread_size"),
0098       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0099       ngx_conf_set_size_slot,
0100       NGX_HTTP_SRV_CONF_OFFSET,
0101       offsetof(ngx_http_v2_srv_conf_t, preread_size),
0102       &ngx_http_v2_preread_size_post },
0103 
0104     { ngx_string("http2_streams_index_size"),
0105       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0106       ngx_conf_set_num_slot,
0107       NGX_HTTP_SRV_CONF_OFFSET,
0108       offsetof(ngx_http_v2_srv_conf_t, streams_index_mask),
0109       &ngx_http_v2_streams_index_mask_post },
0110 
0111     { ngx_string("http2_recv_timeout"),
0112       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0113       ngx_conf_set_msec_slot,
0114       NGX_HTTP_SRV_CONF_OFFSET,
0115       offsetof(ngx_http_v2_srv_conf_t, recv_timeout),
0116       NULL },
0117 
0118     { ngx_string("http2_idle_timeout"),
0119       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0120       ngx_conf_set_msec_slot,
0121       NGX_HTTP_SRV_CONF_OFFSET,
0122       offsetof(ngx_http_v2_srv_conf_t, idle_timeout),
0123       NULL },
0124 
0125     { ngx_string("http2_chunk_size"),
0126       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0127       ngx_conf_set_size_slot,
0128       NGX_HTTP_LOC_CONF_OFFSET,
0129       offsetof(ngx_http_v2_loc_conf_t, chunk_size),
0130       &ngx_http_v2_chunk_size_post },
0131 
0132     { ngx_string("spdy_recv_buffer_size"),
0133       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
0134       ngx_http_v2_spdy_deprecated,
0135       NGX_HTTP_MAIN_CONF_OFFSET,
0136       0,
0137       NULL },
0138 
0139     { ngx_string("spdy_pool_size"),
0140       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0141       ngx_http_v2_spdy_deprecated,
0142       NGX_HTTP_SRV_CONF_OFFSET,
0143       0,
0144       NULL },
0145 
0146     { ngx_string("spdy_max_concurrent_streams"),
0147       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0148       ngx_http_v2_spdy_deprecated,
0149       NGX_HTTP_SRV_CONF_OFFSET,
0150       0,
0151       NULL },
0152 
0153     { ngx_string("spdy_streams_index_size"),
0154       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0155       ngx_http_v2_spdy_deprecated,
0156       NGX_HTTP_SRV_CONF_OFFSET,
0157       0,
0158       NULL },
0159 
0160     { ngx_string("spdy_recv_timeout"),
0161       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0162       ngx_http_v2_spdy_deprecated,
0163       NGX_HTTP_SRV_CONF_OFFSET,
0164       0,
0165       NULL },
0166 
0167     { ngx_string("spdy_keepalive_timeout"),
0168       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0169       ngx_http_v2_spdy_deprecated,
0170       NGX_HTTP_SRV_CONF_OFFSET,
0171       0,
0172       NULL },
0173 
0174     { ngx_string("spdy_headers_comp"),
0175       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0176       ngx_http_v2_spdy_deprecated,
0177       NGX_HTTP_SRV_CONF_OFFSET,
0178       0,
0179       NULL },
0180 
0181     { ngx_string("spdy_chunk_size"),
0182       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0183       ngx_http_v2_spdy_deprecated,
0184       NGX_HTTP_LOC_CONF_OFFSET,
0185       0,
0186       NULL },
0187 
0188       ngx_null_command
0189 };
0190 
0191 
0192 static ngx_http_module_t  ngx_http_v2_module_ctx = {
0193     ngx_http_v2_add_variables,             /* preconfiguration */
0194     NULL,                                  /* postconfiguration */
0195 
0196     ngx_http_v2_create_main_conf,          /* create main configuration */
0197     ngx_http_v2_init_main_conf,            /* init main configuration */
0198 
0199     ngx_http_v2_create_srv_conf,           /* create server configuration */
0200     ngx_http_v2_merge_srv_conf,            /* merge server configuration */
0201 
0202     ngx_http_v2_create_loc_conf,           /* create location configuration */
0203     ngx_http_v2_merge_loc_conf             /* merge location configuration */
0204 };
0205 
0206 
0207 ngx_module_t  ngx_http_v2_module = {
0208     NGX_MODULE_V1,
0209     &ngx_http_v2_module_ctx,               /* module context */
0210     ngx_http_v2_commands,                  /* module directives */
0211     NGX_HTTP_MODULE,                       /* module type */
0212     NULL,                                  /* init master */
0213     ngx_http_v2_module_init,               /* init module */
0214     NULL,                                  /* init process */
0215     NULL,                                  /* init thread */
0216     NULL,                                  /* exit thread */
0217     NULL,                                  /* exit process */
0218     NULL,                                  /* exit master */
0219     NGX_MODULE_V1_PADDING
0220 };
0221 
0222 
0223 static ngx_http_variable_t  ngx_http_v2_vars[] = {
0224 
0225     { ngx_string("http2"), NULL,
0226       ngx_http_v2_variable, 0, 0, 0 },
0227 
0228     { ngx_null_string, NULL, NULL, 0, 0, 0 }
0229 };
0230 
0231 
0232 static ngx_int_t
0233 ngx_http_v2_add_variables(ngx_conf_t *cf)
0234 {
0235     ngx_http_variable_t  *var, *v;
0236 
0237     for (v = ngx_http_v2_vars; v->name.len; v++) {
0238         var = ngx_http_add_variable(cf, &v->name, v->flags);
0239         if (var == NULL) {
0240             return NGX_ERROR;
0241         }
0242 
0243         var->get_handler = v->get_handler;
0244         var->data = v->data;
0245     }
0246 
0247     return NGX_OK;
0248 }
0249 
0250 
0251 static ngx_int_t
0252 ngx_http_v2_variable(ngx_http_request_t *r,
0253     ngx_http_variable_value_t *v, uintptr_t data)
0254 {
0255 
0256     if (r->stream) {
0257 #if (NGX_HTTP_SSL)
0258 
0259         if (r->connection->ssl) {
0260             v->len = sizeof("h2") - 1;
0261             v->valid = 1;
0262             v->no_cacheable = 0;
0263             v->not_found = 0;
0264             v->data = (u_char *) "h2";
0265 
0266             return NGX_OK;
0267         }
0268 
0269 #endif
0270         v->len = sizeof("h2c") - 1;
0271         v->valid = 1;
0272         v->no_cacheable = 0;
0273         v->not_found = 0;
0274         v->data = (u_char *) "h2c";
0275 
0276         return NGX_OK;
0277     }
0278 
0279     *v = ngx_http_variable_null_value;
0280 
0281     return NGX_OK;
0282 }
0283 
0284 
0285 static ngx_int_t
0286 ngx_http_v2_module_init(ngx_cycle_t *cycle)
0287 {
0288     return NGX_OK;
0289 }
0290 
0291 
0292 static void *
0293 ngx_http_v2_create_main_conf(ngx_conf_t *cf)
0294 {
0295     ngx_http_v2_main_conf_t  *h2mcf;
0296 
0297     h2mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_main_conf_t));
0298     if (h2mcf == NULL) {
0299         return NULL;
0300     }
0301 
0302     h2mcf->recv_buffer_size = NGX_CONF_UNSET_SIZE;
0303 
0304     return h2mcf;
0305 }
0306 
0307 
0308 static char *
0309 ngx_http_v2_init_main_conf(ngx_conf_t *cf, void *conf)
0310 {
0311     ngx_http_v2_main_conf_t *h2mcf = conf;
0312 
0313     ngx_conf_init_size_value(h2mcf->recv_buffer_size, 256 * 1024);
0314 
0315     return NGX_CONF_OK;
0316 }
0317 
0318 
0319 static void *
0320 ngx_http_v2_create_srv_conf(ngx_conf_t *cf)
0321 {
0322     ngx_http_v2_srv_conf_t  *h2scf;
0323 
0324     h2scf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_srv_conf_t));
0325     if (h2scf == NULL) {
0326         return NULL;
0327     }
0328 
0329     h2scf->pool_size = NGX_CONF_UNSET_SIZE;
0330 
0331     h2scf->concurrent_streams = NGX_CONF_UNSET_UINT;
0332     h2scf->max_requests = NGX_CONF_UNSET_UINT;
0333 
0334     h2scf->max_field_size = NGX_CONF_UNSET_SIZE;
0335     h2scf->max_header_size = NGX_CONF_UNSET_SIZE;
0336 
0337     h2scf->preread_size = NGX_CONF_UNSET_SIZE;
0338 
0339     h2scf->streams_index_mask = NGX_CONF_UNSET_UINT;
0340 
0341     h2scf->recv_timeout = NGX_CONF_UNSET_MSEC;
0342     h2scf->idle_timeout = NGX_CONF_UNSET_MSEC;
0343 
0344     return h2scf;
0345 }
0346 
0347 
0348 static char *
0349 ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
0350 {
0351     ngx_http_v2_srv_conf_t *prev = parent;
0352     ngx_http_v2_srv_conf_t *conf = child;
0353 
0354     ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096);
0355 
0356     ngx_conf_merge_uint_value(conf->concurrent_streams,
0357                               prev->concurrent_streams, 128);
0358     ngx_conf_merge_uint_value(conf->max_requests, prev->max_requests, 1000);
0359 
0360     ngx_conf_merge_size_value(conf->max_field_size, prev->max_field_size,
0361                               4096);
0362     ngx_conf_merge_size_value(conf->max_header_size, prev->max_header_size,
0363                               16384);
0364 
0365     ngx_conf_merge_size_value(conf->preread_size, prev->preread_size, 65536);
0366 
0367     ngx_conf_merge_uint_value(conf->streams_index_mask,
0368                               prev->streams_index_mask, 32 - 1);
0369 
0370     ngx_conf_merge_msec_value(conf->recv_timeout,
0371                               prev->recv_timeout, 30000);
0372     ngx_conf_merge_msec_value(conf->idle_timeout,
0373                               prev->idle_timeout, 180000);
0374 
0375     return NGX_CONF_OK;
0376 }
0377 
0378 
0379 static void *
0380 ngx_http_v2_create_loc_conf(ngx_conf_t *cf)
0381 {
0382     ngx_http_v2_loc_conf_t  *h2lcf;
0383 
0384     h2lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_loc_conf_t));
0385     if (h2lcf == NULL) {
0386         return NULL;
0387     }
0388 
0389     h2lcf->chunk_size = NGX_CONF_UNSET_SIZE;
0390 
0391     return h2lcf;
0392 }
0393 
0394 
0395 static char *
0396 ngx_http_v2_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
0397 {
0398     ngx_http_v2_loc_conf_t *prev = parent;
0399     ngx_http_v2_loc_conf_t *conf = child;
0400 
0401     ngx_conf_merge_size_value(conf->chunk_size, prev->chunk_size, 8 * 1024);
0402 
0403     return NGX_CONF_OK;
0404 }
0405 
0406 
0407 static char *
0408 ngx_http_v2_recv_buffer_size(ngx_conf_t *cf, void *post, void *data)
0409 {
0410     size_t *sp = data;
0411 
0412     if (*sp <= 2 * NGX_HTTP_V2_STATE_BUFFER_SIZE) {
0413         return "value is too small";
0414     }
0415 
0416     return NGX_CONF_OK;
0417 }
0418 
0419 
0420 static char *
0421 ngx_http_v2_pool_size(ngx_conf_t *cf, void *post, void *data)
0422 {
0423     size_t *sp = data;
0424 
0425     if (*sp < NGX_MIN_POOL_SIZE) {
0426         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0427                            "the pool size must be no less than %uz",
0428                            NGX_MIN_POOL_SIZE);
0429 
0430         return NGX_CONF_ERROR;
0431     }
0432 
0433     if (*sp % NGX_POOL_ALIGNMENT) {
0434         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0435                            "the pool size must be a multiple of %uz",
0436                            NGX_POOL_ALIGNMENT);
0437 
0438         return NGX_CONF_ERROR;
0439     }
0440 
0441     return NGX_CONF_OK;
0442 }
0443 
0444 
0445 static char *
0446 ngx_http_v2_preread_size(ngx_conf_t *cf, void *post, void *data)
0447 {
0448     size_t *sp = data;
0449 
0450     if (*sp > NGX_HTTP_V2_MAX_WINDOW) {
0451         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0452                            "the maximum body preread buffer size is %uz",
0453                            NGX_HTTP_V2_MAX_WINDOW);
0454 
0455         return NGX_CONF_ERROR;
0456     }
0457 
0458     return NGX_CONF_OK;
0459 }
0460 
0461 
0462 static char *
0463 ngx_http_v2_streams_index_mask(ngx_conf_t *cf, void *post, void *data)
0464 {
0465     ngx_uint_t *np = data;
0466 
0467     ngx_uint_t  mask;
0468 
0469     mask = *np - 1;
0470 
0471     if (*np == 0 || (*np & mask)) {
0472         return "must be a power of two";
0473     }
0474 
0475     *np = mask;
0476 
0477     return NGX_CONF_OK;
0478 }
0479 
0480 
0481 static char *
0482 ngx_http_v2_chunk_size(ngx_conf_t *cf, void *post, void *data)
0483 {
0484     size_t *sp = data;
0485 
0486     if (*sp == 0) {
0487         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0488                            "the http2 chunk size cannot be zero");
0489 
0490         return NGX_CONF_ERROR;
0491     }
0492 
0493     if (*sp > NGX_HTTP_V2_MAX_FRAME_SIZE) {
0494         *sp = NGX_HTTP_V2_MAX_FRAME_SIZE;
0495     }
0496 
0497     return NGX_CONF_OK;
0498 }
0499 
0500 
0501 static char *
0502 ngx_http_v2_spdy_deprecated(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0503 {
0504     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
0505                        "invalid directive \"%V\": ngx_http_spdy_module "
0506                        "was superseded by ngx_http_v2_module", &cmd->name);
0507 
0508     return NGX_CONF_OK;
0509 }