Previously chain links could sometimes be dropped instead of being reused,
which could result in increased memory consumption during long requests.
A similar chain link issue in ngx_http_gzip_filter_module was fixed in
da46bfc484ef (1.11.10).
Based on a patch by Sangmin Lee.
ngx_debug_point();
- ctx->in = ctx->in->next;
+ cl = ctx->in;
+ ctx->in = cl->next;
+
+ ngx_free_chain(ctx->pool, cl);
continue;
}
/* delete the completed buf from the ctx->in chain */
if (ngx_buf_size(ctx->in->buf) == 0) {
- ctx->in = ctx->in->next;
+ cl = ctx->in;
+ ctx->in = cl->next;
+
+ ngx_free_chain(ctx->pool, cl);
}
cl = ngx_alloc_chain_link(ctx->pool);
ngx_buf_t *b;
ngx_int_t rc;
ngx_uint_t next, last;
- ngx_chain_t *cl, *out, **ll;
+ ngx_chain_t *cl, *out, *ln, **ll;
ngx_http_upstream_t *u;
ngx_http_grpc_ctx_t *ctx;
ngx_http_grpc_frame_t *f;
last = 1;
}
+ ln = in;
in = in->next;
+
+ ngx_free_chain(r->pool, ln);
}
ctx->in = in;
ngx_http_gunzip_filter_add_data(ngx_http_request_t *r,
ngx_http_gunzip_ctx_t *ctx)
{
+ ngx_chain_t *cl;
+
if (ctx->zstream.avail_in || ctx->flush != Z_NO_FLUSH || ctx->redo) {
return NGX_OK;
}
return NGX_DECLINED;
}
- ctx->in_buf = ctx->in->buf;
- ctx->in = ctx->in->next;
+ cl = ctx->in;
+ ctx->in_buf = cl->buf;
+ ctx->in = cl->next;
+
+ ngx_free_chain(r->pool, cl);
ctx->zstream.next_in = ctx->in_buf->pos;
ctx->zstream.avail_in = ctx->in_buf->last - ctx->in_buf->pos;
ngx_http_gunzip_filter_get_buf(ngx_http_request_t *r,
ngx_http_gunzip_ctx_t *ctx)
{
+ ngx_chain_t *cl;
ngx_http_gunzip_conf_t *conf;
if (ctx->zstream.avail_out) {
conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module);
if (ctx->free) {
- ctx->out_buf = ctx->free->buf;
- ctx->free = ctx->free->next;
+
+ cl = ctx->free;
+ ctx->out_buf = cl->buf;
+ ctx->free = cl->next;
+
+ ngx_free_chain(r->pool, cl);
ctx->out_buf->flush = 0;
ngx_http_gzip_filter_free_copy_buf(ngx_http_request_t *r,
ngx_http_gzip_ctx_t *ctx)
{
- ngx_chain_t *cl;
+ ngx_chain_t *cl, *ln;
+
+ for (cl = ctx->copied; cl; /* void */) {
+ ln = cl;
+ cl = cl->next;
- for (cl = ctx->copied; cl; cl = cl->next) {
- ngx_pfree(r->pool, cl->buf->start);
+ ngx_pfree(r->pool, ln->buf->start);
+ ngx_free_chain(r->pool, ln);
}
ctx->copied = NULL;
while (ctx->in || ctx->buf) {
if (ctx->buf == NULL) {
- ctx->buf = ctx->in->buf;
- ctx->in = ctx->in->next;
+
+ cl = ctx->in;
+ ctx->buf = cl->buf;
+ ctx->in = cl->next;
ctx->pos = ctx->buf->pos;
+
+ ngx_free_chain(r->pool, cl);
}
if (ctx->state == ssi_start_state) {
while (ctx->in || ctx->buf) {
if (ctx->buf == NULL) {
- ctx->buf = ctx->in->buf;
- ctx->in = ctx->in->next;
+
+ cl = ctx->in;
+ ctx->buf = cl->buf;
+ ctx->in = cl->next;
ctx->pos = ctx->buf->pos;
+
+ ngx_free_chain(r->pool, cl);
}
if (ctx->buf->flush || ctx->buf->recycled) {