details: https://hg.nginx.org/nginx/rev/262c01782566 branches: changeset: 9121:262c01782566 user: Sergey Kandaurov <pluk...@nginx.com> date: Thu Jun 08 16:56:46 2023 +0400 description: 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 diffstat: auto/modules | 2 - src/http/v2/ngx_http_v2.c | 320 ++-------------- src/http/v2/ngx_http_v2.h | 14 - src/http/v2/ngx_http_v2_filter_module.c | 622 +------------------------------- src/http/v2/ngx_http_v2_module.c | 111 +---- src/http/v2/ngx_http_v2_module.h | 5 - 6 files changed, 59 insertions(+), 1015 deletions(-) diffs (truncated from 1466 to 1000 lines): diff -r 0aaa09927703 -r 262c01782566 auto/modules --- a/auto/modules Thu Jun 08 14:49:27 2023 +0400 +++ b/auto/modules Thu Jun 08 16:56:46 2023 +0400 @@ -423,7 +423,6 @@ if [ $HTTP = YES ]; then if [ $HTTP_V2 = YES ]; then have=NGX_HTTP_V2 . auto/have - have=NGX_HTTP_HEADERS . auto/have ngx_module_name=ngx_http_v2_module ngx_module_incs=src/http/v2 @@ -444,7 +443,6 @@ if [ $HTTP = YES ]; then HTTP_SSL=YES have=NGX_HTTP_V3 . auto/have - have=NGX_HTTP_HEADERS . auto/have ngx_module_name=ngx_http_v3_module ngx_module_incs=src/http/v3 diff -r 0aaa09927703 -r 262c01782566 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Jun 08 14:49:27 2023 +0400 +++ b/src/http/v2/ngx_http_v2.c Thu Jun 08 16:56:46 2023 +0400 @@ -11,14 +11,6 @@ #include <ngx_http_v2_module.h> -typedef struct { - ngx_str_t name; - ngx_uint_t offset; - ngx_uint_t hash; - ngx_http_header_t *hh; -} ngx_http_v2_parse_header_t; - - /* errors */ #define NGX_HTTP_V2_NO_ERROR 0x0 #define NGX_HTTP_V2_PROTOCOL_ERROR 0x1 @@ -126,7 +118,7 @@ static ngx_int_t ngx_http_v2_parse_int(n u_char **pos, u_char *end, ngx_uint_t prefix); static ngx_http_v2_stream_t *ngx_http_v2_create_stream( - ngx_http_v2_connection_t *h2c, ngx_uint_t push); + ngx_http_v2_connection_t *h2c); static ngx_http_v2_node_t *ngx_http_v2_get_node_by_id( ngx_http_v2_connection_t *h2c, ngx_uint_t sid, ngx_uint_t alloc); static ngx_http_v2_node_t *ngx_http_v2_get_closed_node( @@ -162,14 +154,11 @@ static ngx_int_t ngx_http_v2_parse_schem ngx_str_t *value); static ngx_int_t ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value); -static ngx_int_t ngx_http_v2_parse_header(ngx_http_request_t *r, - ngx_http_v2_parse_header_t *header, ngx_str_t *value); static ngx_int_t ngx_http_v2_construct_request_line(ngx_http_request_t *r); static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r, ngx_http_v2_header_t *header); static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r); static void ngx_http_v2_run_request(ngx_http_request_t *r); -static void ngx_http_v2_run_request_handler(ngx_event_t *ev); static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r, u_char *pos, size_t size, ngx_uint_t last, ngx_uint_t flush); static ngx_int_t ngx_http_v2_filter_request_body(ngx_http_request_t *r); @@ -210,23 +199,6 @@ static ngx_http_v2_handler_pt ngx_http_v (sizeof(ngx_http_v2_frame_states) / sizeof(ngx_http_v2_handler_pt)) -static ngx_http_v2_parse_header_t ngx_http_v2_parse_headers[] = { - { ngx_string("host"), - offsetof(ngx_http_headers_in_t, host), 0, NULL }, - - { ngx_string("accept-encoding"), - offsetof(ngx_http_headers_in_t, accept_encoding), 0, NULL }, - - { ngx_string("accept-language"), - offsetof(ngx_http_headers_in_t, accept_language), 0, NULL }, - - { ngx_string("user-agent"), - offsetof(ngx_http_headers_in_t, user_agent), 0, NULL }, - - { ngx_null_string, 0, 0, NULL } -}; - - void ngx_http_v2_init(ngx_event_t *rev) { @@ -275,7 +247,6 @@ ngx_http_v2_init(ngx_event_t *rev) h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module); - h2c->concurrent_pushes = h2scf->concurrent_pushes; h2c->priority_limit = ngx_max(h2scf->concurrent_streams, 100); h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log); @@ -385,7 +356,7 @@ ngx_http_v2_read_handler(ngx_event_t *re return; } - if (!h2c->processing && !h2c->pushing) { + if (!h2c->processing) { ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR); return; } @@ -428,9 +399,7 @@ ngx_http_v2_read_handler(ngx_event_t *re break; } - if (n == 0 - && (h2c->state.incomplete || h2c->processing || h2c->pushing)) - { + if (n == 0 && (h2c->state.incomplete || h2c->processing)) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client prematurely closed connection"); } @@ -653,7 +622,7 @@ ngx_http_v2_handle_connection(ngx_http_v ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; - if (h2c->last_out || h2c->processing || h2c->pushing) { + if (h2c->last_out || h2c->processing) { return; } @@ -1338,7 +1307,7 @@ ngx_http_v2_state_headers(ngx_http_v2_co h2c->closed_nodes--; } - stream = ngx_http_v2_create_stream(h2c, 0); + stream = ngx_http_v2_create_stream(h2c); if (stream == NULL) { return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); } @@ -2127,11 +2096,6 @@ ngx_http_v2_state_rst_stream(ngx_http_v2 "client canceled stream %ui", h2c->state.sid); break; - case NGX_HTTP_V2_REFUSED_STREAM: - ngx_log_error(NGX_LOG_INFO, fc->log, 0, - "client refused stream %ui", h2c->state.sid); - break; - case NGX_HTTP_V2_INTERNAL_ERROR: ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client terminated stream %ui due to internal error", @@ -2199,7 +2163,6 @@ ngx_http_v2_state_settings_params(ngx_ht { ssize_t window_delta; ngx_uint_t id, value; - ngx_http_v2_srv_conf_t *h2scf; ngx_http_v2_out_frame_t *frame; window_delta = 0; @@ -2261,14 +2224,6 @@ ngx_http_v2_state_settings_params(ngx_ht NGX_HTTP_V2_PROTOCOL_ERROR); } - h2c->push_disabled = !value; - break; - - case NGX_HTTP_V2_MAX_STREAMS_SETTING: - h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, - ngx_http_v2_module); - - h2c->concurrent_pushes = ngx_min(value, h2scf->concurrent_pushes); break; case NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING: @@ -2723,163 +2678,6 @@ ngx_http_v2_parse_int(ngx_http_v2_connec } -ngx_http_v2_stream_t * -ngx_http_v2_push_stream(ngx_http_v2_stream_t *parent, ngx_str_t *path) -{ - ngx_int_t rc; - ngx_str_t value; - ngx_pool_t *pool; - ngx_uint_t index; - ngx_table_elt_t **h; - ngx_connection_t *fc; - ngx_http_request_t *r; - ngx_http_v2_node_t *node; - ngx_http_v2_stream_t *stream; - ngx_http_v2_srv_conf_t *h2scf; - ngx_http_v2_connection_t *h2c; - ngx_http_v2_parse_header_t *header; - - h2c = parent->connection; - - pool = ngx_create_pool(1024, h2c->connection->log); - if (pool == NULL) { - goto rst_stream; - } - - node = ngx_http_v2_get_node_by_id(h2c, h2c->last_push, 1); - - if (node == NULL) { - ngx_destroy_pool(pool); - goto rst_stream; - } - - stream = ngx_http_v2_create_stream(h2c, 1); - if (stream == NULL) { - - if (node->parent == NULL) { - h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, - ngx_http_v2_module); - - index = ngx_http_v2_index(h2scf, h2c->last_push); - h2c->streams_index[index] = node->index; - - ngx_queue_insert_tail(&h2c->closed, &node->reuse); - h2c->closed_nodes++; - } - - ngx_destroy_pool(pool); - goto rst_stream; - } - - if (node->parent) { - ngx_queue_remove(&node->reuse); - h2c->closed_nodes--; - } - - stream->pool = pool; - - r = stream->request; - fc = r->connection; - - stream->in_closed = 1; - stream->node = node; - - node->stream = stream; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 push stream sid:%ui " - "depends on %ui excl:0 weight:16", - h2c->last_push, parent->node->id); - - node->weight = NGX_HTTP_V2_DEFAULT_WEIGHT; - ngx_http_v2_set_dependency(h2c, node, parent->node->id, 0); - - r->method_name = ngx_http_core_get_method; - r->method = NGX_HTTP_GET; - - r->schema.data = ngx_pstrdup(pool, &parent->request->schema); - if (r->schema.data == NULL) { - goto close; - } - - r->schema.len = parent->request->schema.len; - - value.data = ngx_pstrdup(pool, path); - if (value.data == NULL) { - goto close; - } - - value.len = path->len; - - rc = ngx_http_v2_parse_path(r, &value); - - if (rc != NGX_OK) { - goto error; - } - - for (header = ngx_http_v2_parse_headers; header->name.len; header++) { - h = (ngx_table_elt_t **) - ((char *) &parent->request->headers_in + header->offset); - - if (*h == NULL) { - continue; - } - - value.len = (*h)->value.len; - - value.data = ngx_pnalloc(pool, value.len + 1); - if (value.data == NULL) { - goto close; - } - - ngx_memcpy(value.data, (*h)->value.data, value.len); - value.data[value.len] = '\0'; - - rc = ngx_http_v2_parse_header(r, header, &value); - - if (rc != NGX_OK) { - goto error; - } - } - - fc->write->handler = ngx_http_v2_run_request_handler; - ngx_post_event(fc->write, &ngx_posted_events); - - return stream; - -error: - - if (rc == NGX_ABORT) { - /* header handler has already finalized request */ - ngx_http_run_posted_requests(fc); - return NULL; - } - - if (rc == NGX_DECLINED) { - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); - ngx_http_run_posted_requests(fc); - return NULL; - } - -close: - - ngx_http_v2_close_stream(stream, NGX_HTTP_INTERNAL_SERVER_ERROR); - - return NULL; - -rst_stream: - - if (ngx_http_v2_send_rst_stream(h2c, h2c->last_push, - NGX_HTTP_INTERNAL_SERVER_ERROR) - != NGX_OK) - { - h2c->connection->error = 1; - } - - return NULL; -} - - static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c) { @@ -3151,7 +2949,7 @@ ngx_http_v2_frame_handler(ngx_http_v2_co static ngx_http_v2_stream_t * -ngx_http_v2_create_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t push) +ngx_http_v2_create_stream(ngx_http_v2_connection_t *h2c) { ngx_log_t *log; ngx_event_t *rev, *wev; @@ -3206,13 +3004,7 @@ ngx_http_v2_create_stream(ngx_http_v2_co ngx_memcpy(log, h2c->connection->log, sizeof(ngx_log_t)); log->data = ctx; - - if (push) { - log->action = "processing pushed request headers"; - - } else { - log->action = "reading client request headers"; - } + log->action = "reading client request headers"; ngx_memzero(rev, sizeof(ngx_event_t)); @@ -3284,12 +3076,7 @@ ngx_http_v2_create_stream(ngx_http_v2_co stream->send_window = h2c->init_window; stream->recv_window = h2scf->preread_size; - if (push) { - h2c->pushing++; - - } else { - h2c->processing++; - } + h2c->processing++; h2c->priority_limit += h2scf->concurrent_streams; @@ -3712,45 +3499,41 @@ ngx_http_v2_parse_scheme(ngx_http_reques static ngx_int_t ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value) { - return ngx_http_v2_parse_header(r, &ngx_http_v2_parse_headers[0], value); -} - - -static ngx_int_t -ngx_http_v2_parse_header(ngx_http_request_t *r, - ngx_http_v2_parse_header_t *header, ngx_str_t *value) -{ ngx_table_elt_t *h; + ngx_http_header_t *hh; ngx_http_core_main_conf_t *cmcf; + static ngx_str_t host = ngx_string("host"); + h = ngx_list_push(&r->headers_in.headers); if (h == NULL) { return NGX_ERROR; } - h->key.len = header->name.len; - h->key.data = header->name.data; - h->lowcase_key = header->name.data; - - if (header->hh == NULL) { - header->hash = ngx_hash_key(header->name.data, header->name.len); - - cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - - header->hh = ngx_hash_find(&cmcf->headers_in_hash, header->hash, - h->lowcase_key, h->key.len); - if (header->hh == NULL) { - return NGX_ERROR; - } - } - - h->hash = header->hash; + h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't'); + + h->key.len = host.len; + h->key.data = host.data; h->value.len = value->len; h->value.data = value->data; - if (header->hh->handler(r, h, header->hh->offset) != NGX_OK) { - /* header handler has already finalized request */ + h->lowcase_key = host.data; + + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, + h->lowcase_key, h->key.len); + + if (hh == NULL) { + return NGX_ERROR; + } + + if (hh->handler(r, h, hh->offset) != NGX_OK) { + /* + * request has been finalized already + * in ngx_http_process_host() + */ return NGX_ABORT; } @@ -3993,22 +3776,6 @@ failed: } -static void -ngx_http_v2_run_request_handler(ngx_event_t *ev) -{ - ngx_connection_t *fc; - ngx_http_request_t *r; - - fc = ev->data; - r = fc->data; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, - "http2 run request handler"); - - ngx_http_v2_run_request(r); -} - - ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r) { @@ -4612,7 +4379,6 @@ void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc) { ngx_pool_t *pool; - ngx_uint_t push; ngx_event_t *ev; ngx_connection_t *fc; ngx_http_v2_node_t *node; @@ -4621,10 +4387,9 @@ ngx_http_v2_close_stream(ngx_http_v2_str h2c = stream->connection; node = stream->node; - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 close stream %ui, queued %ui, " - "processing %ui, pushing %ui", - node->id, stream->queued, h2c->processing, h2c->pushing); + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "http2 close stream %ui, queued %ui, processing %ui", + node->id, stream->queued, h2c->processing); fc = stream->request->connection; @@ -4659,8 +4424,6 @@ ngx_http_v2_close_stream(ngx_http_v2_str h2c->state.stream = NULL; } - push = stream->node->id % 2 == 0; - node->stream = NULL; ngx_queue_insert_tail(&h2c->closed, &node->reuse); @@ -4710,14 +4473,9 @@ ngx_http_v2_close_stream(ngx_http_v2_str fc->data = h2c->free_fake_connections; h2c->free_fake_connections = fc; - if (push) { - h2c->pushing--; - - } else { - h2c->processing--; - } - - if (h2c->processing || h2c->pushing || h2c->blocked) { + h2c->processing--; + + if (h2c->processing || h2c->blocked) { return; } @@ -4893,7 +4651,7 @@ ngx_http_v2_finalize_connection(ngx_http } } - if (!h2c->processing && !h2c->pushing) { + if (!h2c->processing) { goto done; } @@ -4941,7 +4699,7 @@ ngx_http_v2_finalize_connection(ngx_http h2c->blocked = 0; - if (h2c->processing || h2c->pushing) { + if (h2c->processing) { c->error = 1; return; } diff -r 0aaa09927703 -r 262c01782566 src/http/v2/ngx_http_v2.h --- a/src/http/v2/ngx_http_v2.h Thu Jun 08 14:49:27 2023 +0400 +++ b/src/http/v2/ngx_http_v2.h Thu Jun 08 16:56:46 2023 +0400 @@ -24,8 +24,6 @@ #define NGX_HTTP_V2_MAX_FIELD \ (127 + (1 << (NGX_HTTP_V2_INT_OCTETS - 1) * 7) - 1) -#define NGX_HTTP_V2_STREAM_ID_SIZE 4 - #define NGX_HTTP_V2_FRAME_HEADER_SIZE 9 /* frame types */ @@ -67,7 +65,6 @@ typedef struct { ngx_flag_t enable; size_t pool_size; ngx_uint_t concurrent_streams; - ngx_uint_t concurrent_pushes; size_t preread_size; ngx_uint_t streams_index_mask; } ngx_http_v2_srv_conf_t; @@ -136,9 +133,6 @@ struct ngx_http_v2_connection_s { ngx_uint_t idle; ngx_uint_t priority_limit; - ngx_uint_t pushing; - ngx_uint_t concurrent_pushes; - size_t send_window; size_t recv_window; size_t init_window; @@ -165,7 +159,6 @@ struct ngx_http_v2_connection_s { ngx_uint_t closed_nodes; ngx_uint_t last_sid; - ngx_uint_t last_push; time_t lingering_time; @@ -173,7 +166,6 @@ struct ngx_http_v2_connection_s { unsigned table_update:1; unsigned blocked:1; unsigned goaway:1; - unsigned push_disabled:1; }; @@ -303,9 +295,6 @@ void ngx_http_v2_init(ngx_event_t *rev); ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r); ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r); -ngx_http_v2_stream_t *ngx_http_v2_push_stream(ngx_http_v2_stream_t *parent, - ngx_str_t *path); - void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc); ngx_int_t ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c); @@ -407,15 +396,12 @@ ngx_int_t ngx_http_v2_table_size(ngx_htt #define NGX_HTTP_V2_STATUS_404_INDEX 13 #define NGX_HTTP_V2_STATUS_500_INDEX 14 -#define NGX_HTTP_V2_ACCEPT_ENCODING_INDEX 16 -#define NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX 17 #define NGX_HTTP_V2_CONTENT_LENGTH_INDEX 28 #define NGX_HTTP_V2_CONTENT_TYPE_INDEX 31 #define NGX_HTTP_V2_DATE_INDEX 33 #define NGX_HTTP_V2_LAST_MODIFIED_INDEX 44 #define NGX_HTTP_V2_LOCATION_INDEX 46 #define NGX_HTTP_V2_SERVER_INDEX 54 -#define NGX_HTTP_V2_USER_AGENT_INDEX 58 #define NGX_HTTP_V2_VARY_INDEX 59 #define NGX_HTTP_V2_PREFACE_START "PRI * HTTP/2.0\r\n" diff -r 0aaa09927703 -r 262c01782566 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Thu Jun 08 14:49:27 2023 +0400 +++ b/src/http/v2/ngx_http_v2_filter_module.c Thu Jun 08 16:56:46 2023 +0400 @@ -27,39 +27,8 @@ #define NGX_HTTP_V2_NO_TRAILERS (ngx_http_v2_out_frame_t *) -1 -typedef struct { - ngx_str_t name; - u_char index; - ngx_uint_t offset; -} ngx_http_v2_push_header_t; - - -static ngx_http_v2_push_header_t ngx_http_v2_push_headers[] = { - { ngx_string(":authority"), NGX_HTTP_V2_AUTHORITY_INDEX, - offsetof(ngx_http_headers_in_t, host) }, - - { ngx_string("accept-encoding"), NGX_HTTP_V2_ACCEPT_ENCODING_INDEX, - offsetof(ngx_http_headers_in_t, accept_encoding) }, - - { ngx_string("accept-language"), NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX, - offsetof(ngx_http_headers_in_t, accept_language) }, - - { ngx_string("user-agent"), NGX_HTTP_V2_USER_AGENT_INDEX, - offsetof(ngx_http_headers_in_t, user_agent) }, -}; - -#define NGX_HTTP_V2_PUSH_HEADERS \ - (sizeof(ngx_http_v2_push_headers) / sizeof(ngx_http_v2_push_header_t)) - - -static ngx_int_t ngx_http_v2_push_resources(ngx_http_request_t *r); -static ngx_int_t ngx_http_v2_push_resource(ngx_http_request_t *r, - ngx_str_t *path, ngx_str_t *binary); - static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame( ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin); -static ngx_http_v2_out_frame_t *ngx_http_v2_create_push_frame( - ngx_http_request_t *r, u_char *pos, u_char *end); static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame( ngx_http_request_t *r); @@ -82,8 +51,6 @@ static ngx_inline ngx_int_t ngx_http_v2_ static ngx_int_t ngx_http_v2_headers_frame_handler( ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); -static ngx_int_t ngx_http_v2_push_frame_handler( - ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); static ngx_int_t ngx_http_v2_data_frame_handler( ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame); static ngx_inline void ngx_http_v2_handle_frame( @@ -244,15 +211,6 @@ ngx_http_v2_header_filter(ngx_http_reque h2c = stream->connection; - if (!h2c->push_disabled && !h2c->goaway - && stream->node->id % 2 == 1 - && r->method != NGX_HTTP_HEAD) - { - if (ngx_http_v2_push_resources(r) != NGX_OK) { - return NGX_ERROR; - } - } - len = h2c->table_update ? 1 : 0; len += status ? 1 : 1 + ngx_http_v2_literal_size("418"); @@ -653,7 +611,7 @@ ngx_http_v2_header_filter(ngx_http_reque ngx_http_v2_queue_blocked_frame(h2c, frame); - stream->queued++; + stream->queued = 1; cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { @@ -671,409 +629,6 @@ ngx_http_v2_header_filter(ngx_http_reque } -static ngx_int_t -ngx_http_v2_push_resources(ngx_http_request_t *r) -{ - u_char *start, *end, *last; - ngx_int_t rc; - ngx_str_t path; - ngx_uint_t i, push; - ngx_table_elt_t *h; - ngx_http_v2_loc_conf_t *h2lcf; - ngx_http_complex_value_t *pushes; - ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS]; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 push resources"); - - ngx_memzero(binary, NGX_HTTP_V2_PUSH_HEADERS * sizeof(ngx_str_t)); - - h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module); - - if (h2lcf->pushes) { - pushes = h2lcf->pushes->elts; - - for (i = 0; i < h2lcf->pushes->nelts; i++) { - - if (ngx_http_complex_value(r, &pushes[i], &path) != NGX_OK) { - return NGX_ERROR; - } - - if (path.len == 0) { - continue; - } - - if (path.len == 3 && ngx_strncmp(path.data, "off", 3) == 0) { - continue; - } - - rc = ngx_http_v2_push_resource(r, &path, binary); - - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - if (rc == NGX_ABORT) { - return NGX_OK; - } - - /* NGX_OK, NGX_DECLINED */ - } - } - - if (!h2lcf->push_preload) { - return NGX_OK; - } - - for (h = r->headers_out.link; h; h = h->next) { - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 parse link: \"%V\"", &h->value); - - start = h->value.data; - end = h->value.data + h->value.len; - - next_link: - - while (start < end && *start == ' ') { start++; } - - if (start == end || *start++ != '<') { - continue; - } - - while (start < end && *start == ' ') { start++; } - - for (last = start; last < end && *last != '>'; last++) { - /* void */ - } - - if (last == start || last == end) { - continue; - } - - path.len = last - start; - path.data = start; - - start = last + 1; - - while (start < end && *start == ' ') { start++; } - - if (start == end) { - continue; - } - - if (*start == ',') { - start++; - goto next_link; - } - - if (*start++ != ';') { - continue; - } - - last = ngx_strlchr(start, end, ','); - - if (last == NULL) { - last = end; - } - - push = 0; - - for ( ;; ) { - - while (start < last && *start == ' ') { start++; } - - if (last - start >= 6 - && ngx_strncasecmp(start, (u_char *) "nopush", 6) == 0) - { - start += 6; - - if (start == last || *start == ' ' || *start == ';') { - push = 0; - break; - } - - goto next_param; - } - - if (last - start >= 11 - && ngx_strncasecmp(start, (u_char *) "rel=preload", 11) == 0) - { - start += 11; - - if (start == last || *start == ' ' || *start == ';') { - push = 1; - } - - goto next_param; - } - - if (last - start >= 4 - && ngx_strncasecmp(start, (u_char *) "rel=", 4) == 0) - { - start += 4; - - while (start < last && *start == ' ') { start++; } - - if (start == last || *start++ != '"') { - goto next_param; - } - - for ( ;; ) { - - while (start < last && *start == ' ') { start++; } - - if (last - start >= 7 - && ngx_strncasecmp(start, (u_char *) "preload", 7) == 0) - { - start += 7; - - if (start < last && (*start == ' ' || *start == '"')) { - push = 1; - break; - } - } - - while (start < last && *start != ' ' && *start != '"') { - start++; - } - - if (start == last) { - break; - } - - if (*start == '"') { - break; - } - - start++; - } - } - - next_param: - - start = ngx_strlchr(start, last, ';'); - - if (start == NULL) { - break; - } - - start++; - } - - if (push) { - while (path.len && path.data[path.len - 1] == ' ') { - path.len--; - } - } - - if (push && path.len - && !(path.len > 1 && path.data[0] == '/' && path.data[1] == '/')) - { - rc = ngx_http_v2_push_resource(r, &path, binary); - - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - if (rc == NGX_ABORT) { - return NGX_OK; - } - - /* NGX_OK, NGX_DECLINED */ - } - - if (last < end) { - start = last + 1; - goto next_link; - } - } - - return NGX_OK; -} - - -static ngx_int_t -ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path, - ngx_str_t *binary) -{ - u_char *start, *pos, *tmp; - size_t len; - ngx_str_t *value; - ngx_uint_t i; - ngx_table_elt_t **h; - ngx_connection_t *fc; - ngx_http_v2_stream_t *stream; - ngx_http_v2_out_frame_t *frame; - ngx_http_v2_connection_t *h2c; - ngx_http_v2_push_header_t *ph; - - fc = r->connection; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, "http2 push resource"); - - stream = r->stream; - h2c = stream->connection; - - if (!ngx_path_separator(path->data[0])) { - ngx_log_error(NGX_LOG_WARN, fc->log, 0, - "non-absolute path \"%V\" not pushed", path); - return NGX_DECLINED; - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "http2 pushing:%ui limit:%ui", - h2c->pushing, h2c->concurrent_pushes); - - if (h2c->pushing >= h2c->concurrent_pushes) { - return NGX_ABORT; - } - - if (h2c->last_push == 0x7ffffffe) { - return NGX_ABORT; - } - - if (path->len > NGX_HTTP_V2_MAX_FIELD) { - return NGX_DECLINED; - } - - if (r->headers_in.host == NULL) { - return NGX_ABORT; - } - - ph = ngx_http_v2_push_headers; - - len = ngx_max(r->schema.len, path->len); - - if (binary[0].len) { - tmp = ngx_palloc(r->pool, len); - if (tmp == NULL) { - return NGX_ERROR; - } - - } else { - for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { - h = (ngx_table_elt_t **) ((char *) &r->headers_in + ph[i].offset); - - if (*h) { - len = ngx_max(len, (*h)->value.len); - } - } - - tmp = ngx_palloc(r->pool, len); - if (tmp == NULL) { - return NGX_ERROR; - } - - for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { - h = (ngx_table_elt_t **) ((char *) &r->headers_in + ph[i].offset); - - if (*h == NULL) { - continue; - } - - value = &(*h)->value; - - len = 1 + NGX_HTTP_V2_INT_OCTETS + value->len; - - pos = ngx_pnalloc(r->pool, len); - if (pos == NULL) { - return NGX_ERROR; - } - - binary[i].data = pos; - - *pos++ = ngx_http_v2_inc_indexed(ph[i].index); - pos = ngx_http_v2_write_value(pos, value->data, value->len, tmp); - - binary[i].len = pos - binary[i].data; - } - } - - len = (h2c->table_update ? 1 : 0) _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel