Welcome! Log In Create A New Profile

Advanced

Re: NGX_DONE from body_filter, and what's next?

bbm
September 18, 2009 05:53AM
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 [info] 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 [info] 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

[result]
0

0

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

GET /sth HTTP/1.1
Host: host

[result]
0

// where is second 0?

GET /sth HTTP/1.1
Host: host

[no result, no reaction]

GET /sth HTTP/1.1
Host: host

[no result, no reaction again]

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 ;)
Subject Author Posted

NGX_DONE from body_filter, and what's next?

bbm September 17, 2009 07:22AM

Re: NGX_DONE from body_filter, and what's next?

bbm September 18, 2009 05:53AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 257
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready