return 204

Alexander Bykov a.bykov at gmail.com
Fri Mar 6 17:14:08 MSK 2009


2009/3/6 Igor Sysoev <is at rambler-co.ru>:
> On Fri, Mar 06, 2009 at 04:01:31PM +0300, INIT wrote:
>
>> У меня вопрос по близкой теме.
>>
>> Есть необходимость возвращать из своего модуля ответ нулевой длины.
>> Текущая реализация nginx в общем случае этого не позволяет, что крайне
>> неприятно, нельзя ли это поправить ?
>>
>> 204 No Content не предлагать потому что контент мигающий то есть
>> иногда есть а иногда нет в зависимости от ротации (банерная система).
>>
>> Если углубляться в недра nginx проблема выглядит следущим образом:
>> 1. если не отдавать тело ответа, то все ок пока не включить
>> перкодирование из cp1251 в utf8: оно сносит заголовок Content-Length и
>> браузер начинает долго ждать chunked-encoding с телом ответа
>> 2. если отдавать нулевой буфер, то с включенным перекодировщиком все
>> ок: буфер после перекодирования в chunked-encoding становится длины 5
>> байт, но возникает проблема с выключенным перекодировщиком: на пустом
>> буфере nginx пишет в лог "zero size buf in writer" и далает return
>> NGX_ERROR т.е.обрывает коннекшен к клиенту
>
> А выдавать пустой буфер с b->last_buf:
>
>    b->last_buf = (r == r->main) ? 1: 0;
>
> не помогает ?
>

к сожалению это лечит только прямые запросы, но не подзапросы внутри nginx

проверка о которой я писал выглядит так:

#define ngx_buf_in_memory_only(b)   (ngx_buf_in_memory(b) && !b->in_file)

#define ngx_buf_special(b)                                                   \
    ((b->flush || b->last_buf || b->sync)                                    \
     && !ngx_buf_in_memory(b) && !b->in_file)

if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {

единственный способ ее обойти делать вид что буфер у нас не в памяти
(не стативить ему b->temporary), но тогда ломаются ненулевые ответы

workaround выглядит так (не ставим флаг только пустым буферам):
b->temporary = (len > 0) ? 1 : 0;

но тогда получаем
2009/03/06 17:00:39 [alert] 27829#0: *1 the http output chain is
empty, client: 195.218.190.25, server: localhost, request: "GET
/news.html HTTP/1.1", subrequest: "/rb/721", host: "localhost:8081"

так вроде работает но мусорит в лог
там тоже return NGX_ERROR, но почему работает еще не разобрался...

> Можно также
> ngx_http_send_special(r, NGX_HTTP_LAST);
>
>> Предложение:
>> в модуле charset не сбрасывать заголовок Content-Length когда он равен 0
>
>
> --
> Игорь Сысоев
> http://sysoev.ru
>
>


More information about the nginx-ru mailing list