Re: фильтр

Alexander Dolgarev a.dolgarev at gmail.com
Mon Mar 31 14:08:10 MSD 2008


Задача очень проста: заменить на лету содержимое, допустим букву A на
2 буквы AA. Мне нужно взять цепочку in и заменить ее на новую цепочку
out, которая содержит новые буфера с измененным содержимым (выходных
буферов будет скорее всего больше чем входных, так как объем данных
увеличится).

Отсюда вытекает пара вопросов.

1. Могу ли я создавать свои цепочки путем
out = ngx_pcalloc(r->pool, sizeof(ngx_chain_t));
и далее вызывать
return ngx_http_next_body_filter(r, out);
или мне обязательно передавать в ngx_http_next_body_filter цепочку in,
заменив в ней буфер на свой?

2. Буфер создается путем
b = ngx_create_temp_buf(r->pool, BUFLEN);
Какие еще флаги надо в нем выставлять кроме тех, что выставляются
функцией ngx_create_temp_buf()?

3. Что нужно делать с буферами в цепочке in? Ниже высказывалось
мнение, что пометить его как отправленный (in->buf->pos =
in->buf->last), что-то еще нужно?

2008/3/30 Maxim Dounin <mdounin at mdounin.ru>:
> Hello!
>
>
>
>  On Sun, Mar 30, 2008 at 03:03:29AM +0200, Alexander Dolgarev wrote:
>
>  >В чем принципиальная неправильность следующего фрагмента кода (если
>  >допустить что in != NULL и in->next == NULL)? Клиент просто ждет и
>  >ничего не получает в ответ.
>  >
>  >
>  >static ngx_int_t
>  >ngx_http_*_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
>  >{
>  >    ngx_chain_t *out;
>  >    ngx_buf_t *b;
>  >
>  >    out = ngx_pcalloc(r->pool, sizeof(ngx_chain_t));
>  >    b = ngx_create_temp_buf(r->pool, in->buf->last - in->buf->pos);
>  >    memcpy (b->pos, in->buf->pos, in->buf->last - in->buf->pos);
>  >    b->last_buf = in->buf->last_buf;
>  >    out->buf = b;
>  >
>  >    return ngx_http_next_body_filter(r, out);
>  >}
>
>  Старый буфер помечен как отправленный, соответственно если ответ
>  будет более чем output_buffers - его не отошлют.  Как минимум надо
>  ещё сделать:
>
>      in->buf->pos = in->buf->last;
>
>  Плюс к тому - никто не обещал, что буфер будет в памяти.  Чтобы он
>  таки там был - об этом надо специально попросить, поставив в
>  ngx_http_*_header_filter()
>
>      r->filter_need_in_memory = 1;
>
>  Maxim Dounin
>
>


More information about the nginx-ru mailing list