Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: IE7 bug / force response to HTTP/1.0
On Mon, Apr 21, 2008 at 07:59:30PM +0400, Igor Sysoev wrote:
> On Mon, Apr 21, 2008 at 03:44:41PM +0400, Andrew V. Statsenko wrote:
>
> > Коллеги, очень похоже, что наступил за замечательные грабли с MS IE7, а
> > именно:
> >
> > есть схема:
> >
> > [Browser]-->[Nginx frontend]-->[Apache backend]
> >
> > Иногда, для отчетов apache должен отдавать "Content-Type:
> > application/vnd.ms-excel" и далее динамически формируемые CSV данные для
> > клиента. Если apache отдает Transfer-Encoding: chunked , то IE7
> > предлагает диалог этот файл открыть или сохранить, но при любом выборе
> > "загрузить" этот отчет не может, ругаясь на что-то в духе "узел сети не
> > может быть найден".
> >
> > Firefix & Opera успешно работают, ответы (проверено через tcpdump &
> > ngrep) все браузеры получают одинаковые.
> >
> > Проблема на backend решается через форсирование ответа в HTTP/1.0
> > примерно такой конструкцией в apache:
> >
> > SetEnvIf Request_URI exporter nokeepalive downgrade-1.0
> > force-response-1.0
> >
> > и этом случае при обращении IE7 напрямую на backend все работает
> > (т.е. ???убираем ???Transfer-Encoding: chunked), но при обращении на
> > frontend IE7 опять ломается (на сей раз по всей видимости из-за
> > отсутствия Content-Length).
> >
> > Вопросы:
> >
> > 1. Возможно ли сконфигурировать nginx, так, чтобы по некоторым localtion
> > он форсировал HTTP/1.0 ? То есть _теоретически_ примерно так:
> >
> > location /
> > {
> > force_response_to_1_0;
> >
> > proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> > proxy_set_header Host $http_host;
> > proxy_pass http://some.backend.host;
> >
> > }
> >
> >
> > 2. Если (1) невозможно/сложно , то есть ли возможность добавить
> > хидер ???Content-Length непосредственно на frontend'е - вычислить эту
> > длину самим nginx'ом и вставить хидер ?
> >
> > 3. Любые другие варианты решения ?
> >
> >
> > P.S.
> > Разломать схему frontend-backend не могу. Слишком будет хлопотно.
> > Чтобы вычислять ??? ???Content-Length на backend, потребуется _сильно_
> > перепиливать генератор отчетов, что _очень_ не хочется делать.
> >
> > P.S.S.
> > По поводу продукции компании MS испытываю массу разнообразнейших эмоций,
> > но если кто-нибудь знает, о том, что эту багу можно вылечить на стороне
> > браузера (патч, update ?), то был бы безмерно признателен за наводку.
>
> Прилагаемый патч добавляет директиву
>
> chunked_encoding off;
Предыдущий патч нужно откатить, новый накатить.
--
Игорь Сысоев
http://sysoev.ru
Index: src/http/ngx_http_core_module.c
===================================================================
--- src/http/ngx_http_core_module.c (revision 1293)
+++ src/http/ngx_http_core_module.c (working copy)
@@ -486,6 +486,13 @@
offsetof(ngx_http_core_loc_conf_t, msie_refresh),
NULL },
+ { ngx_string("chunked_encoding"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, chunked_encoding),
+ NULL },
+
{ ngx_string("log_not_found"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -2717,6 +2724,7 @@
lcf->port_in_redirect = NGX_CONF_UNSET;
lcf->msie_padding = NGX_CONF_UNSET;
lcf->msie_refresh = NGX_CONF_UNSET;
+ lcf->chunked_encoding = NGX_CONF_UNSET;
lcf->log_not_found = NGX_CONF_UNSET;
lcf->recursive_error_pages = NGX_CONF_UNSET;
lcf->server_tokens = NGX_CONF_UNSET;
@@ -2938,6 +2946,7 @@
ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
+ ngx_conf_merge_value(conf->chunked_encoding, prev->chunked_encoding, 1);
ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
ngx_conf_merge_value(conf->recursive_error_pages,
prev->recursive_error_pages, 0);
Index: src/http/ngx_http_core_module.h
===================================================================
--- src/http/ngx_http_core_module.h (revision 1293)
+++ src/http/ngx_http_core_module.h (working copy)
@@ -302,6 +302,7 @@
ngx_flag_t port_in_redirect; /* port_in_redirect */
ngx_flag_t msie_padding; /* msie_padding */
ngx_flag_t msie_refresh; /* msie_refresh */
+ ngx_flag_t chunked_encoding; /* chunked_encoding */
ngx_flag_t log_not_found; /* log_not_found */
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
ngx_flag_t server_tokens; /* server_tokens */
Index: src/http/modules/ngx_http_chunked_filter_module.c
===================================================================
--- src/http/modules/ngx_http_chunked_filter_module.c (revision 1293)
+++ src/http/modules/ngx_http_chunked_filter_module.c (working copy)
@@ -50,6 +50,8 @@
static ngx_int_t
ngx_http_chunked_header_filter(ngx_http_request_t *r)
{
+ ngx_http_core_loc_conf_t *clcf;
+
if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
|| r->headers_out.status == NGX_HTTP_NO_CONTENT
|| r->headers_out.status == NGX_HTTP_CREATED
@@ -63,7 +65,14 @@
r->keepalive = 0;
} else {
- r->chunked = 1;
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->chunked_encoding == 1) {
+ r->chunked = 1;
+
+ } else {
+ r->keepalive = 0;
+ }
}
}
|