# HG changeset patch # User Maxim Dounin # Date 1217638882 -14400 # Node ID 47a21c299f1102ca740cdc54907c12b54546ba96 # Parent 42975d951e9f6e247268a51b4ed7202400daf99c Fix work with multiple buffers. 1. Always free or pass out buffers got from callers. 2. Don't pass out zero size bufs, pass null chain instead. diff --git a/ngx_http_bytes_filter_module.c b/ngx_http_bytes_filter_module.c --- a/ngx_http_bytes_filter_module.c +++ b/ngx_http_bytes_filter_module.c @@ -357,9 +357,7 @@ ngx_http_bytes_body_filter(ngx_http_requ return ngx_http_next_body_filter(r, in); } - for (ll = &in, cl = in; cl; ll = &cl->next, cl = cl->next, - ctx->offset += size) - { + for (ll = &in, cl = in; cl; cl = cl->next, ctx->offset += size) { buf = cl->buf; size = ngx_buf_size(buf); @@ -371,19 +369,25 @@ ngx_http_bytes_body_filter(ngx_http_requ /* pass out anyway */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "bytes body filter: special buffer"); + ll = &cl->next; continue; } next: - if (range->start > ctx->offset + size) { + if (range->start > ctx->offset + size || range->end < ctx->offset) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "bytes body filter: fully ignored buffer"); + buf->pos = buf->last; *ll = cl->next; - buf->pos = buf->last; continue; } - /* todo: do not create buffers/links if not needed */ + /* we should either free or reuse original buffer */ + + if (range == last - 1 || range[1].start > ctx->offset + size) { + b = buf; + goto fixup; + } b = ngx_calloc_buf(r->pool); if (b == NULL) { @@ -420,6 +424,7 @@ next: b->last_buf = 1; } +fixup: if (b->in_file) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -462,6 +467,8 @@ next: goto next; } } + + ll = &cl->next; } return ngx_http_next_body_filter(r, in);