NGX_DONE from body_filter, and what's next?

bbm nginx-forum at nginx.us
Fri Sep 18 13:53:49 MSD 2009


I will give some code example:

ngx_http_my_filter_header_filter(ngx_http_request_t *r)
{
   // (...)

  // I clear content length, because it will be modified by my filter
    if (r == r->main) {
        ngx_http_clear_content_length(r);
        ngx_http_clear_last_modified(r);
    }
    return ngx_http_next_header_filter(r);
}

ngx_http_myfilter_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
// process data
// enqueue downloads etc.
//...
   return NGX_DONE;
}

The function which is called when downloads are finished:

ngx_http_myfilter_download_finished()
{
    // process data etc.

   // create and fill new ngx_chain_t  
   // set in bufs:  memory = 1, last_buf = 1 in last buffer

    rc = ngx_http_next_body_filter(r, output_chain);

    if(rc == NGX_AGAIN)
    {
        ngx_add_timer(r->connection->write, timeout);
        r->write_event_handler = ngx_http_myfilter_fast_handler;
        
        if (ngx_handle_write_event(r->connection->write, 0) == NGX_ERROR) 
        {
              // error handling
        }
    }
    else {
        ngx_http_myfilter_fast_handler(r);
    } 
}


and fast_handler:

ngx_http_xxslt_fast_handler(ngx_http_request_t *r) 
{ 
    ngx_int_t   rc;

    rc = ngx_http_send_special(r, NGX_HTTP_LAST);

    ngx_http_finalize_request(r, rc);
}

When ngx_http_next_body_filter returns NGX_OK everything is fine, no problem.
My filter behaves strange, when ngx_http_next_body_filter returns NGX_AGAIN (for large output chains).
When I refresh website, first request is handled properly, I can see the result in the web browser.
Second request is broken. After receiving rc = NGX_AGAIN my fast_handler is not called and response isn't transferred to the client. 
There are two messages in logs from nginx:
2009/09/18 11:40:25  30067#0: *52 client closed prematurely connection (104: Connection reset by peer) while sending response to client, client: 10.166... 
2009/09/18 11:40:54  30067#0: *1 client timed out (110: Connection timed out) while sending response to client, client: 10.166...

When I use telnet it looks like this:
GET /sth HTTP/1.1
Host: host


0

0

// this is ok, because of Transfer-Encoding: chunked there are two zeros at the end

GET /sth HTTP/1.1
Host: host


0

// where is second 0? 

GET /sth HTTP/1.1
Host: host



GET /sth HTTP/1.1
Host: host

 

etc.

These request which are not handled just call my body_filter with in = NULL (it's visible in logs).

Any ideas what am I doing wrong? 
Any help will be greatly appreciated ;)

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,7413,7611#msg-7611






More information about the nginx mailing list