comparison src/http/v2/ngx_http_v2_module.c @ 9121:262c01782566

HTTP/2: removed server push (ticket #2432). Although it has better implementation status than HTTP/3 server push, it remains of limited use, with adoption numbers seen as negligible. Per IETF 102 materials, server push was used only in 0.04% of sessions. It was considered to be "difficult to use effectively" in RFC 9113. Its use is further limited by badly matching to fetch/cache/connection models in browsers, see related discussions linked from [1]. Server push was disabled in Chrome 106 [2]. The http2_push, http2_push_preload, and http2_max_concurrent_pushes directives are made obsolete. In particular, this essentially reverts 7201:641306096f5b and 7207:3d2b0b02bd3d. [1] https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/ [2] https://chromestatus.com/feature/6302414934114304
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 08 Jun 2023 16:56:46 +0400
parents 08ef02ad5c54
children ea1f29c2010c
comparison
equal deleted inserted replaced
9120:0aaa09927703 9121:262c01782566
24 static char *ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent, 24 static char *ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent,
25 void *child); 25 void *child);
26 static void *ngx_http_v2_create_loc_conf(ngx_conf_t *cf); 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, 27 static char *ngx_http_v2_merge_loc_conf(ngx_conf_t *cf, void *parent,
28 void *child); 28 void *child);
29
30 static char *ngx_http_v2_push(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
31 29
32 static char *ngx_http_v2_recv_buffer_size(ngx_conf_t *cf, void *post, 30 static char *ngx_http_v2_recv_buffer_size(ngx_conf_t *cf, void *post,
33 void *data); 31 void *data);
34 static char *ngx_http_v2_pool_size(ngx_conf_t *cf, void *post, void *data); 32 static char *ngx_http_v2_pool_size(ngx_conf_t *cf, void *post, void *data);
35 static char *ngx_http_v2_preread_size(ngx_conf_t *cf, void *post, void *data); 33 static char *ngx_http_v2_preread_size(ngx_conf_t *cf, void *post, void *data);
103 offsetof(ngx_http_v2_srv_conf_t, concurrent_streams), 101 offsetof(ngx_http_v2_srv_conf_t, concurrent_streams),
104 NULL }, 102 NULL },
105 103
106 { ngx_string("http2_max_concurrent_pushes"), 104 { ngx_string("http2_max_concurrent_pushes"),
107 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, 105 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
108 ngx_conf_set_num_slot, 106 ngx_http_v2_obsolete,
109 NGX_HTTP_SRV_CONF_OFFSET, 107 0,
110 offsetof(ngx_http_v2_srv_conf_t, concurrent_pushes), 108 0,
111 NULL }, 109 NULL },
112 110
113 { ngx_string("http2_max_requests"), 111 { ngx_string("http2_max_requests"),
114 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, 112 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
115 ngx_http_v2_obsolete, 113 ngx_http_v2_obsolete,
166 offsetof(ngx_http_v2_loc_conf_t, chunk_size), 164 offsetof(ngx_http_v2_loc_conf_t, chunk_size),
167 &ngx_http_v2_chunk_size_post }, 165 &ngx_http_v2_chunk_size_post },
168 166
169 { ngx_string("http2_push_preload"), 167 { ngx_string("http2_push_preload"),
170 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, 168 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
171 ngx_conf_set_flag_slot, 169 ngx_http_v2_obsolete,
172 NGX_HTTP_LOC_CONF_OFFSET, 170 0,
173 offsetof(ngx_http_v2_loc_conf_t, push_preload), 171 0,
174 NULL }, 172 NULL },
175 173
176 { ngx_string("http2_push"), 174 { ngx_string("http2_push"),
177 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 175 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
178 ngx_http_v2_push, 176 ngx_http_v2_obsolete,
179 NGX_HTTP_LOC_CONF_OFFSET, 177 0,
180 0, 178 0,
181 NULL }, 179 NULL },
182 180
183 ngx_null_command 181 ngx_null_command
184 }; 182 };
324 h2scf->enable = NGX_CONF_UNSET; 322 h2scf->enable = NGX_CONF_UNSET;
325 323
326 h2scf->pool_size = NGX_CONF_UNSET_SIZE; 324 h2scf->pool_size = NGX_CONF_UNSET_SIZE;
327 325
328 h2scf->concurrent_streams = NGX_CONF_UNSET_UINT; 326 h2scf->concurrent_streams = NGX_CONF_UNSET_UINT;
329 h2scf->concurrent_pushes = NGX_CONF_UNSET_UINT;
330 327
331 h2scf->preread_size = NGX_CONF_UNSET_SIZE; 328 h2scf->preread_size = NGX_CONF_UNSET_SIZE;
332 329
333 h2scf->streams_index_mask = NGX_CONF_UNSET_UINT; 330 h2scf->streams_index_mask = NGX_CONF_UNSET_UINT;
334 331
346 343
347 ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096); 344 ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096);
348 345
349 ngx_conf_merge_uint_value(conf->concurrent_streams, 346 ngx_conf_merge_uint_value(conf->concurrent_streams,
350 prev->concurrent_streams, 128); 347 prev->concurrent_streams, 128);
351 ngx_conf_merge_uint_value(conf->concurrent_pushes,
352 prev->concurrent_pushes, 10);
353 348
354 ngx_conf_merge_size_value(conf->preread_size, prev->preread_size, 65536); 349 ngx_conf_merge_size_value(conf->preread_size, prev->preread_size, 65536);
355 350
356 ngx_conf_merge_uint_value(conf->streams_index_mask, 351 ngx_conf_merge_uint_value(conf->streams_index_mask,
357 prev->streams_index_mask, 32 - 1); 352 prev->streams_index_mask, 32 - 1);
368 h2lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_loc_conf_t)); 363 h2lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v2_loc_conf_t));
369 if (h2lcf == NULL) { 364 if (h2lcf == NULL) {
370 return NULL; 365 return NULL;
371 } 366 }
372 367
373 /*
374 * set by ngx_pcalloc():
375 *
376 * h2lcf->pushes = NULL;
377 */
378
379 h2lcf->chunk_size = NGX_CONF_UNSET_SIZE; 368 h2lcf->chunk_size = NGX_CONF_UNSET_SIZE;
380
381 h2lcf->push_preload = NGX_CONF_UNSET;
382 h2lcf->push = NGX_CONF_UNSET;
383 369
384 return h2lcf; 370 return h2lcf;
385 } 371 }
386 372
387 373
390 { 376 {
391 ngx_http_v2_loc_conf_t *prev = parent; 377 ngx_http_v2_loc_conf_t *prev = parent;
392 ngx_http_v2_loc_conf_t *conf = child; 378 ngx_http_v2_loc_conf_t *conf = child;
393 379
394 ngx_conf_merge_size_value(conf->chunk_size, prev->chunk_size, 8 * 1024); 380 ngx_conf_merge_size_value(conf->chunk_size, prev->chunk_size, 8 * 1024);
395
396 ngx_conf_merge_value(conf->push, prev->push, 1);
397
398 if (conf->push && conf->pushes == NULL) {
399 conf->pushes = prev->pushes;
400 }
401
402 ngx_conf_merge_value(conf->push_preload, prev->push_preload, 0);
403
404 return NGX_CONF_OK;
405 }
406
407
408 static char *
409 ngx_http_v2_push(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
410 {
411 ngx_http_v2_loc_conf_t *h2lcf = conf;
412
413 ngx_str_t *value;
414 ngx_http_complex_value_t *cv;
415 ngx_http_compile_complex_value_t ccv;
416
417 value = cf->args->elts;
418
419 if (ngx_strcmp(value[1].data, "off") == 0) {
420
421 if (h2lcf->pushes) {
422 return "\"off\" parameter cannot be used with URI";
423 }
424
425 if (h2lcf->push == 0) {
426 return "is duplicate";
427 }
428
429 h2lcf->push = 0;
430 return NGX_CONF_OK;
431 }
432
433 if (h2lcf->push == 0) {
434 return "URI cannot be used with \"off\" parameter";
435 }
436
437 h2lcf->push = 1;
438
439 if (h2lcf->pushes == NULL) {
440 h2lcf->pushes = ngx_array_create(cf->pool, 1,
441 sizeof(ngx_http_complex_value_t));
442 if (h2lcf->pushes == NULL) {
443 return NGX_CONF_ERROR;
444 }
445 }
446
447 cv = ngx_array_push(h2lcf->pushes);
448 if (cv == NULL) {
449 return NGX_CONF_ERROR;
450 }
451
452 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
453
454 ccv.cf = cf;
455 ccv.value = &value[1];
456 ccv.complex_value = cv;
457
458 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
459 return NGX_CONF_ERROR;
460 }
461 381
462 return NGX_CONF_OK; 382 return NGX_CONF_OK;
463 } 383 }
464 384
465 385
560 static char * 480 static char *
561 ngx_http_v2_obsolete(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 481 ngx_http_v2_obsolete(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
562 { 482 {
563 ngx_conf_deprecated_t *d = cmd->post; 483 ngx_conf_deprecated_t *d = cmd->post;
564 484
565 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, 485 if (d) {
566 "the \"%s\" directive is obsolete, " 486 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
567 "use the \"%s\" directive instead", 487 "the \"%s\" directive is obsolete, "
568 d->old_name, d->new_name); 488 "use the \"%s\" directive instead",
569 489 d->old_name, d->new_name);
570 return NGX_CONF_OK; 490
571 } 491 } else {
492 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
493 "the \"%V\" directive is obsolete, ignored",
494 &cmd->name);
495 }
496
497 return NGX_CONF_OK;
498 }