On Tue, 11 Jun 2024 02:46:13 +0100 J Carter <jordanc.car...@outlook.com> wrote:
> Style cleanup of previous patch. > > Also removed 'status already > returned' guard in slice range variable handler, as it is no longer > needed given other changes in patch. > Additional fixes. # HG changeset patch # User J Carter <jordanc.car...@outlook.com> # Date 1718225771 -3600 # Wed Jun 12 21:56:11 2024 +0100 # Node ID 8edd891af4d6474ea139490e3662241212926244 # Parent 02e9411009b987f408214ab4a8b6b6093f843bcd Slice filter: proxy_cache_background_update support (ticket #1348). Previously, subrequests of a slice subrequest would have an empty $slice_range variable value. This prevented proxy_cache_background_update and friends from successfully fetching and populating correctly. This occurred for two reasons: - Firstly, a single context was reused for all slice subrequests, where each $slice_range value was overwritten by subsequent slice subrequests. - Secondly, subrequests not initiated by slice filter were unable to access $slice_range in a parent subrequest. Each slice subrequests now retains $slice_range and subrequests of slice subrequests now utilize the parent slice subrequest's $slice_range if available. diff --git a/src/http/modules/ngx_http_slice_filter_module.c b/src/http/modules/ngx_http_slice_filter_module.c --- a/src/http/modules/ngx_http_slice_filter_module.c +++ b/src/http/modules/ngx_http_slice_filter_module.c @@ -18,11 +18,16 @@ typedef struct { typedef struct { off_t start; off_t end; - ngx_str_t range; ngx_str_t etag; unsigned last:1; unsigned active:1; ngx_http_request_t *sr; +} ngx_http_slice_shctx_t; + + +typedef struct { + ngx_str_t range; + ngx_http_slice_shctx_t *sh; } ngx_http_slice_ctx_t; @@ -105,6 +110,7 @@ ngx_http_slice_header_filter(ngx_http_re ngx_int_t rc; ngx_table_elt_t *h; ngx_http_slice_ctx_t *ctx; + ngx_http_slice_shctx_t *sh; ngx_http_slice_loc_conf_t *slcf; ngx_http_slice_content_range_t cr; @@ -113,6 +119,8 @@ ngx_http_slice_header_filter(ngx_http_re return ngx_http_next_header_filter(r); } + sh = ctx->sh; + if (r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT) { if (r == r->main) { ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module); @@ -127,10 +135,10 @@ ngx_http_slice_header_filter(ngx_http_re h = r->headers_out.etag; - if (ctx->etag.len) { + if (sh->etag.len) { if (h == NULL - || h->value.len != ctx->etag.len - || ngx_strncmp(h->value.data, ctx->etag.data, ctx->etag.len) + || h->value.len != sh->etag.len + || ngx_strncmp(h->value.data, sh->etag.data, sh->etag.len) != 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, @@ -140,7 +148,7 @@ ngx_http_slice_header_filter(ngx_http_re } if (h) { - ctx->etag = h->value; + sh->etag = h->value; } if (ngx_http_slice_parse_content_range(r, &cr) != NGX_OK) { @@ -163,15 +171,15 @@ ngx_http_slice_header_filter(ngx_http_re end = ngx_min(cr.start + (off_t) slcf->size, cr.complete_length); - if (cr.start != ctx->start || cr.end != end) { + if (cr.start != sh->start || cr.end != end) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "unexpected range in slice response: %O-%O", cr.start, cr.end); return NGX_ERROR; } - ctx->start = end; - ctx->active = 1; + sh->start = end; + sh->active = 1; r->headers_out.status = NGX_HTTP_OK; r->headers_out.status_line.len = 0; @@ -198,16 +206,16 @@ ngx_http_slice_header_filter(ngx_http_re r->preserve_body = 1; if (r->headers_out.status == NGX_HTTP_PARTIAL_CONTENT) { - if (ctx->start + (off_t) slcf->size <= r->headers_out.content_offset) { - ctx->start = slcf->size - * (r->headers_out.content_offset / slcf->size); + if (sh->start + (off_t) slcf->size <= r->headers_out.content_offset) { + sh->start = slcf->size + * (r->headers_out.content_offset / slcf->size); } - ctx->end = r->headers_out.content_offset - + r->headers_out.content_length_n; + sh->end = r->headers_out.content_offset + + r->headers_out.content_length_n; } else { - ctx->end = cr.complete_length; + sh->end = cr.complete_length; } return rc; @@ -217,9 +225,11 @@ ngx_http_slice_header_filter(ngx_http_re static ngx_int_t ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { + u_char *p; ngx_int_t rc; ngx_chain_t *cl; - ngx_http_slice_ctx_t *ctx; + ngx_http_slice_ctx_t *ctx, *sr_ctx; + ngx_http_slice_shctx_t *sh; ngx_http_slice_loc_conf_t *slcf; ctx = ngx_http_get_module_ctx(r, ngx_http_slice_filter_module); @@ -228,32 +238,34 @@ ngx_http_slice_body_filter(ngx_http_requ return ngx_http_next_body_filter(r, in); } + sh = ctx->sh; + for (cl = in; cl; cl = cl->next) { if (cl->buf->last_buf) { cl->buf->last_buf = 0; cl->buf->last_in_chain = 1; cl->buf->sync = 1; - ctx->last = 1; + sh->last = 1; } } rc = ngx_http_next_body_filter(r, in); - if (rc == NGX_ERROR || !ctx->last) { + if (rc == NGX_ERROR || !sh->last) { return rc; } - if (ctx->sr && !ctx->sr->done) { + if (sh->sr && !sh->sr->done) { return rc; } - if (!ctx->active) { + if (!sh->active) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "missing slice response"); return NGX_ERROR; } - if (ctx->start >= ctx->end) { + if (sh->start >= sh->end) { ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module); ngx_http_send_special(r, NGX_HTTP_LAST); return rc; @@ -263,25 +275,36 @@ ngx_http_slice_body_filter(ngx_http_requ return rc; } - if (ngx_http_subrequest(r, &r->uri, &r->args, &ctx->sr, NULL, + if (ngx_http_subrequest(r, &r->uri, &r->args, &sh->sr, NULL, NGX_HTTP_SUBREQUEST_CLONE) != NGX_OK) { return NGX_ERROR; } - ngx_http_set_ctx(ctx->sr, ctx, ngx_http_slice_filter_module); + sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_slice_ctx_t)); + if (sr_ctx == NULL) { + return NGX_ERROR; + } + + sr_ctx->sh = ctx->sh; + + ngx_http_set_ctx(sh->sr, sr_ctx, ngx_http_slice_filter_module); slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module); - ctx->range.len = ngx_sprintf(ctx->range.data, "bytes=%O-%O", ctx->start, - ctx->start + (off_t) slcf->size - 1) - - ctx->range.data; + p = ngx_pnalloc(r->pool, sizeof("bytes=-") - 1 + 2 * NGX_OFF_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } - ctx->active = 0; + sh->active = 0; + sr_ctx->range.data = p; + sr_ctx->range.len = ngx_sprintf(p, "bytes=%O-%O", sh->start, + sh->start + (off_t) slcf->size - 1) - p; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http slice subrequest: \"%V\"", &ctx->range); + "http slice subrequest: \"%V\"", &sr_ctx->range); return rc; } @@ -397,12 +420,25 @@ ngx_http_slice_range_variable(ngx_http_r { u_char *p; ngx_http_slice_ctx_t *ctx; + ngx_http_slice_shctx_t *sh; ngx_http_slice_loc_conf_t *slcf; ctx = ngx_http_get_module_ctx(r, ngx_http_slice_filter_module); if (ctx == NULL) { - if (r != r->main || r->headers_out.status) { + if (r->headers_out.status) { + v->not_found = 1; + return NGX_OK; + } + + if (r != r->main) { + /* cache_background_update handling */ + ctx = ngx_http_get_module_ctx(r->parent, + ngx_http_slice_filter_module); + if (ctx) { + goto found; + } + v->not_found = 1; return NGX_OK; } @@ -419,6 +455,13 @@ ngx_http_slice_range_variable(ngx_http_r return NGX_ERROR; } + sh = ngx_pcalloc(r->pool, sizeof(ngx_http_slice_shctx_t)); + if (sh == NULL) { + return NGX_ERROR; + } + + ctx->sh = sh; + ngx_http_set_ctx(r, ctx, ngx_http_slice_filter_module); p = ngx_pnalloc(r->pool, sizeof("bytes=-") - 1 + 2 * NGX_OFF_T_LEN); @@ -426,14 +469,15 @@ ngx_http_slice_range_variable(ngx_http_r return NGX_ERROR; } - ctx->start = slcf->size * (ngx_http_slice_get_start(r) / slcf->size); + sh->start = slcf->size * (ngx_http_slice_get_start(r) / slcf->size); ctx->range.data = p; - ctx->range.len = ngx_sprintf(p, "bytes=%O-%O", ctx->start, - ctx->start + (off_t) slcf->size - 1) - - p; + ctx->range.len = ngx_sprintf(p, "bytes=%O-%O", sh->start, + sh->start + (off_t) slcf->size - 1) - p; } +found: + v->data = ctx->range.data; v->valid = 1; v->not_found = 0; _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel