<div class="gmail_quote">On Thu, Dec 3, 2009 at 11:14 PM, Igor Sysoev <span dir="ltr">&lt;<a href="mailto:igor@sysoev.ru">igor@sysoev.ru</a>&gt;</span> wrote:</div><div class="gmail_quote">[...]<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div><div></div><div class="h5">As it was already said, you should mark a buf as consumed:</div></div>
<br>
   buf-&gt;pos = buf-&gt;last;<br></blockquote><div><br></div><div>Thanks.  What is the right thing to do if a body filter consumes</div><div>only part of a buf and sets aside the rest for later?</div><div><br></div><div>

SSI filtering is an example of what I&#39;m thinking of.  There might</div><div>be an incomplete SSI directive at the end of a buf, so the SSI</div><div>parser needs to output everything prior to that directive and</div>
<div>
set aside the incomplete directive to finish parsing later when</div><div>it has more data.</div><div><br></div><div>If a body filter is only able to process part of a buf, is it safe</div><div>to do this:</div><div><br>
</div>
<div>ngx_int_t</div><div>my_body_filter(ngx_http_request_t *r, ngx_chain_t *in)</div><div>{</div><div>  my_module_ctx *my_ctx = ngx_http_get_module_loc_conf(r, my_module);</div><div>  u_char *split;</div><div>  ngx_buf_t *setaside_buf;</div>

<div><br></div><div>  /* Do some parsing of the content in buf to find the point at</div><div>     which we need to split it.  Everything prior to split can be</div><div>     output immediately.  Everything after split needs to be</div>

<div>     saved until later. */</div><div>  split = [some point between in-&gt;buf-&gt;pos and in-&gt;buf-&gt;last];</div><div><br></div><div>  /* Create a new buf holding everything after the split point*/</div><div>  setaside_buf = ngx_calloc_buf(r-&gt;pool);</div>

<div>  setaside_buf-&gt;pos = split;</div><div>  setaside_buf-&gt;last = in-&gt;buf-&gt;last;</div><div><br></div><div>  /* Terminate the original buf at the split point */</div><div>  in-&gt;buf-&gt;last = split;</div><div>

<br></div><div>  /* Save everything after the split point */</div><div>  my_ctx-&gt;setaside = setaside_buf;</div><div><br></div><div>  /* Output everything before the split point */</div><div>  return ngx_next_body_filter(r, in);</div>

<div>}</div><div><br></div><div>And assuming that code is safe, what does the body filter need</div><div>to do later when it finally finishes processing the data in the</div><div>setaside_buf?  I imagine it needs to somehow tell the Nginx</div>

<div>core that it&#39;s done holding onto that buf.</div><div><br></div><div>My prior experience with this sort of thing is in Apache 2, where</div><div>the buckets (Apache&#39;s equivalent to Nginx&#39;s bufs) use reference</div>

<div>counts, so the right way to split a buffer is to increment its</div><div>reference count when splitting and decrement the reference</div><div>count after using the setaside portion.  What&#39;s the equivalent</div><div>

idiom in Nginx?</div><div><br></div><div>I know I can avoid this issue entirely if I make a copy of</div><div>the data after the split point and set in-&gt;buf-&gt;pos=in-&gt;buf-&gt;last</div><div>to release the original buf, but I want to do zero-copy. :-)</div>

<div><br></div><div>Thanks,</div><div>-Brian</div><div><br></div></div>