Назад | Перейти на главную страницу

Nginx не выводит правильные ответные ответы

У меня есть бэкэнд с expressjs, делающим частичные ответы на некоторых конечных точках.

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

function (req, res, next) {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  request.a.file(function response (middleChunk) {
    res.write(middleChunk);
  },
  function final (endingChunk) {
    res.end(endingChunk);
  });
}

использование curl -v непосредственно для экземпляра expressjs работает как шарм, показывая сообщения постепенно и в конце концов то endingChunk;

Но я не использую expressjs непосредственно на своем хостинге, а использую обратный прокси, созданный с помощью nginx, его конфигурация такая:

server {
  listen 80;
  server_name funnyhost;
  root /directory;

  location ~/api/.* {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_read_timeout 600s;
    proxy_buffering off;
  }
}

Надевать proxy_buffering off заставил сервер ответить чем-то:

~$ curl -v "domain.com/api/endpoint?testme=true"
* About to connect() to domain.com port 80 (#0)
*   Trying XX.XX.XX.XX... connected
> GET /api/endpoint?testme=true HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: domain.com
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Date: Mon, 12 Aug 2013 17:43:45 GMT
< Server: nginx/1.5.3
< X-Powered-By: Express
< 

но Nginx ожидает ПОЛНОГО прогресса, пока код expressjs не достигнет res.end() перед отправкой данных клиенту!

Я дошел до отчаяния, я трачу часы на работу :( Надеюсь, кто-нибудь сможет помочь

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Я использую:

~# nginx -v
nginx version: nginx/1.5.3

сервер ubuntu 12.04 LTS, node.js v0.10.15, экспресс 3.3.5

Как просили

# nginx -V
nginx version: nginx/1.5.3
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-http_spdy_module --with-ipv6 --with-mail --with-mail_ssl_module --with-openssl=/build/buildd/nginx-1.5.3/debian/openssl-1.0.1e --add-module=/build/buildd/nginx-1.5.3/debian/modules/nginx-auth-pam --add-module=/build/buildd/nginx-1.5.3/debian/modules/nginx-echo --add-module=/build/buildd/nginx-1.5.3/debian/modules/nginx-upstream-fair --add-module=/build/buildd/nginx-1.5.3/debian/modules/nginx-dav-ext-module --add-module=/build/buildd/nginx-1.5.3/debian/modules/nginx-cache-purge

Новости

Я пытаюсь ограничить возможности, поэтому использую этот скрипт https://gist.github.com/mrgamer/6222708

и следующий файл конфигурации nginx https://gist.github.com/mrgamer/6222734

Делая запросы в localhost, все работает гладко, поэтому запросы к моему удаленному VPS заголовки ответов имеют другой порядок и другое поведение; ответ распечатывается полностью.

у моего локального компьютера и удаленного VPS есть ubuntu 12.04 с chris lea nginx PPA (launchpad.net/~chris-lea/+archive/nginx-devel), в целях тестирования я выполнил оба:

~# sudo aptitude purge nginx nginx-common && sudo aptitude install nginx -y

"странное" поведение указано ниже

локальный тест заголовки в исправленном порядке и ответ правильно прогрессивный

~$ curl -v localhost.test
* About to connect() to localhost.test port 80 (#0)
*   Trying 127.0.0.1... connected
> GET / HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: localhost.test
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.5.3
< Date: Tue, 13 Aug 2013 16:04:19 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< 
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Chunked transfer encoding test</title></head><body><h1>Chunked transfer encoding test</h1><h5>This is a chunked response after 2 seconds. Should be displayed before 5-second chunk arrives.</h5>
* Connection #0 to host localhost.test left intact
* Closing connection #0
<h5>This is a chunked response after 5 seconds. The server should not close the stream before all chunks are sent to a client.</h5></body></html>

удаленный тест

~$ curl -v domain.com
* About to connect() to domain.com port 80 (#0)
*   Trying XX.YY.ZZ.HH... connected
> GET / HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: domain.com
> Accept: */*
> 
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Connection: keep-alive
< Date: Tue, 13 Aug 2013 16:06:22 GMT
< Server: nginx/1.5.3
< 
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Chunked transfer encoding test</title></head><body><h1>Chunked transfer encoding test</h1><h5>This is a chunked response after 2 seconds. Should be displayed before 5-second chunk arrives.</h5>
* Connection #0 to host test.col3.me left intact
* Closing connection #0
<h5>This is a chunked response after 5 seconds. The server should not close the stream before all chunks are sent to a client.</h5></body></html>

Сожалею, что это была личная проблема с подключением :)

Я использовал сеть 3G, а мой провайдер (итальянский TIM, блех!) Использует некоторые прозрачные прокси, которые переупорядочивают заголовки и кешируют ответы.

Они также блокируют веб-сокеты на 80-м порту, поэтому не новость, что они не могут предоставить полезный опыт своим клиентам.

Извините, ошибка сервера!