the http output chain is empty bug

Maxim Dounin mdounin at mdounin.ru
Thu May 29 15:07:05 UTC 2014


Hello!

On Thu, May 29, 2014 at 03:59:56AM -0400, kirimedia wrote:

> nginx >= 1.5.7 (в более новых воспроизводится)
> Собран с lua модулем (0.9.8) (ошибка воспроизводится и с более новыми
> версиями)
> 
> # ./sbin/nginx -V
> nginx version: nginx/1.5.7
> built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) 
> configure arguments: --add-module=../lua-nginx-module
> 
> Конфиг
> 
> user  nginx;
> worker_processes 1;
> 
> error_log /var/log/nginx/nginx-error.log error;
> 
> events {
>     use                 epoll;
> }
> 
> http {
>     gzip on;
> 
>     server {
>         listen 80;
>         root /usr/local/nginx/html;
> 
>         location = /empty/ {
>             empty_gif;
>         }
> 
>         location = /include/ {
>             content_by_lua '
>                 ngx.location.capture("/empty/")
>                 ngx.location.capture("/empty/")
>             ';
>         }
> 
>         location = /ssi.html {
>             ssi on;
>         }
>     }
> }
> 
> Содержимое /usr/local/nginx/html/ssi.html
> HEADER
> <!--#include virtual="/include/" wait="yes" -->
> 
> При запросе http://localhost/ssi.html получаю пустой ответ (без заголовков и
> без тела)
> И в логе 
> [alert] 20457#0: *1 the http output chain is empty, client: 127.0.0.1,
> server: , request: "GET /ssi.html HTTP/1.1", subrequest: "/include/"
> 
> То есть, если из ssi запроса делаем 2 lua подзапроса и при этом перед ssi
> запросом что-то выводится, и включен gzip модуль, то получаем пустой ответ.
> 
> Ошибка появилась с версии 1.5.7. Так как в
> src/http/modules/ngx_http_gzip_filter_module.c была добавлена проверка, что
> цепочка чайнов (chain) не NULL
> -    if (ctx->nomem) {
> +    if (ctx->nomem || in == NULL) {
> 
> При этом при 2х луа подзапросах из луа модуля вызывается
> ngx_http_lua_flush_pending_output, которая вызывает 
> rc = ngx_http_lua_output_filter(r, NULL) как раз с пустой цепочкой чайнов. И
> вероятно из за этого и случается ошибка.
> 
> Помогите понять. Это проблема nginx или lua модуля? И как это можно
> пофиксить?

Скорее всего, это ошибка в lua-модуле.

В чём конкретно - отдельный вопрос, есть смысл обрататиться к 
автору.  Тем более, что упомянутое изменение в gzip-фильтре тоже 
его рук дело.

> Зачем это условие в gzip фильтре? 

Вообще вызов output-фильтра с NULL в качестве цепочки - 
используется для того, чтобы по возможности "протолкнуть" ранее 
отправленные буфера, e.g. для освобождения памяти.  Ранее 
gzip-фильтр такие попытки в процессе отправки ответа нивелировал, 
что неправильно.  Вот тут поробный тред про это:

http://mailman.nginx.org/pipermail/nginx-devel/2013-October/004429.html

> Или вероятно из lua модуля должно вызваться ngx_http_send_special(r, flags);
> с флагом NGX_HTTP_FLUSH, которая вызовет фильтры с некоторым чайном?

Зависит от того, что именно делается.

-- 
Maxim Dounin
http://nginx.org/



Подробная информация о списке рассылки nginx-ru