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