Sub filter‘s bug?

my nginx version is 0.7.67.

I test nginx’s sub filter, there have some alert log in error log:

the http output chain is empty while sending response to client.
*
*
and i debug nginx , and then found this is cause by sub filter. so i
read
sub filter’s source.

in ngx_http_sub_body_filter:

  • if (ctx->once && (ctx->buf == NULL || ctx->in == NULL)) {*
  •    if (ctx->busy) {*
    
  •        if (ngx_http_sub_output(r, ctx) == NGX_ERROR) {*
    
  •            return NGX_ERROR;*
    
  •        }*
    
  •    }*
    
  •    return ngx_http_next_body_filter(r, in);*
    
  • }*

i found when sub_filter_once is on , after text have replaced . and
the
second enter ngx_http_sub_body_filter.
At the moment when in is null,ctx->busy is not null,and so
ngx_http_sub_output
may send the rest of buf completely
*, therefore in
**ngx_http_next_body_filter
will log alert log : the http output chain is empty while sending
response
to client. *
*
*
in conclusion I *think there should add a *judgement that in is
whether
or not NULL.
*
*
this is my patch:
*
*
*
— nginx-0.7.67/src/http/modules/ngx_http_sub_filter_module.c
2009-10-26
23:54:29.000000000 +0800
+++ nginx-0.7.67_new/src/http/modules/ngx_http_sub_filter_module.c
2010-09-15
10:14:04.996666685 +0800
@@ -187,16 +187,16 @@ ngx_http_sub_body_filter(ngx_http_reques
}

 if (ctx->once && (ctx->buf == NULL || ctx->in == NULL)) {

     if (ctx->busy) {
  •        if (ngx_http_sub_output(r, ctx) == NGX_ERROR) {
    
  •            return NGX_ERROR;
    
  •        }
    
  •        rc = ngx_http_sub_output(r, ctx);
       }
    
  •    return ngx_http_next_body_filter(r, in);
    
  •    if (rc != NGX_ERROR && in != NULL)
    
  •        return ngx_http_next_body_filter(r, in);
    
  •    return rc;
    

    }

    /* add the incoming chain to the chain ctx->in */

    if (in) {


博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: www.twitter.com/minibobo

i find this result is cause by postpone filter is removed. because i
use --without-http_ssi_module config nginx. and i read nginx config find
this in auto/modules:

if [ $HTTP_SSI = YES ]; then
HTTP_POSTPONE=YES
fi

if [ $HTTP_ADDITION = YES ]; then
HTTP_POSTPONE=YES
fi

and why postpone is yes when ssi or addition module is on ?
and then i debug nginx find some code in ngx_http_postpone_filter method
:

if (r->postponed == NULL) {

    if (in || c->buffered) {
        return ngx_http_next_filter(r->main, in);
    }

    return NGX_OK;
}

therefore if no postpone module, sub filter module may emerge the result
in
my previous email .

On Wed, Sep 15, 2010 at 11:00 AM, Simon L.
[email protected]wrote:

in ngx_http_sub_body_filter:
*
*
+++ nginx-0.7.67_new/src/http/modules/ngx_http_sub_filter_module.c 2010-09-15


博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: www.twitter.com/minibobo

Hello!

On Tue, Sep 21, 2010 at 05:08:08PM +0800, Simon L. wrote:

HTTP_POSTPONE=YES

fi

and why postpone is yes when ssi or addition module is on ?

Postpone filter is used to order data sent by subrequests. It
shouldn’t be needed when no subrequests are used.

  •        if (ngx_http_sub_output(r, ctx) == NGX_ERROR) {*
    

At the moment when in is null,ctx->busy is not null,and so *ngx_http_sub_output
*

  •    return rc;
    

This will use uninitialized rc when no ctx->busy.

Maxim D.

Hello!

On Tue, Sep 21, 2010 at 08:36:11PM +0800, Simon L. wrote:

if (r->postponed == NULL) {

    if (in || c->buffered) {
        return ngx_http_next_filter(r->main, in);
    }

    return NGX_OK;
}

this code is needed by subrequest only? i think sub filter is needed too.

It is believed that empty chains shouldn’t appear in output. They
doesn’t make sense unless used to flush various buffers, and
writer rightfully complains when it sees empty chain while there
are no buffered data.

The code in postpone filter obviously hides some of “empty chain”
problems. But it doesn’t mean that sub module needs it. It means
that sub module have to be fixed (and the problem is usually
hidden by postpone filter).

Maxim D.

thanks Maxim!

my patch is mistake.

but when remove http_ssi_module , sub filter module may log alert:

“the http output chain is empty while sending response to client.”

because sub filter module need ngx_http_postpone_filter’s code :

if (r->postponed == NULL) {

    if (in || c->buffered) {
        return ngx_http_next_filter(r->main, in);
    }

    return NGX_OK;
}

this code is needed by subrequest only? i think sub filter is needed
too.

On Tue, Sep 21, 2010 at 7:57 PM, Maxim D. [email protected]
wrote:

fi

}

I test nginx’s sub filter, there have some alert log in error log:

  • if (ctx->once && (ctx->buf == NULL || ctx->in == NULL)) {*
  • }*
    to client. *
  •    return rc;
    

This will use uninitialized rc when no ctx->busy.

Maxim D.


nginx mailing list
[email protected]
nginx Info Page


博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: www.twitter.com/minibobo

igor will fix this in next version?

On Tue, Sep 21, 2010 at 11:02 PM, Simon L.
[email protected]wrote:

because sub filter module need ngx_http_postpone_filter’s code :
this code is needed by subrequest only? i think sub filter is needed
hidden by postpone filter).


博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: www.twitter.com/minibobo


博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: www.twitter.com/minibobo

thanks maxim!

I agree your perspective , sub filter must deal with this situation(in
is
NULL) .

and as you say , this is sub filter’s bug?

On Tue, Sep 21, 2010 at 10:19 PM, Maxim D. [email protected]
wrote:

“the http output chain is empty while sending response to client.”
}
problems. But it doesn’t mean that sub module needs it. It means
that sub module have to be fixed (and the problem is usually
hidden by postpone filter).

Maxim D.


nginx mailing list
[email protected]
nginx Info Page


博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: www.twitter.com/minibobo