Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: return 204
2009/3/6 Igor Sysoev <is@xxxxxxxxxxxxx>:
> 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
>
>
|