It looks like I've figured out again, I see buffers flushed when they contain \n character.
Sorry to bother. -- Marat On Mon, Mar 25, 2013 at 1:15 AM, Marat Dakota <[email protected]> wrote: > It looks like I've figured out. When I set b->last_buf to 0 for all > the buffers and to 1 for just actual last buffer, everything is ok. > > But then another question happens. Even if all the buffers have > b->flush set to 1, I see my response only in one single chunk, after > all the subrequests finished. How to actually flush the response > buffer by buffer? > > -- > Marat > > On Sun, Mar 24, 2013 at 9:12 PM, Marat Dakota <[email protected]> wrote: >> Hi, >> >> I'm writing a handler module. It makes subrequests and uses body >> filter for subrequests. >> >> Here is simplified handler code: >> >> static ngx_int_t >> ngx_http_my_handler(ngx_http_request_t *r) { >> >> // ... Sending headers. >> >> ngx_chain_t *out; >> ngx_buf_t *b; >> >> out = ngx_alloc_chain_link(r->pool); >> b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); >> >> if (out == NULL || b == NULL) { >> return NGX_HTTP_INTERNAL_SERVER_ERROR; >> } >> >> b->pos = "aaa"; >> b->last = "aaa" + 3; >> b->memory = 1; >> b->last_buf = 1; >> >> out->buf = b; >> out->next = NULL; >> >> // ngx_http_my_subrequest() creates ngx_str_t from second argument >> and calls ngx_http_subrequest(). >> if (ngx_http_my_subrequest(r, "/uri1") != NGX_OK) { >> return NGX_ERROR; >> } >> >> if (ngx_http_my_subrequest(r, "/uri2") != NGX_OK) { >> return NGX_ERROR; >> } >> >> return ngx_http_output_filter(r, out); >> } >> >> >> Here is subrequest body filter: >> >> static ngx_int_t >> ngx_http_my_body_filter(ngx_http_request_t *r, ngx_chain_t *in) >> { >> // ... Do something with subrequest's body in "in" argument. >> >> ngx_chain_t *out; >> ngx_buf_t *b; >> ngx_chain_t *cl; >> >> out = ngx_alloc_chain_link(r->pool); >> b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); >> >> if (out == NULL || b == NULL) { >> return NGX_HTTP_INTERNAL_SERVER_ERROR; >> } >> >> // HERE BE DRAGONS. >> >> b->pos = "bbb"; >> b->last = "bbb" + 3; >> b->memory = 1; >> b->last_buf = 1; >> >> out->buf = b; >> out->next = NULL; >> >> // Discard subrequest's body. >> for (cl = in; cl; cl = cl->next) { >> cl->buf->pos = cl->buf->last; >> cl->buf->file_pos = cl->buf->file_last; >> } >> >> // We just put "bbb" to main response for each call of this body filter. >> return ngx_http_output_filter(r->main, out); >> } >> >> And everything works just fine. For example, if >> ngx_http_my_body_filter is called twice for each (/uri1 and /uri2) >> subrequest started from ngx_http_my_handler, the result will be >> "aaabbbbbbbbbbbb". >> >> But if I replace "HERE BE DRAGONS" with a call to >> ngx_http_my_subrequest(r->main, "/uri3"), let's suppose this >> subrequest is being started only in second call of >> ngx_http_my_body_filter for /uri1 subrequest started from >> ngx_http_my_handler. The result will be "aaabbb", not >> "aaabbbbbbbbbbbbbbbbbb" as I expect (and logs say all three >> subrequests are processed ok). >> >> I guess my problem is about some magic with buffers and chains, but I >> can't figure out what to fix and where. >> >> I would be thankful for any help. >> >> -- >> Marat _______________________________________________ nginx-devel mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx-devel
