У меня есть бэкэнд с 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-м порту, поэтому не новость, что они не могут предоставить полезный опыт своим клиентам.
Извините, ошибка сервера!