Hello! On Sun, May 14, 2023 at 05:38:54PM +0400, Roman Arutyunyan wrote:
> # HG changeset patch > # User Roman Arutyunyan <a...@nginx.com> > # Date 1683871330 -14400 > # Fri May 12 10:02:10 2023 +0400 > # Branch quic > # Node ID 49a8edf7bf31b78681399cd7e93a8516788607dd > # Parent adcc6d8acfd47c1344b121fceeb94fbcc3f8b5c0 > HTTP/3: removed server push support. > > diff --git a/README b/README > --- a/README > +++ b/README > @@ -135,10 +135,7 @@ 3. Configuration > http3 > http3_hq > http3_stream_buffer_size > - http3_max_concurrent_pushes > http3_max_concurrent_streams > - http3_push > - http3_push_preload > > In http, an additional variable is available: $http3. > The value of $http3 is "h3" for HTTP/3 connections, > @@ -226,13 +223,6 @@ 4. Directives > - initial_max_stream_data_uni > > > - Syntax: http3_max_concurrent_pushes number; > - Default: http3_max_concurrent_pushes 10; > - Context: http, server > - > - Limits the maximum number of concurrent push requests in a connection. > - > - > Syntax: http3_max_concurrent_streams number; > Default: http3_max_concurrent_streams 128; > Context: http, server > @@ -240,31 +230,6 @@ 4. Directives > Sets the maximum number of concurrent HTTP/3 streams in a connection. > > > - Syntax: http3_push uri | off; > - Default: http3_push off; > - Context: http, server, location > - > - Pre-emptively sends (pushes) a request to the specified uri along with > - the response to the original request. Only relative URIs with absolute > - path will be processed, for example: > - > - http3_push /static/css/main.css; > - > - The uri value can contain variables. > - > - Several http3_push directives can be specified on the same configuration > - level. The off parameter cancels the effect of the http3_push directives > - inherited from the previous configuration level. > - > - > - Syntax: http3_push_preload on | off; > - Default: http3_push_preload off; > - Context: http, server, location > - > - Enables automatic conversion of preload links specified in the “Link” > - response header fields into push requests. > - > - > Syntax: http3 on | off; > Default: http3 on; > Context: http, server > diff --git a/src/http/v3/ngx_http_v3.c b/src/http/v3/ngx_http_v3.c > --- a/src/http/v3/ngx_http_v3.c > +++ b/src/http/v3/ngx_http_v3.c > @@ -30,11 +30,7 @@ ngx_http_v3_init_session(ngx_connection_ > goto failed; > } > > - h3c->max_push_id = (uint64_t) -1; > - h3c->goaway_push_id = (uint64_t) -1; > - > ngx_queue_init(&h3c->blocked); > - ngx_queue_init(&h3c->pushing); > > h3c->keepalive.log = c->log; > h3c->keepalive.data = c; > diff --git a/src/http/v3/ngx_http_v3.h b/src/http/v3/ngx_http_v3.h > --- a/src/http/v3/ngx_http_v3.h > +++ b/src/http/v3/ngx_http_v3.h > @@ -106,19 +106,11 @@ typedef struct { > ngx_flag_t enable_hq; > size_t max_table_capacity; > ngx_uint_t max_blocked_streams; > - ngx_uint_t max_concurrent_pushes; > ngx_uint_t max_concurrent_streams; > ngx_quic_conf_t quic; > } ngx_http_v3_srv_conf_t; > > > -typedef struct { > - ngx_flag_t push_preload; > - ngx_flag_t push; > - ngx_array_t *pushes; > -} ngx_http_v3_loc_conf_t; > - > - > struct ngx_http_v3_parse_s { > size_t header_limit; > ngx_http_v3_parse_headers_t headers; > @@ -136,11 +128,6 @@ struct ngx_http_v3_session_s { > ngx_queue_t blocked; > ngx_uint_t nblocked; > > - ngx_queue_t pushing; > - ngx_uint_t npushing; > - uint64_t next_push_id; > - uint64_t max_push_id; > - uint64_t goaway_push_id; > uint64_t next_request_id; > > off_t total_bytes; > diff --git a/src/http/v3/ngx_http_v3_filter_module.c > b/src/http/v3/ngx_http_v3_filter_module.c > --- a/src/http/v3/ngx_http_v3_filter_module.c > +++ b/src/http/v3/ngx_http_v3_filter_module.c > @@ -36,17 +36,6 @@ typedef struct { > > > static ngx_int_t ngx_http_v3_header_filter(ngx_http_request_t *r); > -static ngx_int_t ngx_http_v3_push_resources(ngx_http_request_t *r, > - ngx_chain_t ***out); > -static ngx_int_t ngx_http_v3_push_resource(ngx_http_request_t *r, > - ngx_str_t *path, ngx_chain_t ***out); > -static ngx_int_t ngx_http_v3_create_push_request( > - ngx_http_request_t *pr, ngx_str_t *path, uint64_t push_id); > -static ngx_int_t ngx_http_v3_set_push_header(ngx_http_request_t *r, > - const char *name, ngx_str_t *value); > -static void ngx_http_v3_push_request_handler(ngx_event_t *ev); > -static ngx_chain_t *ngx_http_v3_create_push_promise(ngx_http_request_t *r, > - ngx_str_t *path, uint64_t push_id); > static ngx_int_t ngx_http_v3_body_filter(ngx_http_request_t *r, > ngx_chain_t *in); > static ngx_chain_t *ngx_http_v3_create_trailers(ngx_http_request_t *r, > @@ -155,14 +144,6 @@ ngx_http_v3_header_filter(ngx_http_reque > out = NULL; > ll = &out; > > - if ((c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0 > - && r->method != NGX_HTTP_HEAD) > - { > - if (ngx_http_v3_push_resources(r, &ll) != NGX_OK) { > - return NGX_ERROR; > - } > - } > - > len = ngx_http_v3_encode_field_section_prefix(NULL, 0, 0, 0); > > if (r->headers_out.status == NGX_HTTP_OK) { > @@ -607,672 +588,6 @@ ngx_http_v3_header_filter(ngx_http_reque > > > static ngx_int_t > -ngx_http_v3_push_resources(ngx_http_request_t *r, ngx_chain_t ***out) > -{ > - u_char *start, *end, *last; > - ngx_str_t path; > - ngx_int_t rc; > - ngx_uint_t i, push; > - ngx_table_elt_t *h; > - ngx_http_v3_loc_conf_t *h3lcf; > - ngx_http_complex_value_t *pushes; > - > - h3lcf = ngx_http_get_module_loc_conf(r, ngx_http_v3_module); > - > - if (h3lcf->pushes) { > - pushes = h3lcf->pushes->elts; > - > - for (i = 0; i < h3lcf->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_v3_push_resource(r, &path, out); > - > - if (rc == NGX_ERROR) { > - return NGX_ERROR; > - } > - > - if (rc == NGX_ABORT) { > - return NGX_OK; > - } > - > - /* NGX_OK, NGX_DECLINED */ > - } > - } > - > - if (!h3lcf->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, > - "http3 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_v3_push_resource(r, &path, out); > - > - 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_v3_push_resource(ngx_http_request_t *r, ngx_str_t *path, > - ngx_chain_t ***ll) > -{ > - uint64_t push_id; > - ngx_int_t rc; > - ngx_chain_t *cl; > - ngx_connection_t *c; > - ngx_http_v3_session_t *h3c; > - ngx_http_v3_srv_conf_t *h3scf; > - > - c = r->connection; > - h3c = ngx_http_v3_get_session(c); > - h3scf = ngx_http_get_module_srv_conf(r, ngx_http_v3_module); > - > - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, > - "http3 push \"%V\" pushing:%ui/%ui id:%uL/%L", > - path, h3c->npushing, h3scf->max_concurrent_pushes, > - h3c->next_push_id, h3c->max_push_id); > - > - if (!ngx_path_separator(path->data[0])) { > - ngx_log_error(NGX_LOG_WARN, c->log, 0, > - "non-absolute path \"%V\" not pushed", path); > - return NGX_DECLINED; > - } > - > - if (h3c->max_push_id == (uint64_t) -1 > - || h3c->next_push_id > h3c->max_push_id) > - { > - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, > - "http3 abort pushes due to max_push_id"); > - return NGX_ABORT; > - } > - > - if (h3c->goaway_push_id != (uint64_t) -1) { > - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, > - "http3 abort pushes due to goaway"); > - return NGX_ABORT; > - } > - > - if (h3c->npushing >= h3scf->max_concurrent_pushes) { > - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, > - "http3 abort pushes due to max_concurrent_pushes"); > - return NGX_ABORT; > - } > - > - if (r->headers_in.server.len == 0) { > - return NGX_ABORT; > - } > - > - push_id = h3c->next_push_id++; > - > - rc = ngx_http_v3_create_push_request(r, path, push_id); > - if (rc != NGX_OK) { > - return rc; > - } > - > - cl = ngx_http_v3_create_push_promise(r, path, push_id); > - if (cl == NULL) { > - return NGX_ERROR; > - } > - > - for (**ll = cl; **ll; *ll = &(**ll)->next); > - > - return NGX_OK; > -} > - > - > -static ngx_int_t > -ngx_http_v3_create_push_request(ngx_http_request_t *pr, ngx_str_t *path, > - uint64_t push_id) > -{ > - ngx_connection_t *c, *pc; > - ngx_http_request_t *r; > - ngx_http_log_ctx_t *ctx; > - ngx_http_connection_t *hc, *phc; > - ngx_http_core_srv_conf_t *cscf; > - > - pc = pr->connection; > - > - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, > - "http3 create push request id:%uL", push_id); > - > - c = ngx_http_v3_create_push_stream(pc, push_id); > - if (c == NULL) { > - return NGX_ABORT; > - } > - > -#if (NGX_STAT_STUB) > - (void) ngx_atomic_fetch_add(ngx_stat_active, 1); > -#endif > - > - hc = ngx_palloc(c->pool, sizeof(ngx_http_connection_t)); > - if (hc == NULL) { > - ngx_http_close_connection(c); > - return NGX_ERROR; > - } > - > - phc = ngx_http_quic_get_connection(pc); > - ngx_memcpy(hc, phc, sizeof(ngx_http_connection_t)); > - c->data = hc; > - > - ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); > - if (ctx == NULL) { > - ngx_http_close_connection(c); > - return NGX_ERROR; > - } > - > - ctx->connection = c; > - ctx->request = NULL; > - ctx->current_request = NULL; > - > - c->log->handler = pc->log->handler; > - c->log->data = ctx; > - c->log->action = "processing pushed request headers"; > - > - c->log_error = NGX_ERROR_INFO; > - > - r = ngx_http_create_request(c); > - if (r == NULL) { > - ngx_http_close_connection(c); > - return NGX_ERROR; > - } > - > - c->data = r; > - > - ngx_str_set(&r->http_protocol, "HTTP/3.0"); > - > - r->http_version = NGX_HTTP_VERSION_30; > - r->method_name = ngx_http_core_get_method; > - r->method = NGX_HTTP_GET; > - > - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); > - > - r->header_in = ngx_create_temp_buf(r->pool, > - cscf->client_header_buffer_size); > - if (r->header_in == NULL) { > - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); > - return NGX_ERROR; > - } > - > - if (ngx_list_init(&r->headers_in.headers, r->pool, 4, > - sizeof(ngx_table_elt_t)) > - != NGX_OK) > - { > - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); > - return NGX_ERROR; > - } > - > - r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; > - > - r->schema.data = ngx_pstrdup(r->pool, &pr->schema); > - if (r->schema.data == NULL) { > - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); > - return NGX_ERROR; > - } > - > - r->schema.len = pr->schema.len; > - > - r->uri_start = ngx_pstrdup(r->pool, path); > - if (r->uri_start == NULL) { > - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); > - return NGX_ERROR; > - } > - > - r->uri_end = r->uri_start + path->len; > - > - if (ngx_http_parse_uri(r) != NGX_OK) { > - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); > - return NGX_ERROR; > - } > - > - if (ngx_http_process_request_uri(r) != NGX_OK) { > - return NGX_ERROR; > - } > - > - if (ngx_http_v3_set_push_header(r, "host", &pr->headers_in.server) > - != NGX_OK) > - { > - return NGX_ERROR; > - } > - > - if (pr->headers_in.accept_encoding) { > - if (ngx_http_v3_set_push_header(r, "accept-encoding", > - > &pr->headers_in.accept_encoding->value) > - != NGX_OK) > - { > - return NGX_ERROR; > - } > - } > - > - if (pr->headers_in.accept_language) { > - if (ngx_http_v3_set_push_header(r, "accept-language", > - > &pr->headers_in.accept_language->value) > - != NGX_OK) > - { > - return NGX_ERROR; > - } > - } > - > - if (pr->headers_in.user_agent) { > - if (ngx_http_v3_set_push_header(r, "user-agent", > - &pr->headers_in.user_agent->value) > - != NGX_OK) > - { > - return NGX_ERROR; > - } > - } > - > - c->read->handler = ngx_http_v3_push_request_handler; > - c->read->handler = ngx_http_v3_push_request_handler; > - > - ngx_post_event(c->read, &ngx_posted_events); > - > - return NGX_OK; > -} > - > - > -static ngx_int_t > -ngx_http_v3_set_push_header(ngx_http_request_t *r, const char *name, > - ngx_str_t *value) > -{ > - u_char *p; > - ngx_table_elt_t *h; > - ngx_http_header_t *hh; > - ngx_http_core_main_conf_t *cmcf; > - > - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > - "http3 push header \"%s\": \"%V\"", name, value); > - > - cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); > - > - p = ngx_pnalloc(r->pool, value->len + 1); > - if (p == NULL) { > - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); > - return NGX_ERROR; > - } > - > - ngx_memcpy(p, value->data, value->len); > - p[value->len] = '\0'; > - > - h = ngx_list_push(&r->headers_in.headers); > - if (h == NULL) { > - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); > - return NGX_ERROR; > - } > - > - h->key.data = (u_char *) name; > - h->key.len = ngx_strlen(name); > - h->hash = ngx_hash_key(h->key.data, h->key.len); > - h->lowcase_key = (u_char *) name; > - h->value.data = p; > - h->value.len = value->len; > - > - hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, > - h->lowcase_key, h->key.len); > - > - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { > - return NGX_ERROR; > - } > - > - return NGX_OK; > -} > - > - > -static void > -ngx_http_v3_push_request_handler(ngx_event_t *ev) > -{ > - ngx_connection_t *c; > - ngx_http_request_t *r; > - > - c = ev->data; > - r = c->data; > - > - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 push request > handler"); > - > - ngx_http_process_request(r); > -} > - > - > -static ngx_chain_t * > -ngx_http_v3_create_push_promise(ngx_http_request_t *r, ngx_str_t *path, > - uint64_t push_id) > -{ > - size_t n, len; > - ngx_buf_t *b; > - ngx_chain_t *hl, *cl; > - ngx_http_v3_session_t *h3c; > - > - h3c = ngx_http_v3_get_session(r->connection); > - > - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > - "http3 create push promise id:%uL", push_id); > - > - len = ngx_http_v3_encode_varlen_int(NULL, push_id); > - > - len += ngx_http_v3_encode_field_section_prefix(NULL, 0, 0, 0); > - > - len += ngx_http_v3_encode_field_ri(NULL, 0, > - NGX_HTTP_V3_HEADER_METHOD_GET); > - > - len += ngx_http_v3_encode_field_lri(NULL, 0, > - NGX_HTTP_V3_HEADER_AUTHORITY, > - NULL, r->headers_in.server.len); > - > - if (path->len == 1 && path->data[0] == '/') { > - len += ngx_http_v3_encode_field_ri(NULL, 0, > - NGX_HTTP_V3_HEADER_PATH_ROOT); > - > - } else { > - len += ngx_http_v3_encode_field_lri(NULL, 0, > - NGX_HTTP_V3_HEADER_PATH_ROOT, > - NULL, path->len); > - } > - > - if (r->schema.len == 5 && ngx_strncmp(r->schema.data, "https", 5) == 0) { > - len += ngx_http_v3_encode_field_ri(NULL, 0, > - NGX_HTTP_V3_HEADER_SCHEME_HTTPS); > - > - } else if (r->schema.len == 4 > - && ngx_strncmp(r->schema.data, "http", 4) == 0) > - { > - len += ngx_http_v3_encode_field_ri(NULL, 0, > - NGX_HTTP_V3_HEADER_SCHEME_HTTP); > - > - } else { > - len += ngx_http_v3_encode_field_lri(NULL, 0, > - NGX_HTTP_V3_HEADER_SCHEME_HTTP, > - NULL, r->schema.len); > - } > - > - if (r->headers_in.accept_encoding) { > - len += ngx_http_v3_encode_field_lri(NULL, 0, > - NGX_HTTP_V3_HEADER_ACCEPT_ENCODING, > NULL, > - > r->headers_in.accept_encoding->value.len); > - } > - > - if (r->headers_in.accept_language) { > - len += ngx_http_v3_encode_field_lri(NULL, 0, > - NGX_HTTP_V3_HEADER_ACCEPT_LANGUAGE, > NULL, > - > r->headers_in.accept_language->value.len); > - } > - > - if (r->headers_in.user_agent) { > - len += ngx_http_v3_encode_field_lri(NULL, 0, > - NGX_HTTP_V3_HEADER_USER_AGENT, > NULL, > - > r->headers_in.user_agent->value.len); > - } > - > - b = ngx_create_temp_buf(r->pool, len); > - if (b == NULL) { > - return NULL; > - } > - > - b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, push_id); > - > - b->last = (u_char *) ngx_http_v3_encode_field_section_prefix(b->last, > - 0, 0, 0); > - > - b->last = (u_char *) ngx_http_v3_encode_field_ri(b->last, 0, > - > NGX_HTTP_V3_HEADER_METHOD_GET); > - > - b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, > - > NGX_HTTP_V3_HEADER_AUTHORITY, > - r->headers_in.server.data, > - r->headers_in.server.len); > - > - if (path->len == 1 && path->data[0] == '/') { > - b->last = (u_char *) ngx_http_v3_encode_field_ri(b->last, 0, > - > NGX_HTTP_V3_HEADER_PATH_ROOT); > - > - } else { > - b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, > - > NGX_HTTP_V3_HEADER_PATH_ROOT, > - path->data, path->len); > - } > - > - if (r->schema.len == 5 && ngx_strncmp(r->schema.data, "https", 5) == 0) { > - b->last = (u_char *) ngx_http_v3_encode_field_ri(b->last, 0, > - > NGX_HTTP_V3_HEADER_SCHEME_HTTPS); > - > - } else if (r->schema.len == 4 > - && ngx_strncmp(r->schema.data, "http", 4) == 0) > - { > - b->last = (u_char *) ngx_http_v3_encode_field_ri(b->last, 0, > - > NGX_HTTP_V3_HEADER_SCHEME_HTTP); > - > - } else { > - b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, > - > NGX_HTTP_V3_HEADER_SCHEME_HTTP, > - r->schema.data, > r->schema.len); > - } > - > - if (r->headers_in.accept_encoding) { > - b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, > - NGX_HTTP_V3_HEADER_ACCEPT_ENCODING, > - > r->headers_in.accept_encoding->value.data, > - > r->headers_in.accept_encoding->value.len); > - } > - > - if (r->headers_in.accept_language) { > - b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, > - NGX_HTTP_V3_HEADER_ACCEPT_LANGUAGE, > - > r->headers_in.accept_language->value.data, > - > r->headers_in.accept_language->value.len); > - } > - > - if (r->headers_in.user_agent) { > - b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, > - NGX_HTTP_V3_HEADER_USER_AGENT, > - > r->headers_in.user_agent->value.data, > - > r->headers_in.user_agent->value.len); > - } > - > - cl = ngx_alloc_chain_link(r->pool); > - if (cl == NULL) { > - return NULL; > - } > - > - cl->buf = b; > - cl->next = NULL; > - > - n = b->last - b->pos; > - > - h3c->payload_bytes += n; > - > - len = ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_FRAME_PUSH_PROMISE) > - + ngx_http_v3_encode_varlen_int(NULL, n); > - > - b = ngx_create_temp_buf(r->pool, len); > - if (b == NULL) { > - return NULL; > - } > - > - b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, > - > NGX_HTTP_V3_FRAME_PUSH_PROMISE); > - b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, n); > - > - hl = ngx_alloc_chain_link(r->pool); > - if (hl == NULL) { > - return NULL; > - } > - > - hl->buf = b; > - hl->next = cl; > - > - return hl; > -} > - > - > -static ngx_int_t > ngx_http_v3_body_filter(ngx_http_request_t *r, ngx_chain_t *in) > { > u_char *chunk; > diff --git a/src/http/v3/ngx_http_v3_module.c > b/src/http/v3/ngx_http_v3_module.c > --- a/src/http/v3/ngx_http_v3_module.c > +++ b/src/http/v3/ngx_http_v3_module.c > @@ -18,10 +18,6 @@ static char *ngx_http_v3_merge_srv_conf( > void *child); > static char *ngx_http_quic_host_key(ngx_conf_t *cf, ngx_command_t *cmd, > void *conf); > -static void *ngx_http_v3_create_loc_conf(ngx_conf_t *cf); > -static char *ngx_http_v3_merge_loc_conf(ngx_conf_t *cf, void *parent, > - void *child); > -static char *ngx_http_v3_push(ngx_conf_t *cf, ngx_command_t *cmd, void > *conf); > > > static ngx_command_t ngx_http_v3_commands[] = { > @@ -40,13 +36,6 @@ static ngx_command_t ngx_http_v3_comman > offsetof(ngx_http_v3_srv_conf_t, enable_hq), > NULL }, > > - { ngx_string("http3_max_concurrent_pushes"), > - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, > - ngx_conf_set_num_slot, > - NGX_HTTP_SRV_CONF_OFFSET, > - offsetof(ngx_http_v3_srv_conf_t, max_concurrent_pushes), > - NULL }, > - > { ngx_string("http3_max_concurrent_streams"), > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, > ngx_conf_set_num_slot, > @@ -54,20 +43,6 @@ static ngx_command_t ngx_http_v3_comman > offsetof(ngx_http_v3_srv_conf_t, max_concurrent_streams), > NULL }, > > - { ngx_string("http3_push"), > - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, > - ngx_http_v3_push, > - NGX_HTTP_LOC_CONF_OFFSET, > - 0, > - NULL }, > - > - { ngx_string("http3_push_preload"), > - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, > - ngx_conf_set_flag_slot, > - NGX_HTTP_LOC_CONF_OFFSET, > - offsetof(ngx_http_v3_loc_conf_t, push_preload), > - NULL }, > - > { ngx_string("http3_stream_buffer_size"), > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, > ngx_conf_set_size_slot, > @@ -117,8 +92,8 @@ static ngx_http_module_t ngx_http_v3_mo > ngx_http_v3_create_srv_conf, /* create server configuration */ > ngx_http_v3_merge_srv_conf, /* merge server configuration */ > > - ngx_http_v3_create_loc_conf, /* create location configuration > */ > - ngx_http_v3_merge_loc_conf /* merge location configuration */ > + NULL, /* create location configuration > */ > + NULL /* merge location configuration */ > }; > > > @@ -224,7 +199,6 @@ ngx_http_v3_create_srv_conf(ngx_conf_t * > h3scf->enable = NGX_CONF_UNSET; > h3scf->enable_hq = NGX_CONF_UNSET; > h3scf->max_table_capacity = NGX_HTTP_V3_MAX_TABLE_CAPACITY; > - h3scf->max_concurrent_pushes = NGX_CONF_UNSET_UINT; > h3scf->max_concurrent_streams = NGX_CONF_UNSET_UINT; > > h3scf->quic.stream_buffer_size = NGX_CONF_UNSET_SIZE; > @@ -255,9 +229,6 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *c > > ngx_conf_merge_value(conf->enable_hq, prev->enable_hq, 0); > > - ngx_conf_merge_uint_value(conf->max_concurrent_pushes, > - prev->max_concurrent_pushes, 10); > - > ngx_conf_merge_uint_value(conf->max_concurrent_streams, > prev->max_concurrent_streams, 128); > > @@ -416,102 +387,3 @@ failed: > > return NGX_CONF_ERROR; > } > - > - > -static void * > -ngx_http_v3_create_loc_conf(ngx_conf_t *cf) > -{ > - ngx_http_v3_loc_conf_t *h3lcf; > - > - h3lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_v3_loc_conf_t)); > - if (h3lcf == NULL) { > - return NULL; > - } > - > - /* > - * set by ngx_pcalloc(): > - * > - * h3lcf->pushes = NULL; > - */ > - > - h3lcf->push_preload = NGX_CONF_UNSET; > - h3lcf->push = NGX_CONF_UNSET; > - > - return h3lcf; > -} > - > - > -static char * > -ngx_http_v3_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) > -{ > - ngx_http_v3_loc_conf_t *prev = parent; > - ngx_http_v3_loc_conf_t *conf = child; > - > - ngx_conf_merge_value(conf->push, prev->push, 1); > - > - if (conf->push && conf->pushes == NULL) { > - conf->pushes = prev->pushes; > - } > - > - ngx_conf_merge_value(conf->push_preload, prev->push_preload, 0); > - > - return NGX_CONF_OK; > -} > - > - > -static char * > -ngx_http_v3_push(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) > -{ > - ngx_http_v3_loc_conf_t *h3lcf = conf; > - > - ngx_str_t *value; > - ngx_http_complex_value_t *cv; > - ngx_http_compile_complex_value_t ccv; > - > - value = cf->args->elts; > - > - if (ngx_strcmp(value[1].data, "off") == 0) { > - > - if (h3lcf->pushes) { > - return "\"off\" parameter cannot be used with URI"; > - } > - > - if (h3lcf->push == 0) { > - return "is duplicate"; > - } > - > - h3lcf->push = 0; > - return NGX_CONF_OK; > - } > - > - if (h3lcf->push == 0) { > - return "URI cannot be used with \"off\" parameter"; > - } > - > - h3lcf->push = 1; > - > - if (h3lcf->pushes == NULL) { > - h3lcf->pushes = ngx_array_create(cf->pool, 1, > - sizeof(ngx_http_complex_value_t)); > - if (h3lcf->pushes == NULL) { > - return NGX_CONF_ERROR; > - } > - } > - > - cv = ngx_array_push(h3lcf->pushes); > - if (cv == NULL) { > - return NGX_CONF_ERROR; > - } > - > - ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); > - > - ccv.cf = cf; > - ccv.value = &value[1]; > - ccv.complex_value = cv; > - > - if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { > - return NGX_CONF_ERROR; > - } > - > - return NGX_CONF_OK; > -} > diff --git a/src/http/v3/ngx_http_v3_uni.c b/src/http/v3/ngx_http_v3_uni.c > --- a/src/http/v3/ngx_http_v3_uni.c > +++ b/src/http/v3/ngx_http_v3_uni.c > @@ -16,19 +16,10 @@ typedef struct { > } ngx_http_v3_uni_stream_t; > > > -typedef struct { > - ngx_queue_t queue; > - uint64_t id; > - ngx_connection_t *connection; > - ngx_uint_t *npushing; > -} ngx_http_v3_push_t; > - > - > static void ngx_http_v3_close_uni_stream(ngx_connection_t *c); > static void ngx_http_v3_uni_read_handler(ngx_event_t *rev); > static void ngx_http_v3_uni_dummy_read_handler(ngx_event_t *wev); > static void ngx_http_v3_uni_dummy_write_handler(ngx_event_t *wev); > -static void ngx_http_v3_push_cleanup(void *data); > static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c, > ngx_uint_t type); > > @@ -316,78 +307,6 @@ ngx_http_v3_uni_dummy_write_handler(ngx_ > } > > > -ngx_connection_t * > -ngx_http_v3_create_push_stream(ngx_connection_t *c, uint64_t push_id) > -{ > - u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 2]; > - size_t n; > - ngx_connection_t *sc; > - ngx_pool_cleanup_t *cln; > - ngx_http_v3_push_t *push; > - ngx_http_v3_session_t *h3c; > - > - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, > - "http3 create push stream id:%uL", push_id); > - > - sc = ngx_quic_open_stream(c, 0); > - if (sc == NULL) { > - goto failed; > - } > - > - p = buf; > - p = (u_char *) ngx_http_v3_encode_varlen_int(p, NGX_HTTP_V3_STREAM_PUSH); > - p = (u_char *) ngx_http_v3_encode_varlen_int(p, push_id); > - n = p - buf; > - > - h3c = ngx_http_v3_get_session(c); > - h3c->total_bytes += n; > - > - if (sc->send(sc, buf, n) != (ssize_t) n) { > - goto failed; > - } > - > - cln = ngx_pool_cleanup_add(sc->pool, sizeof(ngx_http_v3_push_t)); > - if (cln == NULL) { > - goto failed; > - } > - > - h3c->npushing++; > - > - cln->handler = ngx_http_v3_push_cleanup; > - > - push = cln->data; > - push->id = push_id; > - push->connection = sc; > - push->npushing = &h3c->npushing; > - > - ngx_queue_insert_tail(&h3c->pushing, &push->queue); > - > - return sc; > - > -failed: > - > - ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to create push stream"); > - > - ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR, > - "failed to create push stream"); > - if (sc) { > - ngx_http_v3_close_uni_stream(sc); > - } > - > - return NULL; > -} > - > - > -static void > -ngx_http_v3_push_cleanup(void *data) > -{ > - ngx_http_v3_push_t *push = data; > - > - ngx_queue_remove(&push->queue); > - (*push->npushing)--; > -} > - > - > static ngx_connection_t * > ngx_http_v3_get_uni_stream(ngx_connection_t *c, ngx_uint_t type) > { > @@ -696,19 +615,9 @@ failed: > ngx_int_t > ngx_http_v3_set_max_push_id(ngx_connection_t *c, uint64_t max_push_id) > { > - ngx_http_v3_session_t *h3c; > - > - h3c = ngx_http_v3_get_session(c); > - > ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, > "http3 MAX_PUSH_ID:%uL", max_push_id); > > - if (h3c->max_push_id != (uint64_t) -1 && max_push_id < h3c->max_push_id) > { > - return NGX_HTTP_V3_ERR_ID_ERROR; > - } > - > - h3c->max_push_id = max_push_id; > - > return NGX_OK; > } > > @@ -716,14 +625,8 @@ ngx_http_v3_set_max_push_id(ngx_connecti > ngx_int_t > ngx_http_v3_goaway(ngx_connection_t *c, uint64_t push_id) > { > - ngx_http_v3_session_t *h3c; > - > - h3c = ngx_http_v3_get_session(c); > - > ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 GOAWAY:%uL", > push_id); > > - h3c->goaway_push_id = push_id; > - > return NGX_OK; > } Shouldn't we simply skip MAX_PUSH_ID and GOAWAY frames somewhere at ngx_http_v3_parse_control()? > @@ -731,40 +634,9 @@ ngx_http_v3_goaway(ngx_connection_t *c, > ngx_int_t > ngx_http_v3_cancel_push(ngx_connection_t *c, uint64_t push_id) > { > - ngx_queue_t *q; > - ngx_http_request_t *r; > - ngx_http_v3_push_t *push; > - ngx_http_v3_session_t *h3c; > - > - h3c = ngx_http_v3_get_session(c); > - > ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, > "http3 CANCEL_PUSH:%uL", push_id); > > - if (push_id >= h3c->next_push_id) { > - return NGX_HTTP_V3_ERR_ID_ERROR; > - } > - > - for (q = ngx_queue_head(&h3c->pushing); > - q != ngx_queue_sentinel(&h3c->pushing); > - q = ngx_queue_next(q)) > - { > - push = (ngx_http_v3_push_t *) q; > - > - if (push->id != push_id) { > - continue; > - } > - > - r = push->connection->data; > - > - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > - "http3 cancel push"); > - > - ngx_http_finalize_request(r, NGX_HTTP_CLOSE); > - > - break; > - } > - > return NGX_OK; > } > And CANCEL_PUSH probably worth an explicit error (https://www.rfc-editor.org/rfc/rfc9114.html#name-cancel_push): : If a server receives a CANCEL_PUSH frame for a push ID that has : not yet been mentioned by a PUSH_PROMISE frame, this MUST be : treated as a connection error of type H3_ID_ERROR. Since no pushes are expected to appear on the connection, returning NGX_HTTP_V3_ERR_ID_ERROR seems to be correct option. Similarly to the above, handling this at ngx_http_v3_parse_control() might be easier. > diff --git a/src/http/v3/ngx_http_v3_uni.h b/src/http/v3/ngx_http_v3_uni.h > --- a/src/http/v3/ngx_http_v3_uni.h > +++ b/src/http/v3/ngx_http_v3_uni.h > @@ -17,8 +17,6 @@ > void ngx_http_v3_init_uni_stream(ngx_connection_t *c); > ngx_int_t ngx_http_v3_register_uni_stream(ngx_connection_t *c, uint64_t > type); > > -ngx_connection_t *ngx_http_v3_create_push_stream(ngx_connection_t *c, > - uint64_t push_id); > ngx_int_t ngx_http_v3_set_max_push_id(ngx_connection_t *c, > uint64_t max_push_id); > ngx_int_t ngx_http_v3_goaway(ngx_connection_t *c, uint64_t push_id); Otherwise looks good. -- Maxim Dounin http://mdounin.ru/ _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel